|
| 1 | +--- |
| 2 | +title: Run method |
| 3 | +pcx_content_type: concept |
| 4 | +sidebar: |
| 5 | + order: 2 |
| 6 | + |
| 7 | +--- |
| 8 | + |
| 9 | +The main difference between the [Typescript SDK](/workflows/build/workers-api/#run) and the Python SDK lives in the `run` method, and the parameters that it receives. |
| 10 | + |
| 11 | +## WorkflowStep |
| 12 | + |
| 13 | +* <code>step.do(name, depends=[], concurrent=False, config=None)</code> is a decorator that allows you to define a step in a workflow. |
| 14 | + * `name` - the name of the step. |
| 15 | + * `depends` - an optional list of steps that must complete before this step can run. |
| 16 | + * `concurrent` - an optional boolean that indicates whether this step can run concurrently with other steps. |
| 17 | + * `config` - an optional [`WorkflowStepConfig`](/workflows/build/workers-api/#workflowstepconfig) for configuring [step specific retry behaviour](/workflows/build/sleeping-and-retrying/). This is passed as a Python dictionary and then type translated into a `WorkflowStepConfig` object. |
| 18 | + |
| 19 | +```python |
| 20 | +from workers import WorkflowEntrypoint |
| 21 | + |
| 22 | +class MyWorkflow(WorkflowEntrypoint): |
| 23 | + async def on_run(self, event, step): |
| 24 | + @step.do("my first step") |
| 25 | + async def my_first_step(): |
| 26 | + # do some work |
| 27 | + return "Hello World!" |
| 28 | + |
| 29 | + await my_first_step() |
| 30 | +``` |
| 31 | + |
| 32 | +When returning state from a step, you must make sure that the returned value is serializable. Since steps run through an FFI layer, the returned value gets type translated via [FFI.](https://pyodide.org/en/stable/usage/api/python-api/ffi.html#pyodide.ffi.to_js) |
| 33 | +Refer to [Pyodide's documentation](https://pyodide.org/en/stable/usage/type-conversions.html#type-translations-pyproxy-to-js) regarding type conversions for more information. |
| 34 | + |
| 35 | +* <code>step.sleep(name, duration)</code> |
| 36 | + |
| 37 | + * `name` - the name of the step. |
| 38 | + * `duration` - the duration to sleep until, in either seconds or as a `WorkflowDuration` compatible string. |
| 39 | + |
| 40 | +* <code>step.sleep_until(name, timestamp)</code> |
| 41 | + |
| 42 | + * `name` - the name of the step. |
| 43 | + * `timestamp` - a `datetime.date` object or seconds from the Unix epoch to sleep the Workflow instance until. |
| 44 | + |
| 45 | +* <code>step.wait_for_event(name, event_type, timeout="24 hours")</code> |
| 46 | + |
| 47 | + * `name` - the name of the step. |
| 48 | + * `event_type` - the type of event to wait for. |
| 49 | + * `timeout` - the timeout for the `waitForEvent` call. The default timeout is 24 hours. |
| 50 | + |
| 51 | +## Error Handling |
| 52 | + |
| 53 | +Workflows semantics allow users to catch exceptions that get thrown to the top level. |
| 54 | + |
| 55 | +:::note |
| 56 | +Catching specific exceptions within an `except` block may not work, as some Python errors will not be re-instantiated into the same type of error when they are passed through the RPC layer. |
| 57 | +::: |
| 58 | + |
| 59 | +### NonRetryableError |
| 60 | + |
| 61 | +Similarly to the [Typescript SDK](/workflows/build/workers-api/#nonretryableerror), the Python SDK provides a `NonRetryableError` class that can be used to signal that a step should not be retried. |
| 62 | + |
| 63 | +```python |
| 64 | +from workers.workflows import NonRetryableError |
| 65 | + |
| 66 | +throw NonRetryableError(message) |
| 67 | +``` |
| 68 | + |
| 69 | +## Configure a workflow instance |
| 70 | + |
| 71 | +You can bind a step to a specific retry policy by passing a `WorkflowStepConfig` object to the `config` parameter of the `step.do` decorator. |
| 72 | +In Python , you need to make sure that your `dict` respects the [`WorkflowStepConfig`](/workflows/build/workers-api/#workflowstepconfig) type. |
| 73 | + |
| 74 | +```python |
| 75 | +class DemoWorkflowClass(WorkflowEntrypoint): |
| 76 | + async def on_run(self, event, step): |
| 77 | + @step.do('step-name', config={"retries": {"limit": 1, "delay": "10 seconds"}}) |
| 78 | + async def first_step(): |
| 79 | + # do some work |
| 80 | + pass |
| 81 | +``` |
0 commit comments