This file provides context for AI agents working on the Dapr Python SDK. The project is the official Python SDK for Dapr (Distributed Application Runtime), enabling Python developers to build distributed applications using Dapr building blocks.
Repository: https://github.com/dapr/python-sdk License: Apache 2.0
Deeper documentation lives alongside the code. This root file gives you the big picture and tells you where to look. Each extension and the examples directory has its own
AGENTS.mdwith detailed architecture, APIs, and patterns.
dapr/ # Core SDK package
├── actor/ # Actor framework (virtual actor model)
├── aio/ # Async I/O modules
├── clients/ # Dapr clients (gRPC and HTTP)
├── common/ # Shared utilities
├── conf/ # Configuration (settings, environment)
├── proto/ # Auto-generated gRPC protobuf stubs (DO NOT EDIT)
├── serializers/ # JSON and pluggable serializers
└── version/ # Version metadata
ext/ # Extension packages (each is a separate PyPI package)
├── dapr-ext-workflow/ # Workflow authoring ← see ext/dapr-ext-workflow/AGENTS.md
├── dapr-ext-grpc/ # gRPC App extension ← see ext/dapr-ext-grpc/AGENTS.md
├── dapr-ext-fastapi/ # FastAPI integration ← see ext/dapr-ext-fastapi/AGENTS.md
├── dapr-ext-langgraph/ # LangGraph checkpointer ← see ext/dapr-ext-langgraph/AGENTS.md
├── dapr-ext-strands/ # Strands agent sessions ← see ext/dapr-ext-strands/AGENTS.md
└── flask_dapr/ # Flask integration ← see ext/flask_dapr/AGENTS.md
tests/ # Unit tests (mirrors dapr/ package structure)
examples/ # Integration test suite ← see examples/AGENTS.md
docs/ # Sphinx documentation source
tools/ # Build and release scripts
- Namespace packages: The
daprnamespace is shared across the core SDK and extensions viafind_namespace_packages. Extensions live inext/but install into thedapr.ext.*namespace. Do not add__init__.pyto namespace package roots in extensions. - Client architecture:
DaprGrpcClient(primary, high-performance) and HTTP-based clients. Both implement shared interfaces. - Actor model:
Actorbase class,ActorInterfacewith@actormethoddecorator,ActorProxy/ActorProxyFactoryfor client-side references,ActorRuntimefor server-side hosting. - Serialization: Pluggable via
Serializerbase class.DefaultJSONSerializeris the default. - Proto files: Auto-generated from Dapr proto definitions. Never edit files under
dapr/proto/directly.
Each extension is a separate PyPI package with its own setup.cfg, setup.py, tests/, and AGENTS.md.
| Extension | Package | Purpose | Active development |
|---|---|---|---|
dapr-ext-workflow |
dapr.ext.workflow |
Durable workflow orchestration via durabletask-dapr | High — major focus area |
dapr-ext-grpc |
dapr.ext.grpc |
gRPC server for Dapr callbacks (methods, pub/sub, bindings, jobs) | Moderate |
dapr-ext-fastapi |
dapr.ext.fastapi |
FastAPI integration for pub/sub and actors | Moderate |
flask_dapr |
flask_dapr |
Flask integration for pub/sub and actors | Low |
dapr-ext-langgraph |
dapr.ext.langgraph |
LangGraph checkpoint persistence to Dapr state store | Moderate |
dapr-ext-strands |
dapr.ext.strands |
Strands agent session management via Dapr state store | New |
The examples/ directory serves as both user-facing documentation and the project's integration test suite. Examples are validated in CI using mechanical-markdown, which executes bash code blocks from README files and asserts expected output.
See examples/AGENTS.md for the full guide on example structure, validation, mechanical-markdown STEP blocks, and how to add new examples.
Quick reference:
tox -e examples # Run all examples (needs Dapr runtime)
tox -e example-component -- state_store # Run a single example
cd examples && ./validate.sh state_store # Run directly- Minimum: Python 3.10
- Tested: 3.10, 3.11, 3.12, 3.13, 3.14
- Target version for tooling:
py310(ruff, mypy)
Install all packages in editable mode with dev dependencies:
pip install -r dev-requirements.txt \
-e . \
-e ext/dapr-ext-workflow/ \
-e ext/dapr-ext-grpc/ \
-e ext/dapr-ext-fastapi/ \
-e ext/dapr-ext-langgraph/ \
-e ext/dapr-ext-strands/ \
-e ext/flask_dapr/Tests use Python's built-in unittest framework with coverage. Run via tox:
# Run all unit tests (replace 311 with your Python version)
tox -e py311
# Run linting and formatting
tox -e ruff
# Run type checking
tox -e type
# Validate examples (requires Dapr runtime)
tox -e examplesTo run tests directly without tox:
# Core SDK tests
python -m unittest discover -v ./tests
# Extension tests (run each separately)
python -m unittest discover -v ./ext/dapr-ext-workflow/tests
python -m unittest discover -v ./ext/dapr-ext-grpc/tests
python -m unittest discover -v ./ext/dapr-ext-fastapi/tests
python -m unittest discover -v ./ext/dapr-ext-langgraph/tests
python -m unittest discover -v ./ext/dapr-ext-strands/tests
python -m unittest discover -v ./ext/flask_dapr/testsFormatter/Linter: Ruff (v0.14.1)
Key rules:
- Line length: 100 characters (E501 is currently ignored, but respect the 100-char target)
- Quote style: Single quotes
- Import sorting: isort-compatible (ruff
Irules) - Target: Python 3.10
- Excluded from linting:
.github/,dapr/proto/
Run formatting and lint fixes:
ruff check --fix
ruff formatType checking: MyPy
mypy --config-file mypy.iniMyPy is configured to check: dapr/actor/, dapr/clients/, dapr/conf/, dapr/serializers/, ext/dapr-ext-grpc/, ext/dapr-ext-fastapi/, ext/flask_dapr/, and examples/demo_actor/. Proto stubs (dapr.proto.*) have errors ignored.
- DCO required: Every commit must include a
Signed-off-byline. Usegit commit -sto add it automatically. - CI checks: Linting (ruff), unit tests (Python 3.10-3.14), type checking (mypy), and DCO verification run on all PRs.
- Branch targets: PRs go to
mainorrelease-*branches. - Tag-based releases: Tags like
v*,workflow-v*,grpc-v*,fastapi-v*,flask-v*,langgraph-v*,strands-v*trigger PyPI publishing for the corresponding package.
When completing any task on this project, work through this checklist. Not every item applies to every change — use judgment — but always consider each one.
- Read the relevant existing source files before making changes
- Understand the existing patterns in the area you're modifying (naming, error handling, async vs sync)
- Check if there's both a sync and async variant that needs updating (see
dapr/aio/and extensionaio/subdirectories) - Read the relevant extension's
AGENTS.mdfor architecture and gotchas specific to that area
- Follow existing code style: single quotes, 100-char lines, Python 3.10+ syntax
- Do not edit files under
dapr/proto/— these are auto-generated - Do not add
__init__.pyfiles to namespace package roots in extensions
- Add or update unit tests under
tests/(core SDK) orext/*/tests/(extensions) - Tests use
unittest— follow the existing test patterns in the relevant directory - Verify tests pass:
python -m unittest discover -v ./tests(or the relevant test directory)
- Run
ruff check --fix && ruff formatand fix any remaining issues - Run
mypy --config-file mypy.iniif you changed files covered by mypy (actor, clients, conf, serializers, ext-grpc, ext-fastapi, flask_dapr)
- If you added a new user-facing feature or building block, add or update an example in
examples/ - Ensure the example README has
<!-- STEP -->blocks withexpected_stdout_linesso it is validated in CI - If you added a new example, register it in
tox.iniunder[testenv:examples] - If you changed output format of existing functionality, update
expected_stdout_linesin affected example READMEs - See
examples/AGENTS.mdfor full details on writing examples
- Update docstrings if you changed a public API's signature or behavior
- Update the relevant example README if the usage pattern changed
- Run
tox -e ruff— linting must be clean - Run
tox -e py311(or your Python version) — all unit tests must pass - If you touched examples:
tox -e example-component -- <example-name>to validate locally - Commits must be signed off for DCO:
git commit -s
| File | Purpose |
|---|---|
setup.cfg |
Core package metadata and dependencies |
setup.py |
Package build script (handles dev version suffixing) |
pyproject.toml |
Ruff configuration |
tox.ini |
Test environments and CI commands |
mypy.ini |
Type checking configuration |
dev-requirements.txt |
Development/test dependencies |
dapr/version/__init__.py |
SDK version string |
ext/*/setup.cfg |
Extension package metadata and dependencies |
examples/validate.sh |
Entry point for mechanical-markdown example validation |
- Namespace packages: Do not add
__init__.pyto the top-leveldapr/directory in extensions — it will break namespace package resolution. - Proto files: Never manually edit anything under
dapr/proto/. These are generated. - Extension independence: Each extension is a separate PyPI package. Core SDK changes should not break extensions; extension changes should not require core SDK changes unless intentional.
- DCO signoff: PRs will be blocked by the DCO bot if commits lack
Signed-off-by. Always usegit commit -s. - Ruff version pinned: Dev requirements pin
ruff === 0.14.1. Use this exact version to match CI. - Examples are integration tests: Changing output format (log messages, print statements) can break example validation. Always check
expected_stdout_linesin example READMEs when modifying user-visible output. - Background processes in examples: Examples that start background services (servers, subscribers) must include a cleanup step to stop them, or CI will hang.
- Workflow is the most active area: See
ext/dapr-ext-workflow/AGENTS.mdfor workflow-specific architecture and constraints.