22
33## Python Backend Framework
44
5- - ** ` dash/dash.py ` ** - Main ` Dash ` application class (~ 2000 lines). Orchestrates Flask server, layout management, callback registration, routing, and asset serving. Key methods: ` layout ` property, ` callback() ` , ` clientside_callback() ` , ` run() ` .
5+ - ** ` dash/dash.py ` ** - Main ` Dash ` application class (~ 2000 lines). Orchestrates the server backend, layout management, callback registration, routing, and asset serving. Key methods: ` layout ` property, ` callback() ` , ` clientside_callback() ` , ` run() ` .
6+
7+ - ** ` dash/backends/ ` ** - Server backend implementations. See [ Server Backends] ( #server-backends ) section for details.
68
79- ** ` dash/_callback.py ` ** - Callback registration and execution. Contains ` callback() ` decorator (usable as ` @dash.callback ` without app instance), ` clientside_callback() ` , and ` register_callback() ` which inserts callbacks into the callback map.
810
@@ -101,6 +103,127 @@ Use dict IDs with wildcards (`MATCH`, `ALL`, `ALLSMALLER`) to target dynamically
101103- ` /_dash-component-suites/<package>/<path> ` - Serves component JS/CSS assets
102104- ` /assets/<path> ` - Serves static assets from app's assets folder
103105
106+ ## Server Backends
107+
108+ Dash supports multiple web server backends. The backend abstraction is in ` dash/backends/ ` .
109+
110+ ### Available Backends
111+
112+ | Backend | Type | Install | Use Case |
113+ | ---------| ------| ---------| ----------|
114+ | ** Flask** (default) | WSGI (sync) | ` pip install dash ` | Standard deployments, simplicity |
115+ | ** Quart** | ASGI (async) | ` pip install dash[quart] ` | Async callbacks, WebSocket support |
116+ | ** FastAPI** | ASGI (async) | ` pip install dash[fastapi] ` | OpenAPI docs, async, modern Python |
117+
118+ ### Usage
119+
120+ ** Default (Flask):**
121+ ``` python
122+ from dash import Dash
123+ app = Dash(__name__ )
124+ ```
125+
126+ ** With existing server instance:**
127+ ``` python
128+ from flask import Flask
129+ from dash import Dash
130+
131+ server = Flask(__name__ )
132+ app = Dash(__name__ , server = server)
133+ ```
134+
135+ ** Quart backend:**
136+ ``` python
137+ from quart import Quart
138+ from dash import Dash
139+
140+ server = Quart(__name__ )
141+ app = Dash(__name__ , server = server)
142+ ```
143+
144+ ** FastAPI backend:**
145+ ``` python
146+ from fastapi import FastAPI
147+ from dash import Dash
148+
149+ server = FastAPI()
150+ app = Dash(__name__ , server = server)
151+
152+ # Run with: uvicorn module:app.server --reload
153+ ```
154+
155+ ### Architecture
156+
157+ The backend system uses an abstract interface:
158+
159+ - ** ` BaseDashServer ` ** (` dash/backends/base_server.py ` ) - Abstract base class defining the server interface. All backends implement this.
160+
161+ - ** ` RequestAdapter ` ** - Normalizes HTTP request objects across frameworks. Provides unified access to ` args ` , ` cookies ` , ` headers ` , ` get_json() ` , etc.
162+
163+ - ** ` ResponseAdapter ` ** - Normalizes response creation. Handles ` set_cookie() ` , ` set_header() ` , ` set_response() ` .
164+
165+ - ** ` get_backend(name) ` ** - Factory function to get backend class by name (` "flask" ` , ` "quart" ` , ` "fastapi" ` ).
166+
167+ - ** ` get_server_type(server) ` ** - Auto-detects backend from a server instance.
168+
169+ ### Backend Implementations
170+
171+ ** Flask** (` dash/backends/_flask.py ` ):
172+ - ` FlaskDashServer ` - Wraps Flask app
173+ - ` FlaskRequestAdapter ` - Uses ` flask.request ` proxy
174+ - ` FlaskResponseAdapter ` - Uses ` flask.Response `
175+ - Compression via ` flask-compress `
176+
177+ ** Quart** (` dash/backends/_quart.py ` ):
178+ - ` QuartDashServer ` - Wraps Quart app (async Flask API)
179+ - ` QuartRequestAdapter ` - Uses ` quart.request ` proxy
180+ - ` QuartResponseAdapter ` - Uses ` quart.Response `
181+ - All route handlers are ` async def `
182+ - Compression via ` quart-compress `
183+
184+ ** FastAPI** (` dash/backends/_fastapi.py ` ):
185+ - ` FastAPIDashServer ` - Wraps FastAPI app
186+ - ` FastAPIRequestAdapter ` - Uses context variable for current request
187+ - ` FastAPIResponseAdapter ` - Uses Starlette responses
188+ - ` DashMiddleware ` - Consolidated ASGI middleware for request handling
189+ - Runs with uvicorn, supports hot reload
190+ - Built-in GZip compression
191+
192+ ### Key Interface Methods
193+
194+ All backends implement:
195+
196+ ``` python
197+ class BaseDashServer (ABC ):
198+ def create_app (name , config ) -> server # Create new server
199+ def add_url_rule(rule, view_func, ... ) # Register routes
200+ def before_request(func) # Request hooks
201+ def after_request(func) # Response hooks
202+ def run(dash_app, host, port, debug) # Start dev server
203+ def make_response(data, mimetype, status) # Create response
204+ def jsonify(obj) # JSON response
205+ def setup_index(dash_app) # Register / route
206+ def serve_callback(dash_app) # Callback endpoint
207+ def setup_component_suites(dash_app) # JS/CSS serving
208+ ```
209+
210+ # ## Accessing the Backend
211+
212+ ```python
213+ app = Dash(__name__ )
214+
215+ # Get the underlying server
216+ app.server # Flask/Quart/FastAPI instance
217+
218+ # Get the backend wrapper
219+ app.backend # BaseDashServer subclass instance
220+ app.backend.server_type # "flask", "quart", or "fastapi"
221+
222+ # Access request in callbacks
223+ from dash import dash
224+ dash.get_app().backend.request_adapter() # RequestAdapter instance
225+ ```
226+
104227# # Frontend (dash-renderer)
105228
106229** `dash/ dash- renderer/ src/ ` ** contains the TypeScript/ React frontend. See [RENDERER .md](RENDERER .md) for detailed documentation on:
@@ -503,14 +626,14 @@ app.run(
503626# ## How It Works
504627
5056281 . `app.run()` detects Jupyter environment via `get_ipython()`
506- 2 . Flask server starts in background daemon thread
629+ 2 . Server starts in background daemon thread
5076303 . Jupyter comm protocol negotiates proxy configuration
5086314 . App displays according to selected mode
509632
510633```
511634app.run() in notebook
512635 ↓
513- Detect Jupyter → Start Flask in background thread
636+ Detect Jupyter → Start server in background thread
514637 ↓
515638Comm request → Extension responds with base_url
516639 ↓
@@ -572,8 +695,8 @@ Special handling for Colab:
572695# ## Dash() Constructor Parameters
573696
574697** Basic Setup:**
575- - ` name ` - Flask app name (default: infers from ` __name__ ` )
576- - ` server ` - Flask instance or ` True ` to create new (default: ` True ` )
698+ - `name` - Application name (default: infers from `__name__ ` )
699+ - `server` - Server instance (Flask, Quart, or FastAPI) or `True ` to create Flask (default: `True ` )
577700- `title` - Browser tab title (default: `" Dash" ` )
578701- `update_title` - Title during callbacks (default: `" Updating..." ` )
579702
@@ -682,6 +805,7 @@ Dash supports `async def` callbacks for non-blocking execution.
682805
683806# ## Setup
684807
808+ ** With Flask backend:**
685809```bash
686810pip install dash[async ]
687811```
@@ -692,6 +816,16 @@ Async is auto-enabled when `asgiref` is detected. Or explicitly:
692816app = Dash(__name__ , use_async = True )
693817```
694818
819+ ** With Quart or FastAPI backend:** Async is native - no extra dependencies needed.
820+
821+ ```python
822+ from fastapi import FastAPI
823+ from dash import Dash
824+
825+ server = FastAPI()
826+ app = Dash(__name__ , server = server) # Async works automatically
827+ ```
828+
695829# ## Usage
696830
697831```python
@@ -708,7 +842,8 @@ async def async_update(value):
708842- Regular async callbacks are ** non- blocking** - multiple can run concurrently
709843- Background callbacks also support `async def `
710844- Jupyter uses `nest_asyncio` for event loop compatibility
711- - Without ` dash[async] ` , coroutines raise an error
845+ - With Flask backend: requires `dash[async ]` , coroutines raise error without it
846+ - With Quart/ FastAPI backends: async is native, no extra setup needed
712847
713848# ## Async with Background Callbacks
714849
0 commit comments