Phase 3 — CRUD and data-heavy patterns
This note complements PERFORMANCE.md with repeatable shapes for list/detail/edit flows on Streamlit’s rerun model. It is not a full admin framework: stay with explicit state, elements, and optional extras.
Cookbook: List / detail / save (CRUD) embeds the two CRUD demos end-to-end.
Building blocks
| Concern | StreamTree pieces |
|---|---|
| Tabular data | DataGrid ([tables] extra) or DataFrame for simple tables |
| Filters in the URL | routing.sync_query_value / set_query_value (see PERFORMANCE) |
| Forms | Form, TextInput, streamtree.forms, streamtree.forms_layout |
| Async save/load | streamtree.asyncio.submit / submit_many + TaskHandle |
| Declarative branches | streamtree.loading.match_task; parallel waits → match_task_many |
| CRUD URL + save intent | streamtree.crud.selected_id_from_query, save_intent_counter (see examples) |
| Heavy subtree reuse | streamtree.state.memo_subtree (render-path scoped; see PERFORMANCE) |
| Lower-priority UI block | DeferredFragment (uses st.fragment when present; see PERFORMANCE) |
| Failure isolation | ErrorBoundary around risky subtrees |
Recommended flow
- List — Hold rows in
state(..., key=...)(or load viasubmitandmatch_task). For rich grids, bindDataGridselection to session state keysstreamlit-aggridexposes (or useDataGrid.on_resultto observe theAgGridreturn value in the same run), then mirror into aStateVarin your@componenton the next rerun. - Selection — Keep
selected_id(or similar) instate. Row actions useButton.on_clickor grid callbacks to update selection and seed edit fields. - Edit — Use
Form+TextInput(value=state_var)so submit batches match Streamlit’s form semantics. - Save — Start
submit(save_fn, key="...")from the render path when the user intent is clear (for example after a “Save” click sets asave_versioncounter you read on the next rerun). Usematch_task(ormatch_task_manyif several keys must finish together) to swap loading / success / error UI. - Cleanup — After a terminal task, call
dismiss_task/dismiss_tasksbefore reusing the samekeyfor a new logical job (see PERFORMANCE andstreamtree.asynciodocstring).
Example
examples/crud_pattern_demo.py shows in-memory list/edit/add plus match_task_many over two parallel submit handles (stand-ins for reference data). Swap the bodies for real I/O as needed. On this doc site, the same file is included in full on the Examples page.
examples/crud_automation_demo.py wires streamtree.crud helpers (URL id + save-intent counter) next to normal state. Full source: Examples.
CLI scaffolding (0.10.0+)
With pip install "streamtree[cli]", streamtree init --template crud (or explore, enterprise, default) writes a matching app.py under the target directory; combine with --with-pages and --name as needed. See examples/streamtree_run_demo.md and streamtree.helpers.scaffold.
Charts and reporting
Optional [charts] provides Chart (Plotly), AltairChart (Altair), and EChartsChart (Apache ECharts / streamlit-echarts). Prefer small, composable chart elements next to tables rather than oversized single-page dashboards unless you add fragment() or portal-based shells for layout control. DataGrid.on_result (same-run hook after AgGrid) can mirror grid return values into state() on the next interaction-driven rerun.