{"id":31320636,"url":"https://github.com/inquilabee/streamtabs","last_synced_at":"2026-05-17T00:36:00.481Z","repository":{"id":315618423,"uuid":"1060212334","full_name":"inquilabee/streamtabs","owner":"inquilabee","description":"Streamlit Tabs Simplified with automatic session management and clear data dependencies.","archived":false,"fork":false,"pushed_at":"2025-09-19T16:07:47.000Z","size":3571,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-09-19T17:49:16.794Z","etag":null,"topics":["python3","streamlit","streamlit-webapp"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/inquilabee.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-19T14:48:03.000Z","updated_at":"2025-09-19T16:12:20.000Z","dependencies_parsed_at":"2025-09-19T17:49:19.337Z","dependency_job_id":"cc0b9eb7-5929-461d-8f3b-5d098120465b","html_url":"https://github.com/inquilabee/streamtabs","commit_stats":null,"previous_names":["inquilabee/streamtabs"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/inquilabee/streamtabs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/inquilabee%2Fstreamtabs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/inquilabee%2Fstreamtabs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/inquilabee%2Fstreamtabs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/inquilabee%2Fstreamtabs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/inquilabee","download_url":"https://codeload.github.com/inquilabee/streamtabs/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/inquilabee%2Fstreamtabs/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":276953985,"owners_count":25734618,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-25T02:00:09.612Z","response_time":80,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["python3","streamlit","streamlit-webapp"],"created_at":"2025-09-25T16:53:11.749Z","updated_at":"2025-09-25T16:53:17.502Z","avatar_url":"https://github.com/inquilabee.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# StreamTabs\n\n**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. StreamTabs handles session management automatically, so you rarely need explicit `st.session_state` calls.\n\n\n## 🎥 Demo\n\n![StreamTabs Demo](https://github.com/inquilabee/streamtabs/raw/main/demo/streamtabs_demo.gif)\n\n*Watch StreamTabs in action - see how easy it is to create interconnected tabs with automatic data flow!*\n\n## Features\n\n- 🏗️ **Modular Architecture**: Organize your Streamlit app into separate tab modules\n- 🔄 **Inter-Tab Data Flow**: Pass data between tabs using `required_inputs` and `required_outputs`\n- 🎯 **Clear Dependencies**: Explicitly declare what data each tab needs and provides\n- 📊 **Sidebar Support**: Create reusable sidebar components\n- 🎯 **Easy Integration**: Simple import and registration system\n- 🔐 **Automatic Session Management**: Implicit session state handling - no need for explicit `st.session_state` calls\n- 🐍 **Python 3.10+**: Modern Python support\n\n## Installation\n\n### From PyPI (Recommended)\n\n```bash\npip install streamtabs\n```\n\n### From Source\n\nThis project uses Poetry for dependency management:\n\n```bash\n# Clone the repository\ngit clone https://github.com/inquilabee/streamtabs.git\ncd streamtabs\n\n# Install dependencies\npoetry install\n\n# Activate the virtual environment\npoetry shell\n```\n\n## Quick Start\n\n### Directory Structure\n\nCreate a directory structure like this:\n\n```\nyour-streamlit-app/\n├── app.py                 # Main Streamlit application\n├── tabs/                  # Your tab modules\n│   ├── __init__.py       # Import all tab classes\n│   ├── data_input.py     # Example tab\n│   └── data_analysis.py  # Example tab\n└── sidebars/             # Your sidebar modules (optional)\n    ├── __init__.py       # Import all sidebar classes\n    └── config.py         # Example sidebar\n```\n\n**Note**: The `apps/` directory in this repository is an example structure you can use as a reference.\n\n### 1. Create Your Tab Classes\n\nCreate tab files in your `tabs/` directory:\n\n```python\n# tabs/my_tab.py\nimport streamlit as st\nfrom streamtabs.core import STTab\n\nclass MyTab(STTab):\n    class Meta:\n        name = \"my_tab\"\n        title = \"My Tab\"\n        icon = \"📊\"\n        order = 1\n        required_inputs = []  # Inputs from other tabs\n        required_outputs = [\"my_data\"]  # Data to pass to other tabs\n\n    def render(self, **kwargs):\n        \"\"\"Render the tab UI and return outputs.\"\"\"\n        st.header(\"My Tab\")\n        # Your tab content here\n        return {\"my_data\": \"some_data\"}\n```\n\n### 2. Create Sidebar Components (Optional)\n\nCreate sidebar files in your `sidebars/` directory:\n\n```python\n# sidebars/my_sidebar.py\nimport streamlit as st\nfrom streamtabs.core import STSidebar\n\nclass MySidebar(STSidebar):\n    class Meta:\n        name = \"my_sidebar\"\n\n    def render(self):\n        \"\"\"Render the sidebar UI.\"\"\"\n        st.header(\"Configuration\")\n        # Your sidebar content here\n        return {\"config\": \"value\"}\n```\n\n### 3. Register Components in Your App\n\n```python\n# app.py\nimport streamlit as st\nfrom sidebars import *  # noqa\nfrom tabs import *  # noqa\nfrom streamtabs.core import STSidebar, STTab\n\nst.set_page_config(page_title=\"My App\", layout=\"wide\")\nst.title(\"My StreamTabs App\")\n\nSTSidebar.run_sidebars()\nSTTab.run_tabs(debug=True)\n```\n\n## Example: Student Performance Evaluation\n\nThis repository includes a complete example demonstrating inter-tab data flow:\n\n### Tab Structure\n\n1. **📝 Exam 1 Input** (`exam1_input.py`)\n   - Enter student names and Exam 1 marks\n   - Outputs: `students_data`\n\n2. **📊 Exam 2 Input** (`exam2_input.py`)\n   - Displays Exam 1 data from previous tab\n   - Add Exam 2 marks for each student\n   - Inputs: `students_data`\n   - Outputs: `updated_students_data`\n\n3. **🏆 Results Summary** (`results_summary.py`)\n   - Shows topper student and statistics\n   - Displays performance charts\n   - Inputs: `updated_students_data`\n\n### Sidebar\n\n- **⚙️ Exam Configuration** (`exam_config.py`)\n  - Configure exam weights\n  - App information and quick stats\n\n### Running the Example\n\nIf you installed from PyPI:\n```bash\n# Clone the example repository or download the example files\ngit clone https://github.com/inquilabee/streamtabs.git\ncd streamtabs\nstreamlit run app.py\n```\n\nIf you installed from source:\n```bash\npoetry run streamlit run app.py\n```\n\n## Tab Meta Configuration\n\nEach tab class requires:\n\n1. **A `Meta` class** with the following attributes:\n   - `name`: Unique identifier for the tab\n   - `title`: Display name in the tab header\n   - `icon`: Emoji or icon for the tab\n   - `order`: Display order (lower numbers appear first)\n   - `required_inputs`: List of input keys from other tabs\n   - `required_outputs`: List of output keys this tab provides\n\n2. **A `render` method** that implements the tab's functionality:\n\n```python\ndef render(self, **kwargs):\n    \"\"\"Implement your tab's UI and logic here.\"\"\"\n    # Your tab content here\n    return {\"output_key\": \"output_value\"}  # Optional: return data for other tabs\n```\n\n### Tab Documentation\n\nEach tab automatically displays documentation from the `render` method's docstring. This appears at the top of the tab when rendered:\n\n```python\ndef render(self, **kwargs):\n    \"\"\"This docstring will be displayed as tab documentation.\"\"\"\n    # Your tab content here\n```\n\n### Accessing Input Data\n\nInput data from other tabs can be accessed in two ways:\n\n1. **Direct Parameters**: Declare inputs as method parameters\n2. **Via kwargs**: Access through the `kwargs` dictionary\n\n```python\ndef render(self, my_data, **kwargs):\n    \"\"\"Access input data directly as parameters.\"\"\"\n    st.write(f\"Direct access: {my_data}\")\n    \n    # Or access via kwargs\n    other_data = kwargs.get(\"other_data\")\n    st.write(f\"Via kwargs: {other_data}\")\n```\n\n## Data Flow \u0026 Dependencies\n\nStreamTabs uses explicit dependency declaration to ensure clear data flow between tabs. This approach provides several benefits:\n\n### Benefits of Explicit Dependencies\n\n- **🔍 Clear Data Contracts**: Know exactly what data each tab expects and provides\n- **🚫 Error Prevention**: Automatic validation of data dependencies\n- **📖 Self-Documenting**: Code clearly shows the relationship between tabs\n- **🔧 Easy Debugging**: Missing dependencies are caught early with clear error messages\n- **🔐 Automatic Session Management**: Data persistence between tab switches without manual `st.session_state` handling\n\n### How It Works\n\nTabs declare their dependencies using `required_inputs` and `required_outputs`:\n\n```python\n# Tab A: Data Producer\nclass DataProducerTab(STTab):\n    class Meta:\n        name = \"producer\"\n        title = \"Data Producer\"\n        required_inputs = []           # No dependencies\n        required_outputs = [\"raw_data\", \"metadata\"]  # Provides two outputs\n\n    def render(self, **kwargs):\n        \"\"\"Generate and return data.\"\"\"\n        raw_data = [1, 2, 3, 4, 5]\n        metadata = {\"count\": len(raw_data), \"type\": \"numbers\"}\n        \n        return {\n            \"raw_data\": raw_data,      # Available to other tabs\n            \"metadata\": metadata       # Available to other tabs\n        }\n\n# Tab B: Data Consumer\nclass DataConsumerTab(STTab):\n    class Meta:\n        name = \"consumer\"\n        title = \"Data Consumer\"\n        required_inputs = [\"raw_data\"]     # Depends on raw_data from producer\n        required_outputs = [\"processed\"]   # Provides processed data\n\n    def render(self, raw_data, **kwargs):\n        \"\"\"Process data from producer tab.\"\"\"\n        # raw_data is automatically injected from DataProducerTab\n        processed = [x * 2 for x in raw_data]\n        \n        return {\"processed\": processed}\n\n# Tab C: Final Consumer\nclass FinalTab(STTab):\n    class Meta:\n        name = \"final\"\n        title = \"Final Results\"\n        required_inputs = [\"raw_data\", \"processed\"]  # Depends on both\n        required_outputs = []                        # No outputs\n\n    def render(self, raw_data, processed, **kwargs):\n        \"\"\"Display results from both previous tabs.\"\"\"\n        st.write(\"Original data:\", raw_data)\n        st.write(\"Processed data:\", processed)\n        # No return needed - this is a final display tab\n```\n\n### Dependency Resolution\n\nStreamTabs automatically resolves dependencies by:\n\n1. **📋 Analyzing Requirements**: Scans all tabs for their `required_inputs` and `required_outputs`\n2. **🔗 Building Dependency Graph**: Creates a directed graph of data dependencies\n3. **⚡ Executing in Order**: Runs tabs in the correct order to satisfy dependencies\n4. **✅ Validating Data**: Ensures all required inputs are available before running a tab\n\n### Error Handling\n\nIf dependencies can't be satisfied, StreamTabs provides clear error messages:\n\n```python\n# This will fail with a clear error message\nclass BrokenTab(STTab):\n    class Meta:\n        required_inputs = [\"nonexistent_data\"]  # This data doesn't exist!\n    \n    def render(self, nonexistent_data, **kwargs):\n        # This will never be called due to missing dependency\n        pass\n```\n\n### Best Practices\n\n1. **🎯 Be Specific**: Only declare inputs you actually use\n2. **📝 Document Outputs**: Use descriptive names for your outputs\n3. **🔄 Keep It Simple**: Avoid circular dependencies\n4. **🧪 Test Dependencies**: Verify your data flow works as expected\n\n## Requirements\n\n- Python 3.10+\n- Streamlit \u003e= 1.49.1\n\n## License\n\nMIT License - see LICENSE file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finquilabee%2Fstreamtabs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Finquilabee%2Fstreamtabs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finquilabee%2Fstreamtabs/lists"}