Skip to content

Deploying a Workflow

The workflows library includes a WorkflowServer class that allows you to easily expose your workflows over an HTTP API. This provides a flexible way to run and manage workflows from any HTTP-capable client.

You can create a server, add your workflows, and run it programmatically. This is useful when you want to embed the workflow server in a larger application.

First, create a Python file (e.g., my_server.py):

my_server.py
from workflows import Workflow, step
from workflows.context import Context
from workflows.events import Event, StartEvent, StopEvent
from workflows.server import WorkflowServer
class StreamEvent(Event):
sequence: int
# Define a simple workflow
class GreetingWorkflow(Workflow):
@step
async def greet(self, ctx: Context, ev: StartEvent) -> StopEvent:
for i in range(3):
ctx.write_event_to_stream(StreamEvent(sequence=i))
await asyncio.sleep(0.3)
name = getattr(ev, "name", "World")
return StopEvent(result=f"Hello, {name}!")
greet_wf = GreetingWorkflow()
# Create a server instance
server = WorkflowServer()
# Add the workflow to the server
server.add_workflow("greet", greet_wf)
# To run the server programmatically (e.g., from your own script)
# import asyncio
#
# async def main():
# await server.serve(host="0.0.0.0", port=8080)
#
# if __name__ == "__main__":
# asyncio.run(main())

The library also provides a convenient CLI to run a server from a file containing a WorkflowServer instance.

Given the my_server.py file from the example above, you can start the server with the following command:

Terminal window
python -m workflows.server my_server.py

The server will start on 0.0.0.0:8080 by default. You can configure the host and port using the WORKFLOWS_PY_SERVER_HOST and WORKFLOWS_PY_SERVER_PORT environment variables.

The WorkflowServer exposes the following RESTful endpoints:

MethodPathDescription
GET/healthReturns a health check response ({"status": "healthy"}).
GET/workflowsLists the names of all registered workflows.
POST/workflows/{name}/runRuns the specified workflow synchronously and returns the final result.
POST/workflows/{name}/run-nowaitStarts the specified workflow asynchronously and returns a handler_id.
GET/results/{handler_id}Retrieves the result of an asynchronously run workflow. Returns 202 Accepted if still running.
GET/events/{handler_id}Streams all events from a running workflow as newline-delimited JSON (application/x-ndjson).

To run a workflow and wait for its completion, send a POST request to /workflows/{name}/run.

Request Body:

{
"kwargs": {
"a": 5,
"b": 10
}
}

Successful Response (200 OK):

{
"result": 15
}

Running a Workflow Asynchronously (/run-nowait)

Section titled “Running a Workflow Asynchronously (/run-nowait)”

To start a workflow without waiting for it to finish, use the /run-nowait endpoint.

Request Body:

{
"kwargs": {
"a": 5,
"b": 10
}
}

Successful Response (200 OK):

{
"handler_id": "someUniqueId123",
"status": "started"
}

You can then use the handler_id to check for the result or stream events.