Skip to content

Commit 312c6e3

Browse files
committed
update ai docs to include backends
1 parent 9b38d60 commit 312c6e3

2 files changed

Lines changed: 154 additions & 6 deletions

File tree

.ai/ARCHITECTURE.md

Lines changed: 141 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
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

505628
1. `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
507630
3. Jupyter comm protocol negotiates proxy configuration
508631
4. App displays according to selected mode
509632

510633
```
511634
app.run() in notebook
512635
513-
Detect Jupyter → Start Flask in background thread
636+
Detect Jupyter → Start server in background thread
514637
515638
Comm 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
686810
pip install dash[async]
687811
```
@@ -692,6 +816,16 @@ Async is auto-enabled when `asgiref` is detected. Or explicitly:
692816
app = 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

.ai/COMMANDS.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,19 @@ pip install -e .[ci,dev,testing,celery,diskcache]
1414
npm ci
1515
```
1616

17+
### Optional Backend Dependencies
18+
19+
```bash
20+
# For Quart backend (ASGI async)
21+
pip install dash[quart]
22+
23+
# For FastAPI backend (ASGI async)
24+
pip install dash[fastapi]
25+
26+
# For async callbacks with Flask
27+
pip install dash[async]
28+
```
29+
1730
## Building
1831

1932
```bash

0 commit comments

Comments
 (0)