Async port of the official Plotly Dash library
Project description
Async Dash
async-dash is an async port of Plotly Dash library, created by replacing its Flask
backend with its async counterpart Quart.
It started with my need to be able to create realtime dashboards with dash, specifically with event-driven
architecture. Using async-dash with components from dash-extensions
such as WebSocket, EventSource, etc. you can create truly event-based or realtime dashboards.
Table Of Contents
Installation
pip install async-dash
Usage
from async_dash import Dash
from dash import html, dcc
Examples
Basic Async Callback
import asyncio
import time
from dash import Input, Output, html
from quart import Quart
from async_dash import Dash
server = Quart(__name__)
app = Dash(__name__, server=server)
app.layout = html.Div([
html.Button("Async Request (2s delay)", id="async-btn", n_clicks=0),
html.Div(id="async-output"),
])
@app.callback(
Output("async-output", "children"),
Input("async-btn", "n_clicks"),
prevent_initial_call=True,
)
async def async_callback(n_clicks):
"""Async callback that simulates a slow async operation.
This could be an API call, a database query, etc.
"""
start = time.time()
# This is non-blocking - other requests can be processed during this sleep
await asyncio.sleep(2)
elapsed = time.time() - start
return f"Async callback #{n_clicks} completed in {elapsed:.2f}s (non-blocking!)"
if __name__ == "__main__":
app.run(debug=True, port=8050)
Sync Callbacks Still Work
from dash import Input, Output, html
from quart import Quart
from async_dash import Dash
server = Quart(__name__)
app = Dash(__name__, server=server)
app.layout = html.Div([
html.Button("Sync Request", id="sync-btn", n_clicks=0),
html.Div(id="sync-output"),
])
@app.callback(
Output("sync-output", "children"),
Input("sync-btn", "n_clicks"),
prevent_initial_call=True,
)
def sync_callback(n_clicks):
"""Sync callback - still works with async-dash."""
return f"Sync callback #{n_clicks} completed instantly!"
if __name__ == "__main__":
app.run(debug=True, port=8050)
WebSocket Example
Using websockets for real-time updates with dash-extensions:
import asyncio
import random
from dash import Input, Output, dcc, html
from dash_extensions import WebSocket
from quart import Quart, json, websocket
from async_dash import Dash
server = Quart(__name__)
app = Dash(__name__, server=server)
app.layout = html.Div([
WebSocket(id="ws", url="/ws"),
html.H3("Live Random Data (via WebSocket)"),
dcc.Graph(id="graph"),
])
app.clientside_callback(
"""
function(msg) {
if (msg) {
const data = JSON.parse(msg.data);
return {data: [{y: data, type: "scatter"}]};
} else {
return {};
}
}""",
Output("graph", "figure"),
[Input("ws", "message")],
)
@server.websocket("/ws")
async def random_data():
while True:
output = json.dumps([random.random() for _ in range(10)])
await websocket.send(output)
await asyncio.sleep(1)
if __name__ == "__main__":
app.run()
Running with Uvicorn
For production, use an ASGI server like uvicorn:
uvicorn example:server --host 0.0.0.0 --port 8050
Motivation
In addition to all the advantages of writing async code, async-dash enables you to:
- Run truly asynchronous callbacks
- Use websockets, server sent events, etc. without needing to monkey patch the Python standard library
- Use
quart/fastapi/starletteframeworks with your dash apps side by side - Use HTTP/2 (especially server push) if you use an HTTP/2 enabled server such
as
hypercorn
Caveats
I'm maintaining this library as a proof of concept for now. It should not be used for production. If you do decide to use it, I'd love to hear your feedback.
TODO
- Gather reviews and feedback from the Dash Community.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file async_dash-0.1.0.tar.gz.
File metadata
- Download URL: async_dash-0.1.0.tar.gz
- Upload date:
- Size: 26.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6edfdc55a9d58b5faa6453b8efcd5e99c7489e683f0094d0af31640482c940a5
|
|
| MD5 |
7cc3ddcb903342b5892a4dabd74e46b2
|
|
| BLAKE2b-256 |
a8be3958492c17c9c377ae3e751a617c1f29724a7139d5f0763e0c3c85d9fbed
|
File details
Details for the file async_dash-0.1.0-py3-none-any.whl.
File metadata
- Download URL: async_dash-0.1.0-py3-none-any.whl
- Upload date:
- Size: 5.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e7f53b28e9690eca5c17d1c441ca22ed4d3b3283779f25d27ed5b56b00ddf055
|
|
| MD5 |
0a1f6553304e5f492726687e969db42d
|
|
| BLAKE2b-256 |
cb5cd6e37f6710e335ea539159cbe6233f69dac182553de9a0e3320f0bd11f42
|