Workflows SDK for Python
Usage and symbol reference
The Render SDK for Python provides support for:
- Defining tasks and flows in your workflow service
- Running functions as steps inside a flow
- Chaining additional task runs from within a task function
- Triggering and managing runs from Python code outside the workflow
Install
From your Python project directory:
If you already have the SDK installed, make sure you're using version 1.7.0 or later:
After installing, make sure to add render>=1.7.0 as a dependency in your application's requirements.txt, pyproject.toml, or equivalent.
Workflow setup
The following symbols pertain to setting up your workflow service. For usage guidance, see Defining Tasks and Defining Flows.
The Workflows class
Handles defining and registering workflow tasks and flows. Initialize this in each file where you define tasks or flows.
Constructor
Workflows(*, default_retry=None, default_timeout=None, default_plan=None)
Initializes a new Workflows object. All parameters are optional.
| Parameter | Description | |||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
A This setting does not apply to flows. Individual tasks can override this. If neither the workflow nor the task specifies retry settings, Render applies default retry behavior. | |||||||||||||||||||||
|
The default timeout for each execution attempt (in seconds) for all tasks and flows registered directly on this Individual definitions can override this with | |||||||||||||||||||||
|
The default compute plan to use for all tasks and flows registered directly on this Individual definitions can override this with One of the following:
The default value is Providing |
Workflows.from_workflows(*apps, default_retry=None, default_timeout=None, default_plan=None)
Initializes a new Workflows object that incorporates tasks and flows from one or more other Workflows objects.
Use this in your workflow's entry point file if you import task definitions or flow definitions from other files:
If you set any defaults with this method (such as default_timeout), those defaults apply only to definitions registered directly on this Workflows object (not to definitions registered on the imported objects). default_retry applies only to tasks.
| Parameter | Description |
|---|---|
|
Required. One or more Task and flow names share a namespace. If two objects define a task or flow with the same name, this raises a |
|
The default retry configuration for new tasks registered on this workflow. Same as the |
|
The default timeout for new tasks and flows registered on this workflow. Same as the |
|
The default compute plan for new tasks and flows registered on this workflow. Same as the |
The app.start() method
Workflows.start()
The app.start() method serves as the entry point for your workflow during both task and flow registration and run execution. Your workflow definition must call this method as part of startup:
This method has no parameters.
Defining tasks
The following symbols pertain to creating and registering tasks in your workflow service. For usage guidance, see Defining Tasks.
The @app.task decorator
@app.task(*, name=None, retry=None, timeout_seconds=None, plan=None)
You apply the @app.task decorator to a Python function to register it as a workflow task. For details, see Defining Tasks.
On success: Returns a task definition that you can pass to ctx.run() to chain a run of the task.
Basic usage:
With all configuration options:
| Parameter | Description | |||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
Decorator parameters | ||||||||||||||||||||||
|
A custom name for the task. This affects the task's slug, which you use to reference the task when triggering runs. Use a name that is unique across all tasks and flows in the workflow. If omitted, defaults to the name of the decorated function. | |||||||||||||||||||||
|
A If omitted, uses the workflow's | |||||||||||||||||||||
|
The timeout for each execution attempt, in seconds. Must be between 30 seconds ( If omitted, uses the workflow's | |||||||||||||||||||||
|
The compute plan to use for the task's runs. One of the following:
If omitted, uses the workflow's Providing | |||||||||||||||||||||
|
Retry settings | ||||||||||||||||||||||
|
Required if you provide | |||||||||||||||||||||
|
Required if you provide | |||||||||||||||||||||
|
The exponential backoff factor. After each retry, the previous delay is multiplied by this factor. For example, a factor of
| |||||||||||||||||||||
The TaskContext object
Every task function must accept a TaskContext object as its first positional argument. Render automatically provides this object to each run (you do not provide it as an input).
Use run() for run chaining. Read metadata to get the current run's IDs.
async TaskContext.run(task, *args, **kwargs)
Chains a run of the specified task on a separate instance.
On success: Returns the chained run's return value.
Raises: TaskRunError, ValueError
| Parameter | Description |
|---|---|
|
Required. The |
|
All input arguments to pass to the task run, as positional arguments: You cannot provide both positional and named task arguments in the same call (this raises a |
|
All input arguments to pass to the task run, as named arguments: You cannot provide both positional and named task arguments in the same call (this raises a |
TaskContext.metadata
An object containing identifiers for the current task run and its execution chain.
Added in SDK v1.2.0.
| Property | Description |
|---|---|
|
The ID of this task run. |
|
The ID of the root-level task run for this run's execution chain. If this run is the root-level run, this value is the same as |
|
The ID of the task run that chained this run. This value is |
Defining flows
The following symbols pertain to creating and registering flows in your workflow service. For usage guidance, see Defining Flows.
The @app.flow decorator
@app.flow(*, name=None, timeout_seconds=None, plan=None)
You apply the @app.flow decorator to a Python function to register it as a flow. For details, see Defining Flows.
On success: Returns a flow definition.
Basic usage:
With all configuration options:
| Parameter | Description | |||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
Decorator parameters | ||||||||||||||||||||||
|
A custom name for the flow. This affects the flow's slug, which you use to reference the flow when triggering runs. Use a name that is unique across all tasks and flows in the workflow. If omitted, defaults to the name of the decorated function. | |||||||||||||||||||||
|
The timeout for each execution attempt, in seconds. Must be between 30 seconds ( If omitted, uses the workflow's | |||||||||||||||||||||
|
The compute plan to use for the flow's runs. One of the following:
If omitted, uses the workflow's Providing | |||||||||||||||||||||
The FlowContext object
Every flow function receives a FlowContext as its first positional argument. Render provides this object automatically.
For usage guidance, see Configuring step behavior.
FlowContext.step(name, fn, /, *args, retry=None)
Runs a plain function as a step inside the flow's process.
On success: Returns the function's return value.
Raises: TerminalFlowError, DeterminismError, FlowBadRequestError, FlowLimitError, ExecutionError, TypeError, ValueError
| Parameter | Description |
|---|---|
|
Function parameters | |
|
Required. The step's name. This value is not required to match the name of the function you provide as |
|
Required. The function to execute as a step. The function must be synchronous. The function's arguments and return value must be JSON-serializable. You must pass a plain function. You cannot pass a definition returned by |
|
Required if the function takes arguments. The positional argument values to pass to For functions that take zero arguments, omit these arguments. You cannot pass the function's arguments by keyword. |
|
A If a step's return value fails JSON serialization, the step fails without retrying. If all attempts fail, If you omit this field, the step is attempted once. |
|
Retry settings | |
|
Required if you provide |
|
Required if you provide |
|
The exponential backoff factor. After each retry, the previous delay is multiplied by this factor. For example, a factor of The default value is |
FlowContext.metadata
An object containing the current flow run's ID.
| Property | Description |
|---|---|
|
The ID of this flow run. Has the format |
Triggering runs
The following symbols pertain to triggering and managing task and flow runs from code outside your workflow. For full usage guidance, see Triggering Runs.
When the Render API omits an optional field on a returned object, the corresponding Python property contains UNSET, imported from render.public_api.types. This is distinct from None, which represents a JSON null value.
Initialize the client (sync or async)
Use Render for synchronous execution contexts (such as a default Flask or Django app), or RenderAsync for asynchronous contexts (such as FastAPI route handlers). Both clients support all methods under Task methods and Flow methods.
With RenderAsync, you await method calls and use async for to consume event streams. The examples below assume you are already in an asynchronous execution context when using this client.
Render(*, token=None)
Initializes a synchronous Render SDK client.
| Parameter | Description |
|---|---|
|
The API key to use for authentication. If omitted, the client automatically detects and uses the value of the |
RenderAsync(*, token=None)
Initializes an asynchronous Render SDK client.
| Parameter | Description |
|---|---|
|
The API key to use for authentication. If omitted, the client automatically detects and uses the value of the |
Task methods
These methods are available on the workflows attribute of either client. Unless indicated otherwise, parameter descriptions and returned types apply to both clients.
start_task(task_slug, input_data, *, idempotency_key=None)
Kicks off a run of the registered task with the specified identifier, passing the specified arguments.
To instead start a task and wait for it to finish, use workflows.run_task.
On success: Returns a TaskRun with the sync client, or an AwaitableTaskRun with the async client. Both provide the run's ID and initial status immediately. You can await an AwaitableTaskRun to wait for completion and obtain TaskRunDetails.
Raises: ClientError, RateLimitError, ServerError, TimeoutError
| Parameter | Description |
|---|---|
|
Required. The slug indicating the task to run, available from your task's page in the Render Dashboard:
Always has the format |
|
Required. A list or dictionary containing the task's input arguments.
For a task that takes zero arguments, provide an empty list, |
|
An optional string used to prevent duplicate task runs. Added in SDK v1.2.0. For details, see Idempotency keys. |
run_task(task_slug, input_data, *, idempotency_key=None)
Starts the registered task with the specified identifier, waits for it to finish, and returns its details.
To instead start a run without waiting for completion, use workflows.start_task.
On success: Returns a TaskRunDetails object.
Raises: ClientError, RateLimitError, ServerError, TimeoutError, TaskRunError, RenderError
| Parameter | Description |
|---|---|
|
Required. The slug indicating the task to run, available from your task's page in the Render Dashboard:
Always has the format |
|
Required. A list or dictionary containing the task's input arguments.
For a task that takes zero arguments, provide an empty list, |
|
An optional string used to prevent duplicate task runs. Added in SDK v1.2.0. For details, see Idempotency keys. |
list_task_runs(params=None)
Lists task runs that match optional filters specified in a ListTaskRunsParams object.
On success: Returns a list of TaskRunWithCursor objects.
Raises: ClientError, RateLimitError, ServerError, TimeoutError
The optional params object supports the following fields:
| Parameter | Description |
|---|---|
|
An integer specifying the maximum number of task runs to return. |
|
A cursor string for pagination. Use this to retrieve the next page of results. |
|
A list of workspace IDs to filter results by. Only task runs from these workspaces will be returned. |
get_task_run(task_run_id)
Retrieves the details of the task run with the specified ID.
On success: Returns a TaskRunDetails object, regardless of whether the run is still in progress or has finished. A failed status does not itself raise TaskRunError.
Raises: ClientError, RateLimitError, ServerError, TimeoutError
| Parameter | Description |
|---|---|
|
Required. The ID of the task run to retrieve. Has the format |
cancel_task_run(task_run_id)
Cancels the root-level task run with the specified ID, along with all of its chained runs. Raises ClientError if the root-level run is not found.
Runs that have already finished are left unchanged.
On success: Returns None.
Raises: ClientError, RateLimitError, ServerError, TimeoutError
| Parameter | Description |
|---|---|
|
Required. The ID of the root-level task run to cancel. Has the format |
task_run_events(task_run_ids)
Streams terminal-status events for one or more task runs via Server-Sent Events (SSE).
On success: Returns an iterator of TaskRunDetails objects: a regular iterator with Render, or an async iterator with RenderAsync. Each event describes a run that has reached a terminal status: completed, failed, or canceled. A failed run is yielded as an event (it does not raise TaskRunError).
The stream finishes when the server closes the connection after all requested runs have finished. You can also stop consuming events by breaking out of the loop.
Raises: ClientError, RateLimitError, ServerError, TimeoutError
| Parameter | Description |
|---|---|
|
Required. A list of task run IDs to stream events for. Each ID has the format |
Flow methods
These methods are available on the workflows attribute of either client. Unless indicated otherwise, parameter descriptions and returned types apply to both clients.
start_flow(flow_slug, input_data, *, idempotency_key=None)
Kicks off a run of the registered flow with the specified identifier, passing the specified arguments.
To instead run a flow and wait for it to complete, use workflows.run_flow.
On success: Returns a FlowRun object representing the started run.
Raises: ClientError, RateLimitError, ServerError, TimeoutError
| Parameter | Description |
|---|---|
|
Required. The slug indicating the flow to run, available from your flow's page in the Render Dashboard. Always has the format |
|
Required. A list or dictionary containing the flow's input arguments.
For a flow that takes zero arguments, provide an empty list, |
|
An optional string used to prevent duplicate flow runs. For details, see Idempotency keys. |
run_flow(flow_slug, input_data, *, idempotency_key=None)
Starts the registered flow with the specified identifier, waits for it to complete, and returns the result.
To instead kick off a run without waiting for it to complete, use workflows.start_flow.
On success: Returns a FlowRunDetails object for the finished flow run.
Raises: ClientError, RateLimitError, ServerError, TimeoutError, FlowRunError
| Parameter | Description |
|---|---|
|
Required. The slug indicating the flow to run, available from your flow's page in the Render Dashboard. Has the format |
|
Required. A list or dictionary containing the flow's input arguments.
For a flow that takes zero arguments, provide an empty list, |
|
An optional string used to prevent duplicate flow runs. For details, see Idempotency keys. |
list_flow_runs(params=None)
Lists flow runs that match optional filters specified in a ListFlowRunsParams object.
On success: Returns a list of FlowRunWithCursor objects.
Raises: ClientError, RateLimitError, ServerError, TimeoutError
The optional params object supports the following fields:
| Parameter | Description |
|---|---|
|
An integer specifying the maximum number of flow runs to return. |
|
A cursor string for pagination. Use this to retrieve the next page of results. |
|
A list of flow slugs to filter results by. Only flow runs for these flows are returned. |
|
A list of flow definition IDs to filter results by. |
|
A list of flow run status values to filter results by. Accepts |
|
A list of workspace IDs to filter results by. Only flow runs from these workspaces will be returned. |
|
A list of workflow version IDs to filter results by. |
|
A list of workflow IDs to filter results by. |
get_flow_run(flow_run_id)
Retrieves the details of the flow run with the specified ID.
On success: Returns a FlowRunDetails object, regardless of whether the run is still in progress or has finished. A failed status does not itself raise an execution error.
Raises: ClientError, RateLimitError, ServerError, TimeoutError
| Parameter | Description |
|---|---|
|
Required. The ID of the flow run to retrieve. Has the format |
cancel_flow_run(flow_run_id)
Cancels the flow run with the specified ID.
On success: Returns None.
Raises: ClientError, RateLimitError, ServerError, TimeoutError
| Parameter | Description |
|---|---|
|
Required. The ID of the flow run to cancel. Has the format |
Task types
AwaitableTaskRun
Represents a started task run returned by the async workflows.start_task method.
You can await this object to wait for completion and obtain a TaskRunDetails object:
| Member | Description |
|---|---|
|
The task run's ID, available immediately. Has the format |
|
The initial status of the task run, as a string. This value is usually See Run status. |
|
Returns whether the initial |
TaskAttempt
Represents one execution attempt of a particular task run. Returned in a TaskRun object's attempts list.
Each run's initial attempt has "attempt number" 0. If an attempt fails and the run retries, each retry creates a new attempt with an incremented number.
| Property | Description |
|---|---|
|
The ID of the task run this attempt belongs to. |
|
The zero-based "attempt number": |
|
The current status of this attempt, as a See Run status. |
TaskAttemptDetails
Provides the full details of an individual attempt. Returned in the TaskRunDetails object's attempts list.
Includes all of the same properties as a TaskAttempt object, plus:
| Property | Description |
|---|---|
|
The error message if the attempt failed. Otherwise, this value is the empty string. |
|
A list containing the attempt's return value, if it completed successfully. Otherwise, |
TaskRun
Summarizes the state of a task run. Obtained in any of the following ways:
- From the sync
workflows.start_taskmethod - The
task_runproperty of aTaskRunWithCursorreturned byworkflows.list_task_runs
To obtain full details, including results, pass the run's ID to workflows.get_task_run.
| Property | Description |
|---|---|
|
The ID of the task run. Has the format |
|
The ID of the run's associated task. Has the format |
|
The current status of the task run, as a |
|
The |
|
The |
|
The ID of this run's parent run, if this run was chained. For a root-level run, this value is the empty string. |
|
The zero-based attempt number of the parent task run that chained this run. This value is |
|
The ID of the root task run in this run's execution chain. For a root-level run, this value matches |
|
The number of times the task run has retried so far. For a newly started run, this is |
|
A list of |
TaskRunDetails
Provides the full details of a task run. Obtained in any of the following ways:
- Awaiting an
AwaitableTaskRunreturned by the asyncworkflows.start_taskmethod - Calling
workflows.run_task - Calling
workflows.get_task_run - Iterating over
workflows.task_run_events
Includes all of the same properties as a TaskRun object, plus:
| Property | Description |
|---|---|
|
A list containing the task's return value(s). This value is |
|
The argument values that were passed to the task run, in one of the following formats:
The format matches whichever format the task input was originally provided in. If this value is an object, you can call its Note the trailing underscore ( |
|
The error message if the task run failed. Otherwise, |
|
A list of |
TaskRunWithCursor
Represents an item returned by workflows.list_task_runs. It pairs a task run with its pagination cursor.
| Property | Description |
|---|---|
|
The |
|
The cursor associated with this item. Pass it as |
Flow types
FlowRun
Summarizes the state of a flow run. Obtained in any of the following ways:
- From the
workflows.start_flowmethod (sync or async) - The
flow_runproperty of aFlowRunWithCursorreturned byworkflows.list_flow_runs
To obtain full details, including results, pass the run's ID to workflows.get_flow_run.
| Property | Description |
|---|---|
|
The ID of the flow run. Has the format |
|
The ID of the run's associated flow. Has the format |
|
The current status of the flow run, as a |
|
The |
|
The |
FlowRunDetails
Provides the full details of a flow run. Obtained by calling workflows.get_flow_run.
Includes all of the same properties as a FlowRun object, plus:
| Property | Description |
|---|---|
|
A list containing the flow's return value(s). This value is an empty list unless |
|
The argument values that were passed to the flow run, in one of the following formats:
The format matches whichever format the flow input was originally provided in. If this value is an object, you can call its Note the trailing underscore ( |
|
The error message if the flow run failed. Otherwise, |
|
Details for a determinism or limit error. See fields below. Otherwise, |
|
A list of objects representing each individual execution attempt for this run. See all supported fields below. |
|
| |
|
The zero-based "attempt number": |
|
The current status of this attempt, as a |
|
The |
|
The |
|
The error message if the attempt failed. Otherwise, |
|
| |
|
The error code: Read the enum's |
|
A description of the failure. |
|
The zero-based sequence number of the step that caused the determinism error. |
|
The zero-based "attempt number" associated with the determinism error. |
|
For determinism errors: Read the enum's |
|
Descriptions of the recorded and attempted calls for a determinism error. |
|
The applicable limit and the value that exceeded it. |
FlowRunStatus
The status of a flow run or flow attempt, as an enum value. Import it from render.client.types and read its .value property to obtain the status string.
A successful flow run has status succeeded (task runs use completed). The terminal statuses are succeeded, failed, and canceled.
| Value | Description |
|---|---|
|
The run has been queued but has not yet started executing. |
|
The run is currently executing. |
|
The run finished successfully. |
|
The run failed. |
|
The run was canceled. |
FlowRunWithCursor
Represents an item returned by workflows.list_flow_runs. It pairs a flow run with its pagination cursor.
| Property | Description |
|---|---|
|
The |
|
The cursor associated with this item. Pass it as |
Run status
For flow runs and attempts, see FlowRunStatus. The table below describes task runs and attempts.
The status property on TaskRun, TaskRunDetails, TaskAttempt, and TaskAttemptDetails is a TaskRunStatus enum value. Read its .value property to obtain the status string. The status property on AwaitableTaskRun is already a string.
For example, to check a returned run's status:
The exact meaning of each status differs for a task attempt and a task run, as shown:
| Value | Task attempt | Task run |
|---|---|---|
|
The attempt has been queued but has not yet started executing. |
The run's current attempt is |
|
The attempt is currently executing. |
The run's current attempt is |
|
The attempt is waiting for the result of a chained run. |
The run's current attempt is |
|
The attempt finished successfully. |
The run finished successfully. |
|
The attempt finished with an error. |
All of the run's attempts have finished with an error and no retries remain. |
|
The run was canceled before this attempt finished. |
The run was canceled before it finished. |
Error types
The Render SDK defines the custom error types below. In certain cases, the SDK also raises standard Python errors, such as ValueError and TypeError.
Client and task errors
RenderError(Exception)
The base class for custom Render SDK errors.
ClientError(RenderError)
Raised when a request to the Render API returns a 400-level error code.
Common causes include:
- Invalid API key
- Invalid task or flow identifier
- Invalid task or flow arguments
- Invalid action (for example, starting a run on a suspended workflow service)
RateLimitError(ClientError)
Raised when a request to the Render API returns a 429 (rate limit exceeded) error code.
ServerError(RenderError)
Raised when a request to the Render API returns a 500-level error code, and for network connection failures.
TimeoutError(RenderError)
Raised when a request to the Render API times out. This custom SDK definition is distinct from Python's built-in TimeoutError.
ExecutionError(RenderError)
The base class for errors from a failed task run or flow step.
TaskRunError(ExecutionError)
Raised in the following cases:
- A chained run fails.
- A run fails while awaiting an
AwaitableTaskRun. - A run fails while calling
workflows.run_task.
FlowRunError(RenderError)
Raised when a flow run fails or is canceled while calling workflows.run_flow.
Flow execution errors
These errors are raised during flow execution, such as during a call to ctx.step().
Import these errors from render.client.errors.
TerminalFlowError(ExecutionError)
Raised when a step fails after exhausting its retries. The flow run fails even if flow code catches the error.
For retry guidance, see Retry settings.
DeterminismError(TerminalFlowError)
Raised when a step call does not match the recorded history during replay. This fails the flow run even if flow code catches the error.
When available, the details object contains the following:
| Property | Description |
|---|---|
|
The zero-based sequence number of the step that caused the determinism error. |
|
The zero-based "attempt number" associated with the recorded step. |
|
How the replay differs from the recorded history. Read the enum's
|
|
A description of the call recorded in the step history. |
|
A description of the call made during replay. |
FlowBadRequestError(TerminalFlowError)
Raised when a step operation is rejected by the workflow system. The code property contains its error code, or None if no code was supplied.
The flow run fails even if flow code catches the error.
FlowLimitError(FlowBadRequestError)
Raised when a step operation exceeds a workflow limit. The flow run fails even if flow code catches the error.
The code identifies the limit, such as flow_payload_too_large. The limit and value properties contain the applicable limit and the value that exceeded it, or None if not supplied by the runtime.
