from dash import Dash, dcc, html, Input, Output, State, callback★The imports nearly every app needs.app = Dash(__name__)★Create the app; passexternal_stylesheets=if needed.app.layout = html.Div([ … ])★Assign the component tree (a list works too).if __name__ == "__main__": app.run(debug=True)★debug=Truegives hot-reload + error overlay.server = app.serverThe underlying WSGI/ASGI app — forgunicorn app:server.Dash(__name__, backend="fastapi")Dash 4.2+: run on Flask (default), FastAPI, or Quart.
html.Div(children=[ … ])★The generic container;childrenis the first positional arg.html.H1("Title"), html.P("text")★One class per HTML tag (H1…H6,Span,Label,A,Img).html.Button("Click", id="btn")★Itsn_clicksproperty is the classic callback Input.html.A("link", href="/page")Anchor; usedcc.Linkfor in-app navigation.id="my-id"★The handle callbacks use — must be unique.className="row", style={ … }classNamefor CSS classes;stylefor inline (card 3).
style={"backgroundColor": "navy", "padding": 10}★Inline CSS as a dict — keys are camelCase.html.Div([html.H1(…), dcc.Graph(…)])Nest components to build the tree.Dash(__name__, external_stylesheets=[…])Load CSS / themes (e.g. a Bootstrap URL).import dash_bootstrap_components as dbcdbc.Row/dbc.Col/dbc.Cardfor responsive grids.import dash_mantine_components as dmcModern component kit — a popular alternative to dbc.# assets/ folder auto-loads .css & .jsDrop files inassets/and Dash serves them.
dcc.Graph(id="g", figure=fig)★Renders a Plotly figure; the heart of most apps.dcc.Dropdown(options=[…], value="a")★Callback reads itsvalue;multi=Truefor many.dcc.Slider(min=0, max=10, value=5)★RangeSliderfor a low–high pair.dcc.Input(type="number", debounce=True)debouncewaits for Enter/blur before firing.dcc.Checklist(…) · dcc.RadioItems(…)Multi-select vs single-select.dcc.DatePickerRange(…) · dcc.Tabs(…)Dates and tabbed sections.dcc.Markdown("# hi")Render Markdown (with optionalmathjax=True).
dcc.Store(id="s", storage_type="session")★Keep data client-side:memory·session·local.dcc.Interval(interval=1000, n_intervals=0)Tick every N ms — drives live/streaming updates.dcc.Location(id="url")Read/route the browser URL (multi-page nav).dcc.Upload(…) · dcc.Download(…)File in / file out (pair withdcc.send_data_frame).dcc.Loading(children=dcc.Graph(…))Auto spinner while a wrapped output updates.
@callback(★Decorator, directly above the function (no blank line).Output("out", "figure"),updates(componentid, property) that receives the return.Input("ctrl", "value"))triggersAny change here re-runs the callback.def update(value): return fig★Args match Inputs by position; the return goes to Output.# ids must exist in app.layoutEvery referencedid/property must be in the layout.# every property is reactiveAny component property can be an Input or Output.
Input("a","value"), Input("b","value")★Many Inputs → many function args, in order.Output("x","children"), Output("y","figure")Many Outputs →return a, b(a tuple).State("in", "value")read-onlyRead a value without triggering — pair with a Button Input.prevent_initial_call=True★Skip the automatic call when the app first loads.# chaining: one Output is another's InputCallbacks fire in dependency order automatically.
from dash import ctx★The callback context (alias ofcallback_context).ctx.triggered_id★Which componentidactually fired the callback.return dash.no_update★Leave an Output unchanged (per-output with a tuple).raise PreventUpdateAbort the whole callback — update nothing.Output("o","children", allow_duplicate=True)Let a second callback also target that Output.
Input("g", "hoverData")★React to the point under the cursor.Input("g", "clickData")React to a clicked point.Input("g", "selectedData")Box/lasso selection → crossfilter other charts.Input("g", "relayoutData")Zoom/pan ranges — sync views together.fig.update_layout(clickmode="event+select")Enable click-to-select on the figure.
from dash import MATCH, ALL, ALLSMALLER★Wildcards for components created at runtime.id={"type": "filter", "index": i}★Give dynamic components a dict id.Input({"type": "filter", "index": MATCH}, "value")★MATCH— fires once, for the one that changed.Input({"type": "filter", "index": ALL}, "value")ALL— collects every match into a list.ctx.triggered_id["index"]Read which dict-id instance fired.
from dash import Patch★Update part of a prop without resending the whole thing.p = Patch(); p["data"][0]["x"] = xs; return pGreat for appending to figures / editing lists in place.dash.clientside_callback("function(x){…}", …)★Run JS in the browser — zero server round-trip.ClientsideFunction(namespace=, function_name=)Reference JS from yourassets/folder.
@callback(…, background=True)★Run off the request thread so the UI stays responsive.manager = DiskcacheManager(…)Dev; useCeleryManagerfor production.running=[(Output("btn","disabled"), True, False)]Toggle props while it runs (disable a button, show a spinner).progress=[Output("bar","value")]Stream progress to a component as it works.cancel=[Input("cancel","n_clicks")]Let the user abort a running job.
Dash(__name__, use_pages=True)★Turn on the built-in pages system.dash.register_page(__name__, path="/")★Call it at the top of each file inpages/.dash.page_container★Put this inapp.layoutwhere pages should render.dash.page_registryIterate registered pages to build a nav bar.dcc.Link("Home", href="/")Client-side navigation — no full reload.
dcc.Store as an Output, then an Input★The right way to pass data between callbacks.# data must be JSON-serializableStores hold JSON — convert DataFrames with.to_dict().# don't mutate module globalsCallbacks must be stateless — workers don't share memory.gunicorn app:server★Production server;server = app.serverfirst.app.run(host="0.0.0.0", port=8050)Expose it; default is127.0.0.1:8050.
app.layout = a tree of components★What the app looks like — declarative, in the browser.@callback = Python that reacts★How it behaves — runs on the server.Input triggerstriggersA change to this property re-runs the callback.Output updatesupdatesThe return value is written to this property.State reads without triggeringGrab a value only when something else fires.every property is reactive; Dash syncs the rest★You wire dependencies; Dash handles the round-trips.
blank line under @callbackbreaksThe decorator must sit directly above the function.id not in layoutEvery callbackid/prop must exist inapp.layout.two callbacks → one OutputNeedsallow_duplicate=Trueon the Output.style={"background-color": …}Wrong — style keys are camelCase (backgroundColor).app.run_server(…)renamedDash 3.0+: useapp.run().import dash_core_componentsremovedDash 3.0+:from dash import dcc, html.mutating a global in a callbackNon-deterministic across workers — usedcc.Store.