Skip to main content
Pre-release

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 ViewContext binding 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 for st.Page composition.

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 reads config.toml once 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_css is injected via st.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_dispatch and bind_trigger methods 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

tiferet_streamlit-1.0.0a8.tar.gz (36.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

tiferet_streamlit-1.0.0a8-py3-none-any.whl (45.6 kB view details)

Uploaded Python 3

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

Hashes for tiferet_streamlit-1.0.0a8.tar.gz
Algorithm Hash digest
SHA256 2292ecebceb229e00125527346da7fdf70452f2234e17bfdd97e4b041cb07dc1
MD5 7335c0c2925d8e339070d4a7f5d37600
BLAKE2b-256 6c43f6a69f10871fd3d3dbb9eaf6af177071b5e62ceb95b2e791c0384cfcfbf6

See more details on using hashes here.

Provenance

The following attestation bundles were made for tiferet_streamlit-1.0.0a8.tar.gz:

Publisher: python-publish.yml on greatstrength/tiferet-streamlit

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file tiferet_streamlit-1.0.0a8-py3-none-any.whl.

File metadata

File hashes

Hashes for tiferet_streamlit-1.0.0a8-py3-none-any.whl
Algorithm Hash digest
SHA256 659ee0a54dda4380ac034ceec4226bcd0c428c5002ed0c877b7b22843d997764
MD5 9fe37bd552885defd4a1f8d11da004d9
BLAKE2b-256 e9ba2a939e00701a4241416a345f0330d0f0f4355f49c65c784fe0720bc39686

See more details on using hashes here.

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

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

1.0.0a8 This release

2 files

0.2.0

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page