Streamlit Apps on Tabs
Project description
StreamTabs
StreamTabs is a Python package that provides a modular tab system for Streamlit applications. It allows you to organize your Streamlit apps into reusable, interconnected tabs with automatic data flow between them.
Features
- ๐๏ธ Modular Architecture: Organize your Streamlit app into separate tab modules
- ๐ Inter-Tab Data Flow: Pass data between tabs using
required_inputsandrequired_outputs - ๐ฏ Clear Dependencies: Explicitly declare what data each tab needs and provides
- ๐ Sidebar Support: Create reusable sidebar components
- ๐ฏ Easy Integration: Simple import and registration system
- ๐ Python 3.10+: Modern Python support
Installation
This project uses Poetry for dependency management:
# Install dependencies
poetry install
# Activate the virtual environment
poetry shell
Quick Start
1. Create Your Tab Classes
Create tab files in apps/tabs/:
# apps/tabs/my_tab.py
import streamlit as st
from streamtabs.core import STTab
class MyTab(STTab):
class Meta:
name = "my_tab"
title = "My Tab"
icon = "๐"
order = 1
required_inputs = [] # Inputs from other tabs
required_outputs = ["my_data"] # Data to pass to other tabs
def render(self, **kwargs):
"""Render the tab UI and return outputs."""
st.header("My Tab")
# Your tab content here
return {"my_data": "some_data"}
2. Create Sidebar Components (Optional)
Create sidebar files in apps/sidebars/:
# apps/sidebars/my_sidebar.py
import streamlit as st
from streamtabs.core import STSidebar
class MySidebar(STSidebar):
class Meta:
name = "my_sidebar"
def render(self):
"""Render the sidebar UI."""
st.header("Configuration")
# Your sidebar content here
return {"config": "value"}
3. Register Components in Your App
# app.py
import streamlit as st
from apps.sidebars import * # noqa
from apps.tabs import * # noqa
from streamtabs.core import STSidebar, STTab
st.set_page_config(page_title="My App", layout="wide")
st.title("My StreamTabs App")
STSidebar.run_sidebars()
STTab.run_tabs(debug=True)
Example: Student Performance Evaluation
This repository includes a complete example demonstrating inter-tab data flow:
Tab Structure
-
๐ Exam 1 Input (
exam1_input.py)- Enter student names and Exam 1 marks
- Outputs:
students_data
-
๐ Exam 2 Input (
exam2_input.py)- Displays Exam 1 data from previous tab
- Add Exam 2 marks for each student
- Inputs:
students_data - Outputs:
updated_students_data
-
๐ Results Summary (
results_summary.py)- Shows topper student and statistics
- Displays performance charts
- Inputs:
updated_students_data
Sidebar
- โ๏ธ Exam Configuration (
exam_config.py)- Configure exam weights
- App information and quick stats
Running the Example
poetry run streamlit run app.py
Tab Meta Configuration
Each tab class requires a Meta class with the following attributes:
name: Unique identifier for the tabtitle: Display name in the tab headericon: Emoji or icon for the taborder: Display order (lower numbers appear first)required_inputs: List of input keys from other tabsrequired_outputs: List of output keys this tab provides
Data Flow & Dependencies
StreamTabs uses explicit dependency declaration to ensure clear data flow between tabs. This approach provides several benefits:
Benefits of Explicit Dependencies
- ๐ Clear Data Contracts: Know exactly what data each tab expects and provides
- ๐ซ Error Prevention: Automatic validation of data dependencies
- ๐ Self-Documenting: Code clearly shows the relationship between tabs
- ๐ง Easy Debugging: Missing dependencies are caught early with clear error messages
How It Works
Tabs declare their dependencies using required_inputs and required_outputs:
# Tab A: Data Producer
class DataProducerTab(STTab):
class Meta:
name = "producer"
title = "Data Producer"
required_inputs = [] # No dependencies
required_outputs = ["raw_data", "metadata"] # Provides two outputs
def render(self, **kwargs):
"""Generate and return data."""
raw_data = [1, 2, 3, 4, 5]
metadata = {"count": len(raw_data), "type": "numbers"}
return {
"raw_data": raw_data, # Available to other tabs
"metadata": metadata # Available to other tabs
}
# Tab B: Data Consumer
class DataConsumerTab(STTab):
class Meta:
name = "consumer"
title = "Data Consumer"
required_inputs = ["raw_data"] # Depends on raw_data from producer
required_outputs = ["processed"] # Provides processed data
def render(self, raw_data, **kwargs):
"""Process data from producer tab."""
# raw_data is automatically injected from DataProducerTab
processed = [x * 2 for x in raw_data]
return {"processed": processed}
# Tab C: Final Consumer
class FinalTab(STTab):
class Meta:
name = "final"
title = "Final Results"
required_inputs = ["raw_data", "processed"] # Depends on both
required_outputs = [] # No outputs
def render(self, raw_data, processed, **kwargs):
"""Display results from both previous tabs."""
st.write("Original data:", raw_data)
st.write("Processed data:", processed)
# No return needed - this is a final display tab
Dependency Resolution
StreamTabs automatically resolves dependencies by:
- ๐ Analyzing Requirements: Scans all tabs for their
required_inputsandrequired_outputs - ๐ Building Dependency Graph: Creates a directed graph of data dependencies
- โก Executing in Order: Runs tabs in the correct order to satisfy dependencies
- โ Validating Data: Ensures all required inputs are available before running a tab
Error Handling
If dependencies can't be satisfied, StreamTabs provides clear error messages:
# This will fail with a clear error message
class BrokenTab(STTab):
class Meta:
required_inputs = ["nonexistent_data"] # This data doesn't exist!
def render(self, nonexistent_data, **kwargs):
# This will never be called due to missing dependency
pass
Best Practices
- ๐ฏ Be Specific: Only declare inputs you actually use
- ๐ Document Outputs: Use descriptive names for your outputs
- ๐ Keep It Simple: Avoid circular dependencies
- ๐งช Test Dependencies: Verify your data flow works as expected
Development
Project Structure
streamtabs/
โโโ streamtabs/ # Core package
โ โโโ core/
โ โโโ core.py # STTab and STSidebar classes
โโโ apps/ # Example applications
โ โโโ tabs/ # Tab modules
โ โโโ sidebars/ # Sidebar modules
โโโ app.py # Main Streamlit app
โโโ pyproject.toml # Poetry configuration
โโโ README.md
Adding New Tabs
- Create a new file in
apps/tabs/ - Define your tab class inheriting from
STTab - Import the tab in
apps/tabs/__init__.py - The tab will be automatically registered when you run the app
Adding New Sidebars
- Create a new file in
apps/sidebars/ - Define your sidebar class inheriting from
STSidebar - Import the sidebar in
apps/sidebars/__init__.py - The sidebar will be automatically registered when you run the app
Requirements
- Python 3.10+
- Streamlit >= 1.49.1
- Poetry (for dependency management)
License
MIT License - see LICENSE file for details.
Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
Support
For questions or issues, please open an issue on the GitHub repository.
Project details
Release history Release notifications | RSS feed
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 streamtabs-0.1.0.tar.gz.
File metadata
- Download URL: streamtabs-0.1.0.tar.gz
- Upload date:
- Size: 5.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.1.3 CPython/3.10.12 Linux/6.6.87.2-microsoft-standard-WSL2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
356be5f48b214685b2c580c3eaab43867890c79b68314405351afeb19d510756
|
|
| MD5 |
7d0f827b2cf3205d78d3429c028e1ef4
|
|
| BLAKE2b-256 |
763199d7da484b1644c27714c1582a71c6949ce44c32647ed96432437b2101de
|
File details
Details for the file streamtabs-0.1.0-py3-none-any.whl.
File metadata
- Download URL: streamtabs-0.1.0-py3-none-any.whl
- Upload date:
- Size: 6.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.1.3 CPython/3.10.12 Linux/6.6.87.2-microsoft-standard-WSL2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2f42bc3cd6f298895a8d0fda0d06a10caf344e2384ea1277a3a02e71e0289da5
|
|
| MD5 |
3872346544c129a05b77b2cc513d4a01
|
|
| BLAKE2b-256 |
e938ac2a0b1adad10c7e96ada9ba211e687946e38bdccb38f0d74f96e2e83b78
|