The Flask extension provides two integration classes for building Dapr applications with Flask: DaprApp for pub/sub subscriptions and DaprActor for actor hosting. It mirrors the FastAPI extension's functionality but uses Flask's routing and request model.
dapr/ext/flask/
├── __init__.py # Exports: DaprApp, DaprActor
├── app.py # DaprApp — pub/sub subscription handler
├── actor.py # DaprActor — actor runtime HTTP adapter
└── py.typed
tests/ext/flask/
├── test_app.py # DaprApp pub/sub tests
└── test_shim_deprecation.py # Locks the legacy `flask_dapr` shim contract
Installed via the flask extra on core dapr: pip install "dapr[flask]".
The legacy top-level import path (from flask_dapr import DaprApp, DaprActor) is still supported through a thin shim at the repo root that emits a FutureWarning. The shim is kept through 1.21 and removed in 1.22, giving users on 1.18 (the last release to ship the standalone distributions) the full N-2 support window to migrate. All new code and docs should use the canonical from dapr.ext.flask import ... path.
from dapr.ext.flask import DaprApp, DaprActorWraps a Flask instance to add Dapr pub/sub event handling.
app = Flask('myapp')
dapr_app = DaprApp(app)
@dapr_app.subscribe(pubsub='pubsub', topic='orders', route='/handle-order',
metadata={}, dead_letter_topic=None)
def handle_order():
event_data = request.json
return 'ok'- Auto-registers
GET /dapr/subscribeendpoint - Each
@subscriberegisters a POST route viaadd_url_rule() - Default route:
/events/{pubsub}/{topic} - Handlers use Flask's
requestcontext (not function arguments)
Integrates Dapr's actor runtime with Flask.
app = Flask('actor_service')
dapr_actor = DaprActor(app)
dapr_actor.register_actor(MyActorClass)Auto-registers six endpoints (same as FastAPI extension):
GET /healthz,GET /dapr/configDELETE /actors/{type}/{id}— deactivationPUT /actors/{type}/{id}/method/{method}— method invocationPUT /actors/{type}/{id}/method/timer/{timer},PUT /actors/{type}/{id}/method/remind/{reminder}
Async bridging: Uses asyncio.run() to bridge Flask's synchronous request handling with the async ActorRuntime. Each handler call spawns a new event loop.
Response wrapping (wrap_response): Same pattern as FastAPI extension — string → JSON, bytes → raw, dict → JSON. Error responses include errorCode field.
dapr(core, same wheel as this extension)Flask >= 1.1.4, < 4.0.0
# Unittest-style tests (test_app.py)
uv run python -m unittest discover -v ./tests/ext/flask
# The shim deprecation test is pytest-style — run with pytest
uv run pytest tests/ext/flasktest_app.py— uses Flasktest_client()for HTTP-level testing: subscription registration, custom routes, metadata, dead letter topicstest_shim_deprecation.py— asserts thatimport flask_dapremitsFutureWarningand re-exportsDaprApp/DaprActorcorrectly
Note: No tests for DaprActor in this extension (unlike FastAPI which tests _wrap_response).
- Synchronous + asyncio bridge: Flask is sync, but
ActorRuntimeis async. The extension usesasyncio.run()for each actor operation. - Canonical import path: Use
from dapr.ext.flask import DaprApp, DaprActor. The legacyflask_daprtop-level path still works but emitsFutureWarningand will be removed in 1.22. - Similar to FastAPI extension: The two extensions have nearly identical functionality. When modifying one, check if the same change is needed in the other.
- Reentrancy ID: Actor method invocation extracts
Dapr-Reentrancy-Idheader, same as FastAPI extension.