Skip to content

Commit d520292

Browse files
committed
rewrite deployment section
1 parent 93092c3 commit d520292

File tree

1 file changed

+127
-1
lines changed

1 file changed

+127
-1
lines changed

docs/docs/workflows/v2/deployment.md

Lines changed: 127 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,129 @@
11
# Deploying a Workflow
22

3-
You can deploy a workflow as a multi-agent service with [llama_deploy](../../module_guides/llama_deploy) ([repo](https://github.com/run-llama/llama_deploy)). Each agent service is orchestrated via a control plane and communicates via a message queue. Deploy locally or on Kubernetes.
3+
## Deploying with `WorkflowServer`
4+
5+
The `workflows` library includes a `WorkflowServer` class that allows you to easily expose your workflows over an HTTP
6+
API. This provides a flexible way to run and manage workflows from any HTTP-capable client.
7+
8+
### Programmatic Usage
9+
10+
You can create a server, add your workflows, and run it programmatically. This is useful when you want to embed the
11+
workflow server in a larger application.
12+
13+
First, create a Python file (e.g., `my_server.py`):
14+
15+
```python
16+
# my_server.py
17+
from workflows import Workflow, step
18+
from workflows.context import Context
19+
from workflows.events import Event, StartEvent, StopEvent
20+
from workflows.server import WorkflowServer
21+
22+
23+
class StreamEvent(Event):
24+
sequence: int
25+
26+
27+
# Define a simple workflow
28+
class GreetingWorkflow(Workflow):
29+
@step
30+
async def greet(self, ctx: Context, ev: StartEvent) -> StopEvent:
31+
for i in range(3):
32+
ctx.write_event_to_stream(StreamEvent(sequence=i))
33+
await asyncio.sleep(0.3)
34+
35+
name = getattr(ev, "name", "World")
36+
return StopEvent(result=f"Hello, {name}!")
37+
greet_wf = GreetingWorkflow()
38+
39+
40+
# Create a server instance
41+
server = WorkflowServer()
42+
43+
# Add the workflow to the server
44+
server.add_workflow("greet", greet_wf)
45+
46+
# To run the server programmatically (e.g., from your own script)
47+
# import asyncio
48+
#
49+
# async def main():
50+
# await server.serve(host="0.0.0.0", port=8080)
51+
#
52+
# if __name__ == "__main__":
53+
# asyncio.run(main())
54+
```
55+
56+
### Command-Line Interface (CLI)
57+
58+
The library also provides a convenient CLI to run a server from a file containing a `WorkflowServer` instance.
59+
60+
Given the `my_server.py` file from the example above, you can start the server with the following command:
61+
62+
```bash
63+
python -m workflows.server my_server.py
64+
```
65+
66+
The server will start on `0.0.0.0:8080` by default. You can configure the host and port using the
67+
`WORKFLOWS_PY_SERVER_HOST` and `WORKFLOWS_PY_SERVER_PORT` environment variables.
68+
69+
### API Endpoints
70+
71+
The `WorkflowServer` exposes the following RESTful endpoints:
72+
73+
| Method | Path | Description |
74+
|--------|--------------------------------|---------------------------------------------------------------------------------------------------------|
75+
| `GET` | `/health` | Returns a health check response (`{"status": "healthy"}`). |
76+
| `GET` | `/workflows` | Lists the names of all registered workflows. |
77+
| `POST` | `/workflows/{name}/run` | Runs the specified workflow synchronously and returns the final result. |
78+
| `POST` | `/workflows/{name}/run-nowait` | Starts the specified workflow asynchronously and returns a `handler_id`. |
79+
| `GET` | `/results/{handler_id}` | Retrieves the result of an asynchronously run workflow. Returns `202 Accepted` if still running. |
80+
| `GET` | `/events/{handler_id}` | Streams all events from a running workflow as newline-delimited JSON (`application/x-ndjson`). |
81+
82+
#### Running a Workflow (`/run`)
83+
84+
To run a workflow and wait for its completion, send a `POST` request to `/workflows/{name}/run`.
85+
86+
**Request Body:**
87+
88+
```json
89+
{
90+
"kwargs": {
91+
"a": 5,
92+
"b": 10
93+
}
94+
}
95+
```
96+
97+
**Successful Response (`200 OK`):**
98+
99+
```json
100+
{
101+
"result": 15
102+
}
103+
```
104+
105+
#### Running a Workflow Asynchronously (`/run-nowait`)
106+
107+
To start a workflow without waiting for it to finish, use the `/run-nowait` endpoint.
108+
109+
**Request Body:**
110+
111+
```json
112+
{
113+
"kwargs": {
114+
"a": 5,
115+
"b": 10
116+
}
117+
}
118+
```
119+
120+
**Successful Response (`200 OK`):**
121+
122+
```json
123+
{
124+
"handler_id": "someUniqueId123",
125+
"status": "started"
126+
}
127+
```
128+
129+
You can then use the `handler_id` to check for the result or stream events.

0 commit comments

Comments
 (0)