Using App Workflows¶
Organizing app workflows¶
Simmate automatically searches for a workflows.py
(or workflows
module) within your app and retrieves all Python classes within it, assuming they are workflows you want registered. However, if your scripts contain non-workflow classes or abstract base workflows, this can lead to unexpected errors. Therefore, you need to explicitly specify which workflows should be registered with your app.
Tip
If you encounter AttributeError: '...' object has no attribute 'name_full'
or Exception: Make sure you are following Simmate naming conventions
, it's likely that your workflows are misorganized.
in workflows.py file¶
Upon creating your project/app, you'll find a single workflows.py
file with the following at the top:
# -----------------------------------------------------------------------------
# List all workflows you want registered
# -----------------------------------------------------------------------------
__all__ = [
"add",
"Example__Python__MyExample",
]
You must explicitly list all workflows you want registered if you stick with a single workflow.py
file format.
in a workflows module¶
As your app expands, you might want to store your workflows in separate scripts or submodules. You can do this by replacing the workflows.py
file with a workflows
folder with the following structure:
example_app
└── workflows
├── __init__.py # <-- file used for registration
├── example_1.py
├── example_2.py
├── example_3.py
└── example_submodule
├── __init__.py
├── example_4.py
└── example_5.py
Here, example_N.py
files can be named as you wish and do NOT require the __all__
tag. This folder structure allows for better workflow organization.
Instead of the __all__
tag, we can list workflows to register in the workflows/__init__.py
file. We can use relative Python imports to achieve this with minimal code:
# in workflows/__init__.py
from .example_1 import Example__Python__MyExample1
from .example_2 import Example__Python__MyExample2
from .example_3 import Example__Python__MyExample3
from .example_submodule.example_4 import Example__Python__MyExample4
from .example_submodule.example_5 import Example__Python__MyExample5
Example
If you prefer learning by example, check out Simmate's built-in Vasp
app. The workflows
module of this app is located here. You can also see how our workflows/__init__.py
file lists all of our registered workflows here).
Basic use¶
Now that we have registered workflows within a Simmate app, we can access some extra features. We can run the workflow in the same way we run others distributed with Simmate (using a YAML file, Python, Web UI, etc):
workflow_name: example.python.my-example1
structure: NaCl.cif
input_01: 12345
input_02: true
from simmate.workflows.utilities import get_workflow
workflow = get_workflow("example.python.my-example1")
workflow.run(
structure="NaCl.cif",
input_01=12345,
input_02=true,
)
You can also see your workflow listed now:
simmate workflows list-all
Link Datatables to Workflows¶
To use a custom database table in a workflow, the following conditions must be met:
- the table must use the
Calculation
mix-in - the workflow must have
database_table
set to our table - the table and workflow must be registered (already completed)
Note that our database tables and workflows already meet these conditions.
For MyCustomTable2
, we can see it is using the Calculation
mix-in in our models.py
file:
class MyCustomTable1(Structure, Calculation):
# ... custom columns hidden ...
This table has already been linked to a workflow too. In our workflows.py
file, we can see the following:
class Example__Python__MyExample(Workflow):
database_table = MyCustomTable2
This completes our checklist -- so this database and workflow are already configured for us.
Storing inputs parameters¶
To store input parameters at the start of a calculation in a workflow, the following conditions must be met:
- the parameter must have been added as a column to the database
- a parameter with the exact same name must be an input option of
run_config
For our MyCustomTable1
and Example__Python__MyExample
, we can see that the following inputs match both the run_config
input AND are table columns:
- input_01
- input_02
- structure
Here's the relevant code that sets this up:
# structure --> through the Structure mix-in
input_01 = table_column...
input_02 = table_column...
def run_config(
input_01,
input_02,
structure,
That's it! Your workflow will store these inputs in your database when a workflow run starts.
Storing outputs and results¶
To store outputs at the end of a calculation in a workflow, the following conditions must be met:
- the parameter must have been added as a column to the database
- the
run_config
must return a dictionary of columns that need to be updated - a key with the exact same name must be in this dictionary
For our MyCustomTable1
and Example__Python__MyExample
, we can see that the following outputs match both the run_config
's output dictionary AND are table columns:
- output_01
- output_02
Here's the relevant code that sets this up:
output_01 = table_column...
output_02 = table_column...
return {
"output_01": ...,
"output_02": ...,
}
That's it! Your workflow will store these results in your database when a workflow run completes.
Viewing Results¶
Results are stored the same as any other workflow. You'll see a summary file written for you, and you can load all the data from your database. We only configure a small number of columns for our workflow + datatable, but check out all of the outputs!
_DATABASE_TABLE_: MyCustomTable1
_TABLE_ID_: 1
_WEBSITE_URL_: http://127.0.0.1:8000/workflows/example/python/my-example1/1
chemical_system: Cl-Na
computer_system: digital-storm
created_at: 2022-09-04 00:10:01.844798+00:00
density: 2.1053060843576104
density_atomic: 0.04338757298280908
directory: /home/jacksund/Documents/spyder_wd/simmate-task-ow6otw06
formula_anonymous: AB
formula_full: Na4 Cl4
formula_reduced: NaCl
id: 1
input_01: 12345.0
input_02: true
nelements: 2
nsites: 8
output_01: 1234500
output_02: false
run_id: 6872771c-c0d7-43b5-afea-b8ed87f6a5df
spacegroup_id: 225
updated_at: 2022-09-04 00:10:01.875757+00:00
volume: 184.38459332974767
volume_molar: 13.87987468758872
workflow_name: example.python.my-example1
workflow_version: 0.10.0