Changelog
All notable changes to this project are documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[0.11.0] — 2026-05-13
Added
- CLI (
[cli]):streamtree tree(module:attr,--format,--summarize,--expand-components);streamtree previewandstreamtree serveas aliases ofrun;streamtree doctor --verbose. streamtree.helpers.tree_target.load_element_from_targetfor resolvingmodule:attrtrees.streamtree.testing.viz:format_tree_text,tree_dict_to_mermaidfor human-readable tree views.streamtree.testing.introspection:iter_streamtree_session_keys,summarize_streamtree_session_state.streamtree.testing.apptest.run_app_functionwrapper aroundAppTest.from_function(...).run.streamtree.asyncio.summarize_async_tasksfor read-only summaries of managed task slots.streamtree.debug_render_path(re-exported fromstreamtree.core.context).- Docs:
docs/TESTING_AND_DEBUG.md; MkDocs API reference pages (mkdocstrings);.readthedocs.ymlfor Read the Docs builds. examples: package__init__.pyandexamples.counter.streamtree_tree_rootforstreamtree treedemos.tests/test_examples_run.py:AppTest.from_filesmoke test for everyexamples/*.pyandexamples/pages/*.pyscript (asserts noat.exceptionentries);echarts_demo.pyis skipped becausestreamlit-echartscustom-component registration fails in the AppTest harness.- CI / Actions: reusable workflows (
reusable-lint-test.yml,reusable-cli-smoke.yml,reusable-docs-and-dist.yml),workflow_dispatchonci.yml, release concurrency (cancel-in-progress: false), job timeouts, Dependabot for GitHub Actions; releasedocs-and-distruns MkDocs +uv buildon Python 3.12 and uploadsdist/for publish jobs (replaces standalonebuild-diston 3.11).
Fixed
- CI:
ruff format --check— apply Ruff formatting totests/test_tree_viz.py(was failinglint-testmatrix on push). examples/crud_pattern_demo.py: form actions useButton(..., submit=True)so Streamlit receivesst.form_submit_buttoninstead ofst.buttoninsidest.form.examples/numeric_nav_demo.py:PageLinktargetspages/1_About_demo.py(a valid multipage path relative to the entrypoint; siblingcounter.pyis not a discoverable page forst.page_link).
Documentation
docs/EXAMPLES.md: MkDocs / Read the Docs page with embedded full source for everyexamples/*.pyandexamples/streamtree_run_demo.md(viapymdownx.snippets).docs/recipes/: Cookbook pages (first app, state, forms, routing, async, multipage, shell/theme, layouts, data extras, CRUD, auth, CLI, portals, organization, observability, Streamlit interop).- MkDocs Material:
mkdocs-materialtheme, tabbed nav (Home, Examples, Recipes, Guides, API reference), extended Markdown (admonitions, details, tabbed, highlight, emoji, tables),docs/getting-started.md, redesigneddocs/index.md,docs/stylesheets/extra.css,site_url/edit_uri; Guides split into Design & roadmap vs Operations; nested API reference; ROADMAP internal anchors updated for Material heading slugs. - README: shortened for PyPI / GitHub; Read the Docs as the primary learning surface with a compact doc map and RTD links.
- Docs URLs: PyPI Documentation, MkDocs
site_url, and README RTD links use/en/latest/(shields docs badge usesreadthedocs/streamtree/latest) becausestableis not yet serving; roadmap notesstablewhen versioned RTD builds are active.
0.10.0 — 2026-05-13
Added
AltairChart([charts]extra): Altair specs viast.altair_chart;altairpinned alongsideplotlyin[charts]/[all]/[dev].EChartsChart([charts]extra): ECharts option dicts viastreamlit_echarts.st_echarts;streamlit-echartspinned withplotlyandaltairin[charts]/[all]/[dev].DataGrid.on_result: optional callback invoked once after a successfulAgGridcall with the grid return value (selection / updates); not called ifAgGridraises.streamtree.loading.match_task_many: declarative subtree when all pollable handles aredone, with any-error and any-cancelled semantics (see docstring anddocs/PERFORMANCE.md).streamtree.loading.submit_many_ordered: startsubmit_manyjobs in sorted key order somatch_task_manyresult tuples are stable.streamtree.state.memo_subtree: memoize values keyed by render path + logical key +depsfingerprint (seedocs/PERFORMANCE.md).streamtree.elements.DeferredFragment: defer child rendering withst.fragmentwhen the Streamlit version exposes it.streamtree.crud:selected_id_from_query,save_intent_counterfor list/detail/save flows (not a full admin framework).streamtree.enterprise: optionalEventSinkviaapp_context,emit_event,tenant_id,redact_secrets(no extra pinned vendors).streamtree.perf:perf_bump/perf_snapshotwithPERF_COUNTERS_KEYinapp_contextfor lightweight counters.streamtree.helpers.explore:column_summary(stdlib);dataframe_profilewhen pandas is present ([tables]).streamtree.testing.summarize_tree_kinds: count elementkindvalues inrender_to_treeoutput.- CLI:
streamtree init --template/-tfordefault,crud,explore,enterprisescaffolds. - Docs:
docs/PHASE3_CRUD.md— Phase 3 list/detail/save patterns withDataGrid, routing, async,match_task/match_task_many;docs/PERFORMANCE.mdupdates for large trees and hooks. - Example:
examples/altair_chart_demo.py,examples/crud_pattern_demo.py,examples/crud_automation_demo.py,examples/echarts_demo.py,examples/datagrid_selection_demo.py,examples/deferred_region_demo.py,examples/async_ordered_loader_demo.py.
Changed
streamtree.__version__readsimportlib.metadata.version("streamtree")so it trackspyproject.tomlfor editable installs, wheels, and PyPI (cross-checked intests/test_package_meta.py).- CI: Windows matrix pins
windows-2025-vs2026instead ofwindows-latestto avoid image redirect notices. - Release workflow: tag builds publish to PyPI and GitHub Packages (see
.github/workflows/release.yml).
0.9.0 — 2026-05-13
Added
streamtree.portals:gather_portals,portal_render_context,take_portal_children; layout elementsPortal,PortalMount(named-slot deferred rendering; seedocs/PHASE2_PORTALS_AND_PREFETCH.md).SplitViewlayout (narrow + main column strip, pseudo-sidebar without a secondst.sidebar).streamtree.helpers.pages:iter_page_entries,prefetch_page_sources(optionalcompile()syntax warm-up for page scripts without importing modules);group_page_entries_by_order_prefix,page_links_sidebar_sections,multipage_sidebar_nav(sectioned sidebar nav).streamtree.forms_layout:model_field_grid,build_model_from_bindingsfor row/column Pydantic forms (including bool fields);bool_field_names,bind_bool_fieldsinstreamtree.forms; docdocs/PHASE2_FORMS.md.[ui]elementsBottomDock(bottom container),FloatingActionButton,Stoggle,TaggerRow,MentionChip(streamlit-extras).- Routing:
clear_query_param,clear_route,update_query_paramsfor URL/session cleanup and multi-key updates. - Async:
dismiss_tasksbatch terminal cleanup. - Docs:
docs/PHASE2_PORTALS_AND_PREFETCH.md(Phase 2 portals / prefetch / form-layout contract);docs/PHASE2_TAIL.mdreconciliation; roadmap Phase 2 closure. - Example:
examples/phase2_composite_demo.py(ErrorBoundary,app_context,Routes,submit_many).
Changed
streamtree.core.component.render/render_appnow run the Streamlit backend’srender()wrapper so portal gather runs once per tree.
0.8.0 — 2026-05-13
Added
streamtree.helpers.pages.page_links: buildPageLinktuples fromdiscover_pages/list_page_entriesoutput (navigation coupling with multipage apps).streamtree.asyncio.dismiss_task: remove a terminal task session entry sosubmitcan reuse the samekey.[ui]elementsSocialBadge(streamlit-extras badges) andStyleMetricCards(metric card CSS helper).streamtree init --with-pages: generatedapp.pynow wiresdiscover_pages+page_linksinto aSidebarNavshell.[tables]optional extra:streamlit-aggrid+DataGridelement andstreamtree.tables.render_datagrid(lazy import with install hint).[charts]optional extra:plotly+Chartelement andstreamtree.charts.render_chart(Plotly viast.plotly_chart).streamtree.routing.sync_query_value/set_query_value: URL ↔ session helpers for arbitrary string query params (including empty defaults), complementingsync_route/set_route.streamtree.loading.match_task: mapTaskHandle.statustoloading/ready/error(and optionalcancelled) element subtrees.- Examples:
examples/datagrid_demo.py,examples/chart_demo.py,examples/async_loader_demo.py. - Docs:
docs/PERFORMANCE.mdplaybook for memoization, async work, URL filters, and optional data extras.
Changed
[all]meta-extra now listsstreamlit-aggrid,plotly, and the existing optional CLI/auth/UI pins for convenience.[dev]includesstreamlit-aggridandplotlyso contributor / CI installs exercise optional render paths.
0.7.1 — 2026-05-13
Changed
- Packaging: version 0.7.1 (patch).
Documentation
- README: CI badge and Actions link use
eddiethedean/streamtreeso Shields.io reflects this fork’s workflow status.
0.7.0 — 2026-05-12
Added
streamtree.asyncio.submit_many: start several independent tasks with unique keys (gather-style composition).- Cooperative cancel:
TaskHandle.cancel()on a running task setscancel_requested; workers pollis_task_cancel_requestedand callcomplete_cancelledto finish as cancelled; normal done still wins if the worker completes without acknowledging cancel.
Documentation
streamtree.asyncio: module docstring sections Stale runs and keys and Cooperative cancellation; README.md background-work bullet; PHASE2_TAIL.md / ROADMAP.md release notes.examples/async_bg.py: demonstratessubmit_many.
0.6.0 — 2026-05-12
Added
- CLI (
[cli]):streamtree initscaffoldsapp.pyand optionalpages/(seestreamtree.helpers.scaffold). - Auth (
[auth]):streamtree.auth.build_authenticator,AuthGateelement (instreamtree.elements.auth_gate), and Streamlit renderer integration forstreamlit-authenticator. - Overlays:
DialogandPopoverlayout elements (st.dialog/st.popoverwith fallbacks);streamlit>=1.33.0core floor. - UI extras (
[ui]):ColoredHeaderandVerticalSpaceLineswrappingstreamlit-extras(lazy import + install hint). - Examples:
examples/overlay_demo.py,examples/auth_demo.py. - Docs:
docs/PHASE2_TAIL.mdfor post-0.6.0 Phase 2 grooming.
Changed
- Dependencies:
streamlit>=1.33.0;[auth]pinsstreamlit-authenticator,[ui]pinsstreamlit-extras;[dev]includes both for contributor / CI installs. session_state(..., default=None): first read on a missing key raisesValueErrorwith a hint instead of a bareKeyError.streamtree.helpers.scaffold.app_py_source: embedspage_titleviarepr()so generatedapp.pystays valid for arbitrary titles.streamtree.asyncio:TaskHandleandset_task_progressonly touch task dicts that include a realthreading.Lock(same shape assubmit); fake_submittedentries without a lock are replaced onsubmit.ErrorBoundary: ifon_errorraises, the error is logged andfallbackis still rendered.
Documentation
- README: 0.6.0 pin, Streamlit 1.33+,
streamtree init, auth / overlay /[ui]capabilities; releases tagv0.6.0; overlay bullet clarifiesDialoglegacy (inline) vsPopover(expander) fallbacks. - ROADMAP.md, PLAN.md, DEPENDENCY_STRATEGY.md: 0.6.0 shipped scope and optional-extra notes (
[all]was documented as an empty stub until 0.8.0 populated the meta-extra). Dialog,App/apply_page_config: docstrings for legacy dialog behavior and one-shotst.set_page_configper session.
0.5.0 — 2026-05-12
Added
streamtree.helpers.pages:PageEntry,pages_dir_next_to,list_page_entries, anddiscover_pagesfor Streamlitpages/discovery (stdlib + pathlib); re-exported fromstreamtree.helpers.streamtree.asyncio:set_task_progressandTaskHandle.progress()for lock-safe, rerun-polled worker progress (task dict includesprogress).- Example:
examples/pages_helpers_demo.pywithexamples/pages/1_About_demo.pystub page. - Tests: expanded coverage for
streamtree.helpers.pages(paths, unicode, ordering, symlinks) andstreamtree.asyncioprogress (poll while running, error path, main-thread updates).
Documentation
- README: 0.5.0 install pin, capabilities for multipage helpers + async progress, example command; releases tag example
v0.5.0. - ROADMAP.md: release index 0.5.0; Phase 2 “Next” backlog adjusted.
- PLAN.md: packaging timeline 0.5.0 bullet.
- DEPENDENCY_STRATEGY.md: asyncio progress note;
helpers.pages+[pages]stub subsection.
0.4.1 — 2026-05-12
Changed
- Packaging: version 0.4.1 (patch); README install pin and release tag example updated to
v0.4.1.
0.4.0 — 2026-05-12
Added
- CLI (optional
[cli]):streamtree rundelegates topython -m streamlit runwith forwarded argv;streamtree doctorprints versions and Typer availability.[project.scripts]entrystreamtree. streamtree.helpers.runner:build_streamlit_run_argv,run_streamlit_sync(stdlib subprocess;FileNotFoundError→ exit code 127; empty args → 2).PageLinkelement mapping tost.page_link(Streamlit ≥ 1.30 in core dependencies).App:initial_sidebar_stateandmenu_itemspassed through tost.set_page_configwhen set.streamtree.forms:numeric_field_names,bind_numeric_fields,number_inputsforint/floatand optional numeric fields.- Example
examples/numeric_nav_demo.pyandexamples/streamtree_run_demo.md(CLI usage).
Changed
- Minimum Streamlit raised to
>=1.30.0(forst.page_link). [cli]extra now lists Typer; stub extras[pages]and[runner]documented (runner helper ships in the default install;[runner]remains metadata-only).
Documentation
- README:
streamtree[cli],streamtree run, Streamlit 1.30+ requirement,v0.4.0release tag example. - DEPENDENCY_STRATEGY.md: CLI /
[pages]/[runner]notes. - ROADMAP.md: 0.4.0 release index; Phase 2 “Next” adjusted.
Fixed
- CI:
cli-smokesets job-levelUV_PYTHONsouv run streamtree doctorreuses the[cli]sync environment (otherwiseuv runcould follow.python-versionand miss Typer).
0.3.0 — 2026-05-12
Added
- Packaging: optional extra
[async]as a TOML-quoted alias of the empty[asyncio]stub extra (matches install examples in the plan and dependency strategy). streamtree.app.Appshell with optional sidebar composition,apply_page_config,app_root_element, andrender_app()(one-timest.set_page_configguard).streamtree.theme:Theme(Pydantic),theme()/theme_css(), andThemeRootelement for CSS injection viaapp_context.provider(theme=...).streamtree.asyncio:submit()/TaskHandlefor daemon-thread background work with session-scoped poll keys (stdlib-only; optional[asyncio]/[async]stub extras unchanged as meta).streamtree.forms:bind_str_fieldsandstr_text_inputsfor declarativeTextInputgrids from Pydantic string fields.- Examples
examples/app_shell.py,examples/async_bg.py,examples/model_form.py.
Changed
- Routing:
sync_route/set_routenow store the active route inst.session_stateunderstreamtree.routing.active.<param>(one slot per query-param name) instead of a single globalstreamtree.routing.activekey. Apps that read that private key must migrate. ErrorBoundary.on_erroris typed asCallable[[Exception], None], matching the renderer (onlyExceptionsubclasses are passed through).Routes: duplicate route names are rejected at construction.@component: returningNoneor a non-Elementvalue raises a clearTypeError(including inrender_to_tree(..., expand_components=True)).streamtree.asyncio: task status dict updates are serialized with a lock; module andsubmitdocstrings document rerun-polling semantics.Theme:primary_coloris restricted to#RGB/#RRGGBBhex;font_stackrejects<,>, and backticks;custom_cssrejects<scriptandexpression(substrings (fullcustom_cssremains trusted CSS).HStack: non-emptygapinserts gutter columns between children (CSSmin-widthon a spacer).
Documentation
- README refresh (badges, absolute GitHub links for design docs and workflows); install examples pin 0.3.0.
- Design docs live at
docs/PLAN.md,docs/ROADMAP.md, anddocs/DEPENDENCY_STRATEGY.mdwith updated cross-links. - StreamTree is used as the product name in metadata and user-facing defaults (the PyPI / import name remains
streamtree).
0.2.0 — 2026-05-12
Added
- Pydantic and typing-extensions as core dependencies; stub optional extras (
tables,charts,ui,auth,asyncio,cli,all) per dependency strategy. streamtree.app_context:provider()/lookup()/current_bag()for rerun-scoped DI-style values.streamtree.routing:sync_route/set_routefor query-param + session alignment.Routeslayout element (with Streamlit renderer) for one-of-many pages keyed by the active route.ErrorBoundaryelement with Streamlit renderer fallback and optionalon_errorcallback.streamtree.forms:str_field_names,model_validate_json,format_validation_errorsfor Pydantic-first forms.- Example
examples/routed_app.py: multi-page navigation + JSON profile validation.
Changed
- Stricter validation for routing params and route names, app-context keys,
Routesdefaults/query keys, andAnnotated[...]handling instr_field_names;current_bag()returns a shallow copy. - Pytest coverage targets
src/streamtreeby path to avoid import-order coverage warnings.
0.1.0 — 2026-05-11
Added
- Initial public API:
@component,render, virtual elements (Page, layouts, widgets). - Session helpers:
state,toggle_state,form_state,session_state,memo,cache. - Streamlit renderer mapping the virtual tree to
st.*calls (includingFormand submit flows). streamtree.testing.render_to_treefor structure-focused tests without a live Streamlit session.- Runnable example:
examples/counter.py. - Design docs under
docs/(plan, roadmap, dependency strategy).