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.0b1.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.0b1-py3-none-any.whl (45.6 kB view details)

Uploaded Python 3

File details

Details for the file tiferet_streamlit-1.0.0b1.tar.gz.

File metadata

  • Download URL: tiferet_streamlit-1.0.0b1.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.0b1.tar.gz
Algorithm Hash digest
SHA256 84a988984bd27ec8b1bc0c8c8715c84902cbe2f15de325257d3b5c630346aa79
MD5 c63cf778468ff138c04da9759046b40f
BLAKE2b-256 ecccba3844c06a84a3cbbcd93387bf10b864958ccc2cd1219cd5d1ddfabef57a

See more details on using hashes here.

Provenance

The following attestation bundles were made for tiferet_streamlit-1.0.0b1.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.0b1-py3-none-any.whl.

File metadata

File hashes

Hashes for tiferet_streamlit-1.0.0b1-py3-none-any.whl
Algorithm Hash digest
SHA256 c258200006f8de51818736c9df652c5703aea1042e7c376a762ab68a7ffe0be2
MD5 579b9e5f4d36c1d486f0d1d478460cfc
BLAKE2b-256 1bc8165c0716ee99b975311953adb972a31450a90e61889c5ec6a197c2595edc

See more details on using hashes here.

Provenance

The following attestation bundles were made for tiferet_streamlit-1.0.0b1-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.0b1 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