You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+203-2Lines changed: 203 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -150,7 +150,7 @@ Orchestrations can start child orchestrations using the `call_sub_orchestrator`
150
150
151
151
Orchestrations can wait for external events using the `wait_for_external_event` API. External events are useful for implementing human interaction patterns, such as waiting for a user to approve an order before continuing.
152
152
153
-
### Continue-as-new (TODO)
153
+
### Continue-as-new
154
154
155
155
Orchestrations can be continued as new using the `continue_as_new` API. This API allows an orchestration to restart itself from scratch, optionally with a new input.
156
156
@@ -281,6 +281,9 @@ The following is more information about how to develop this project. Note that d
281
281
### Generating protobufs
282
282
283
283
```sh
284
+
# install dev dependencies for generating protobufs and running tests
To run the E2E tests on a specific python version (eg: 3.11), run the following command from the project root:
320
323
321
324
```sh
322
-
tox -e py311 -- e2e
325
+
tox -e py311-e2e
326
+
```
327
+
328
+
### Configuration
329
+
330
+
#### Connection Configuration
331
+
332
+
The SDK connects to a Durable Task sidecar. By default it uses `localhost:4001`. You can override via environment variables (checked in order):
333
+
334
+
-`DAPR_GRPC_ENDPOINT` - Full endpoint (e.g., `localhost:4001`, `grpcs://host:443`)
335
+
-`DAPR_GRPC_HOST` (or `DAPR_RUNTIME_HOST`) and `DAPR_GRPC_PORT` - Host and port separately
336
+
337
+
Example (common ports: 4001 for DurableTask-Go emulator, 50001 for Dapr sidecar):
338
+
339
+
```sh
340
+
export DAPR_GRPC_ENDPOINT=localhost:4001
341
+
# or
342
+
export DAPR_GRPC_HOST=localhost
343
+
export DAPR_GRPC_PORT=50001
344
+
```
345
+
346
+
347
+
#### Async Workflow Configuration
348
+
349
+
Configure async workflow behavior and debugging:
350
+
351
+
-`DAPR_WF_DISABLE_DETECTION` - Disable non-determinism detection (set to `true`)
352
+
353
+
Example:
354
+
355
+
```sh
356
+
export DAPR_WF_DISABLE_DETECTION=false
357
+
```
358
+
359
+
### Async workflow authoring
360
+
361
+
For a deeper tour of the async authoring surface (determinism helpers, sandbox modes, timeouts, concurrency patterns), see the Async Enhancements guide: [ASYNC_ENHANCEMENTS.md](./ASYNC_ENHANCEMENTS.md). The developer-facing migration notes are in [DEVELOPER_TRANSITION_GUIDE.md](./DEVELOPER_TRANSITION_GUIDE.md).
362
+
363
+
You can author orchestrators with `async def` using the new `durabletask.aio` package, which provides a comprehensive async workflow API:
Optional sandbox mode (`best_effort` or `strict`) patches `asyncio.sleep`, `random`, `uuid.uuid4`, and `time.time` within the workflow step to deterministic equivalents. This is best-effort and not a correctness guarantee.
380
+
381
+
In `strict` mode, `asyncio.create_task` is blocked inside workflows to preserve determinism and will raise a `SandboxViolationError` if used.
382
+
383
+
> **Enhanced Sandbox Features**: The enhanced version includes comprehensive non-determinism detection, timeout support, enhanced concurrency primitives, and debugging tools. See [ASYNC_ENHANCEMENTS.md](./durabletask/aio/ASYNCIO_ENHANCEMENTS.md) for complete documentation.
384
+
385
+
#### Async patterns
386
+
387
+
- Activities and sub-orchestrations can be referenced by function object or by their registered string name. Both forms are supported:
388
+
- Function reference (preferred for IDE/type support) or string name (useful across modules/languages).
389
+
390
+
- Activities:
391
+
```python
392
+
result =await ctx.call_activity("process", input={"x": 1})
393
+
# or: result = await ctx.call_activity(process, input={"x": 1})
394
+
```
395
+
396
+
- Timers:
397
+
```python
398
+
await ctx.sleep(1.5) # seconds or timedelta
323
399
```
324
400
401
+
- External events:
402
+
```python
403
+
val =await ctx.wait_for_external_event("approval")
- Async authoring (`durabletask.aio`): awaiting returns the operation's value. Exceptions are raised on `await` (no `is_failed`).
421
+
- Generator authoring (`durabletask.task`): yielding returns `Task` objects. Use `get_result()` to read values; failures surface via `is_failed()` or by raising on `get_result()`.
422
+
423
+
Examples:
424
+
425
+
```python
426
+
# Async authoring (await returns value)
427
+
# when_any returns a proxy that compares equal to the original awaitable
428
+
# and exposes get_result() for the completed item.
- Useful for routing, observability, and cross-cutting concerns passed along activity/sub-orchestrator calls via the sidecar.
492
+
- In python-sdk, available for both async and generator orchestrators. In this repo, currently implemented on `durabletask.aio`; generator parity is planned.
493
+
494
+
- Cross-app activity/sub-orchestrator routing (async only for now):
495
+
```python
496
+
# Route activity to a different app via app_id
497
+
result =await ctx.call_activity("process", input=data, app_id="worker-app-2")
grpcio-tools==1.62.3 # 1.62.X is the latest version before protobuf 1.26.X is used which has breaking changes for Python # supports protobuf 6.x and aligns with generated code
0 commit comments