This release is a pre-release and may not be stable for production use.
tiferet-streamlit
A Streamlit extension for the Tiferet Framework — build multi-page Streamlit applications with Domain-Driven Design.
Installation
pip install tiferet-streamlit
Requires tiferet>=2.0.3 and streamlit>=1.30.0. build_streamlit_app() constructs the app via tiferet.blueprints.app.build_app(...), yielding an AppSessionContext, and performs a runtime check on that constructed object, raising INCOMPATIBLE_APP_CONTEXT if it does not expose a run(feature_id, headers, data)-shaped callable — guarding against any future incompatible tiferet release.
Quick Start
import streamlit as st
from tiferet_streamlit import StreamlitApp, ViewContext
class HomeView(ViewContext):
def init_state(self):
self.session.set('count', 0)
def render(self):
count = self.session.get('count')
st.title('Home')
st.write(f'Count: {count}')
if st.button('Increment'):
self.session.set('count', count + 1)
st.rerun()
StreamlitApp('my_interface', pages={'/': HomeView})
The counter above wires its widget by hand. See docs/guides/widgets.md for
ViewContextbinding methods that sync a widget's value and dispatch for you.
Core Concepts
ViewContext
The code-behind for a Streamlit page. Manages state via SessionCacheContext, dispatches Tiferet features via AppSessionContext, and defines UI through render().
init_state()— Called once on first construction. Override to set initial state.dispatch(feature_id, headers=None, **data)— Execute a Tiferet feature.bind_widget,bind_widget_dispatch,bind_trigger— Bind a native Streamlit widget's value and dispatch on change; see docs/guides/widgets.md.render()— Override to define Streamlit widgets.__call__()— Makes the view callable forst.Pagecomposition.
ViewComponent
A lightweight, prop-driven sub-component with parent ViewContext access.
from tiferet_streamlit import ViewComponent
class Counter(ViewComponent):
def render(self, label='Count', start=0):
count = self.ctx.session.get('count') or start
st.write(f'{label}: {count}')
SessionCacheContext
Cache backed by st.session_state with namespace isolation for multi-page apps.
from tiferet_streamlit import SessionCacheContext
cache = SessionCacheContext(namespace='my_view')
cache.set('key', 'value')
cache.get('key') # 'value'
Multi-Page Applications
Use StreamlitApp (or build_streamlit_app) to register multiple views with routes:
StreamlitApp('my_interface', pages={
'/': HomeView,
'/about': AboutView,
'/settings': SettingsView,
})
Config-Driven Pages
Define pages as Page domain objects for YAML-driven configuration:
from tiferet_streamlit import Page, StreamlitApp
pages = [
Page(route='/', title='Home', icon='🏠',
view_module_path='app.views.home', view_class_name='HomeView'),
Page(route='/about', title='About', icon='ℹ️',
view_module_path='app.views.about', view_class_name='AboutView'),
]
StreamlitApp('my_interface', page_configs=pages)
ViewService-Backed Page Configuration
Source pages from a ViewService implementation (e.g. a YAML-backed repository registered in your app's DI configuration) instead of constructing Page objects in Python. build_streamlit_app/StreamlitApp never import ViewService directly — pass a get_page_configs handler that resolves one through get_view_service, the sole DI-mediated accessor:
from tiferet_streamlit import StreamlitApp, get_view_service
StreamlitApp(
'my_interface',
get_page_configs=lambda app: get_view_service(app).list_pages(),
)
get_view_service(app, service_id='view_service', flags=None) resolves the dependency through the app's DI context and verifies it implements ViewService, raising a structured INVALID_VIEW_SERVICE_ID error otherwise.
Config-Driven Theming
Declare a Theme as data and pass it to StreamlitApp to reach Streamlit's own native appearance controls, instead of hand-patching individual pages with one-off style tweaks:
from tiferet_streamlit import Theme, StreamlitApp
theme = Theme(
primary_color='#FF4B4B',
background_color='#FFFFFF',
text_color='#262730',
custom_css='.stButton button { border-radius: 8px; }',
)
StreamlitApp('my_interface', pages={'/': HomeView}, theme=theme)
A declared Theme reaches two separate, independent paths:
- Native
[theme]fields (base,primary_color,background_color,secondary_background_color,text_color,font) are merged into.streamlit/config.toml's[theme]section on disk, preserving any unrelated settings already in that file. Streamlit readsconfig.tomlonce at server startup, so this write takes effect on the next Streamlit process start — it does not re-theme the app that is currently running. custom_cssis injected viast.markdown(..., unsafe_allow_html=True)on every app run, so it takes effect immediately, including on the current rerun.
Omitting theme entirely leaves existing behavior unchanged: no config.toml write and no CSS injection.
Feature Dispatch
Views dispatch Tiferet features for backend logic:
class CalcView(ViewContext):
def render(self):
a = st.number_input('a')
b = st.number_input('b')
if st.button('Add'):
result = self.dispatch('calc.add', a=a, b=b)
st.write(f'Result: {result}')
This example dispatches on every rerun rather than only on a real change. See docs/guides/widgets.md for the
bind_widget_dispatchandbind_triggermethods that fix both hand-wired patterns above.
API Reference
| Export | Module | Description |
|---|---|---|
build_streamlit_app |
blueprints.streamlit |
Primary entry point blueprint function |
StreamlitApp |
blueprints |
Alias for build_streamlit_app |
Page |
domain.view |
Page configuration domain object |
Theme |
domain.theme |
App appearance declared as data |
ViewService |
interfaces.view |
Abstract service for page management |
get_view_service |
contexts.di |
DI-mediated, verified accessor for a ViewService dependency |
SessionCacheContext |
contexts.session |
Session-state-backed cache with namespacing |
ViewContext |
contexts.view |
Page code-behind with lifecycle management and widget binding (guide) |
ViewComponent |
contexts.view |
Prop-driven sub-component with delegated widget binding |
PageContext |
contexts.page |
Multi-page navigation manager |
Development
# Clone and set up
git clone https://github.com/greatstrength/tiferet-streamlit.git
cd tiferet-streamlit
python -m venv .venv
source .venv/bin/activate
pip install -e .[test]
# Run tests
pytest --verbose
License
MIT
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 tiferet_streamlit-1.0.0a8.tar.gz.
File metadata
- Download URL: tiferet_streamlit-1.0.0a8.tar.gz
- Upload date:
- Size: 36.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2292ecebceb229e00125527346da7fdf70452f2234e17bfdd97e4b041cb07dc1
|
|
| MD5 |
7335c0c2925d8e339070d4a7f5d37600
|
|
| BLAKE2b-256 |
6c43f6a69f10871fd3d3dbb9eaf6af177071b5e62ceb95b2e791c0384cfcfbf6
|
Provenance
The following attestation bundles were made for tiferet_streamlit-1.0.0a8.tar.gz:
Publisher:
python-publish.yml on greatstrength/tiferet-streamlit
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tiferet_streamlit-1.0.0a8.tar.gz -
Subject digest:
2292ecebceb229e00125527346da7fdf70452f2234e17bfdd97e4b041cb07dc1 - Sigstore transparency entry: 2712202411
- Sigstore integration time:
-
Permalink:
greatstrength/tiferet-streamlit@a65fcc1c5a7e699cd5cc3070b6f68f233b99bf3a -
Branch / Tag:
refs/tags/v1.0.0a8 - Owner: https://github.com/greatstrength
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@a65fcc1c5a7e699cd5cc3070b6f68f233b99bf3a -
Trigger Event:
push
-
Statement type:
File details
Details for the file tiferet_streamlit-1.0.0a8-py3-none-any.whl.
File metadata
- Download URL: tiferet_streamlit-1.0.0a8-py3-none-any.whl
- Upload date:
- Size: 45.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
659ee0a54dda4380ac034ceec4226bcd0c428c5002ed0c877b7b22843d997764
|
|
| MD5 |
9fe37bd552885defd4a1f8d11da004d9
|
|
| BLAKE2b-256 |
e9ba2a939e00701a4241416a345f0330d0f0f4355f49c65c784fe0720bc39686
|
Provenance
The following attestation bundles were made for tiferet_streamlit-1.0.0a8-py3-none-any.whl:
Publisher:
python-publish.yml on greatstrength/tiferet-streamlit
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tiferet_streamlit-1.0.0a8-py3-none-any.whl -
Subject digest:
659ee0a54dda4380ac034ceec4226bcd0c428c5002ed0c877b7b22843d997764 - Sigstore transparency entry: 2712203345
- Sigstore integration time:
-
Permalink:
greatstrength/tiferet-streamlit@a65fcc1c5a7e699cd5cc3070b6f68f233b99bf3a -
Branch / Tag:
refs/tags/v1.0.0a8 - Owner: https://github.com/greatstrength
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@a65fcc1c5a7e699cd5cc3070b6f68f233b99bf3a -
Trigger Event:
push
-
Statement type: