This project demonstrates how to leverage the built-in power of Streamlit using best software engineering practices and tools. It provides a non-trivial Streamlit application skeleton, showcasing how to effectively utilize Streamlit's capabilities and address its limitations.
- 🏗️ Modular, layered architecture for better maintainability
- 🧩 Separation of concerns for improved testability
- ⚙️ Modern build tools to complete full CI builds in under 30 seconds
- 🧹 Automated formatter and linter
- 📊 Test coverage
- 🐞 Test execution and debugging available directly from VS Code
- 📦 Minimal number of external dependencies
- 🐳 Optimized Docker image for deploying application
- 🌐 Web routing using built-in multi-page navigation capabilities
- 🔄 Sample reusable, stateful components
- ✅ All pages and components tested with
AppTest
- 📊 Vega-Altair example visualization
- 🗂️ BigQuery integration using the New York Taxi public dataset
- 🔒 Authentication skeleton, easily replaceable with OAuth
- 🔗 Application state sharing via URL
- 💾 Dataframe export buttons to CSV and XLS
- 🧪 Implement BigQuery integration tests
- 📈 Add more visualizations for integrated public dataset
- 🔐 Integration with external OAuth provider, see roadmap
- 📝 Add request logging
- 🔄 Redirect to the original page after login
- ⚖️ Describe load balancer strategies, for example: sticky session
- 🔄 Automatically update dependencies, see dependabot#10039
- 📝 Add more sophisticated type checking, see mypy
- Application pages, no application logic
- Tested with Streamlit testing framework and mocked service layer
- Delegate shared UI components to
example.ui.components
- Delegate application logic to
example.service
- Use
_page
filename suffix to differentiate from services or repositories
- Shared UI components
- Tested with Streamlit testing framework with small helper function wrappers
- Encapsulates Streamlit state management
- Service layer for application logic
- Tested with Pytest and mocked repositories layer
- Shouldn't import Streamlit API
- Use
_service
filename suffix to differentiate from pages or repositories
- Repository layer for data persistence
- Tested in realistic environment (Cloud, Test Containers, etc.)
- Shouldn't import Streamlit API besides
@st.cache
- Keep it simple, delegate logic to
example.service
if possible, for example aggregate small datasets in memory - Use
_repository
filename suffix to differentiate from services or pages
- Infrastructure code
- Tested in realistic environment (Cloud, Test Containers, etc.)
- Shouldn't import Streamlit API
- Keep it simple, should not have any application specific logic
- Acts as anti-corruption layer, for example - expose Pandas DataFrame instead of underlying database API
- Utility functions
- Tested within Pytest without mocks
- Shouldn't import Streamlit API
Note
You need Google Cloud Platform account to access sample dataset!
Use VS Code with the following extensions:
- Python
- Ruff
Update environment:
uv sync
Execute the following commands to run the application locally:
streamlit run app.py
Linting:
ruff check
Check formatting:
ruff format --check
Execute tests with coverage:
pytest
Show outdated dependencies:
uv pip list --outdated