Stack Streamlit — InfoWhere
Template de stack para projetos Streamlit
Última atualização: 25/01/2026
Uso: Dashboards, PoCs, demos rápidos
1. Visão Geral
Stack para criar dashboards interativos, provas de conceito e demos rápidos com Python.
2. Versões
| Componente | Versão | Notas |
|---|---|---|
| Python | 3.12.x | Última estável |
| Streamlit | 1.41.x | Última estável |
| UV | Última | Gerenciador de pacotes |
3. Dependências Core
3.1 Framework Base
# pyproject.toml
[project]
dependencies = [
"streamlit>=1.41.0",
]
3.2 Data & Visualização
data = [
"pandas>=2.2.0",
"numpy>=2.1.0",
"plotly>=5.24.0",
"altair>=5.5.0",
]
3.3 Database
db = [
"sqlalchemy>=2.0.0",
"psycopg2-binary>=2.9.0", # PostgreSQL
"pymongo>=4.10.0", # MongoDB
]
3.4 IA / LLM
ai = [
"openai>=1.57.0",
"anthropic>=0.40.0",
"langchain>=0.3.0",
]
3.5 Autenticação
auth = [
"streamlit-authenticator>=0.4.0",
"python-keycloak>=4.6.0",
]
3.6 Utilitários
utils = [
"python-dotenv>=1.0.0",
"httpx>=0.28.0",
"pydantic>=2.9.0",
]
4. Estrutura do Projeto
4.1 Projeto Simples (Single Page)
{projeto}/
├── app.py # Main Streamlit app
├── requirements.txt # ou pyproject.toml
├── .env
├── .streamlit/
│ └── config.toml # Streamlit config
└── README.md
4.2 Projeto Multi-Page
{projeto}/
├── Home.py # Main page (Home)
├── pages/
│ ├── 1_📊_Dashboard.py
│ ├── 2_📈_Analytics.py
│ ├── 3_⚙️_Settings.py
│ └── ...
├── components/ # Reusable components
│ ├── __init__.py
│ ├── charts.py
│ ├── filters.py
│ └── sidebar.py
├── services/ # Business logic
│ ├── __init__.py
│ ├── data_service.py
│ └── auth_service.py
├── utils/
│ ├── __init__.py
│ └── helpers.py
├── config/
│ ├── __init__.py
│ └── settings.py
├── .streamlit/
│ ├── config.toml
│ └── secrets.toml # Secrets (não commitar!)
├── pyproject.toml
├── Dockerfile
└── README.md
5. Configuração
5.1 Streamlit Config
# .streamlit/config.toml
[theme]
primaryColor = "#10b981"
backgroundColor = "#0f172a"
secondaryBackgroundColor = "#1e293b"
textColor = "#f1f5f9"
font = "sans serif"
[server]
port = 8501
enableCORS = false
enableXsrfProtection = true
[browser]
gatherUsageStats = false
5.2 Secrets
# .streamlit/secrets.toml (NÃO COMMITAR!)
[database]
host = "localhost"
port = 5432
database = "mydb"
user = "user"
password = "password"
[api]
openai_key = "sk-..."
anthropic_key = "sk-ant-..."
[keycloak]
url = "https://keycloak.example.com"
realm = "myrealm"
client_id = "myclient"
5.3 Settings com Pydantic
# config/settings.py
from pydantic_settings import BaseSettings
from functools import lru_cache
class Settings(BaseSettings):
# Database
db_host: str = "localhost"
db_port: int = 5432
db_name: str = "mydb"
db_user: str = "user"
db_password: str = ""
# API Keys
openai_api_key: str = ""
anthropic_api_key: str = ""
class Config:
env_file = ".env"
@lru_cache()
def get_settings() -> Settings:
return Settings()
6. Padrões e Convenções
6.1 Page Structure
# pages/1_📊_Dashboard.py
import streamlit as st
from components.sidebar import render_sidebar
from components.charts import render_chart
from services.data_service import DataService
# Page config (deve ser primeira chamada Streamlit)
st.set_page_config(
page_title="Dashboard",
page_icon="📊",
layout="wide",
)
# Initialize services
@st.cache_resource
def get_data_service():
return DataService()
data_service = get_data_service()
# Sidebar
with st.sidebar:
render_sidebar()
filters = st.session_state.get("filters", {})
# Main content
st.title("📊 Dashboard")
# Layout com colunas
col1, col2 = st.columns(2)
with col1:
st.subheader("Metric 1")
data = data_service.get_metric_1(filters)
st.metric("Total", data["total"], delta=data["delta"])
with col2:
st.subheader("Metric 2")
render_chart(data_service.get_chart_data(filters))
6.2 Reusable Components
# components/charts.py
import streamlit as st
import plotly.express as px
import pandas as pd
def render_line_chart(
data: pd.DataFrame,
x: str,
y: str,
title: str = "",
color: str | None = None,
) -> None:
"""Render a line chart with consistent styling."""
fig = px.line(
data,
x=x,
y=y,
color=color,
title=title,
)
fig.update_layout(
template="plotly_dark",
paper_bgcolor="rgba(0,0,0,0)",
plot_bgcolor="rgba(0,0,0,0)",
)
st.plotly_chart(fig, use_container_width=True)
def render_metric_card(
title: str,
value: str | int | float,
delta: str | int | float | None = None,
help_text: str | None = None,
) -> None:
"""Render a metric card."""
st.metric(
label=title,
value=value,
delta=delta,
help=help_text,
)
6.3 Session State
# utils/state.py
import streamlit as st
from typing import Any
def init_session_state(defaults: dict[str, Any]) -> None:
"""Initialize session state with defaults."""
for key, value in defaults.items():
if key not in st.session_state:
st.session_state[key] = value
def get_state(key: str, default: Any = None) -> Any:
"""Get value from session state."""
return st.session_state.get(key, default)
def set_state(key: str, value: Any) -> None:
"""Set value in session state."""
st.session_state[key] = value
6.4 Caching
# services/data_service.py
import streamlit as st
import pandas as pd
class DataService:
@st.cache_data(ttl=3600) # Cache por 1 hora
def get_data(_self, query: str) -> pd.DataFrame:
"""Fetch data with caching."""
# ... fetch from database
return df
@st.cache_resource # Cache permanente (conexões)
def get_connection(_self):
"""Get database connection."""
# ... create connection
return conn
7. Autenticação
7.1 Streamlit Authenticator (Simples)
# auth/authenticator.py
import streamlit as st
import streamlit_authenticator as stauth
import yaml
from yaml.loader import SafeLoader
def init_auth():
with open("config/auth.yaml") as file:
config = yaml.load(file, Loader=SafeLoader)
authenticator = stauth.Authenticate(
config["credentials"],
config["cookie"]["name"],
config["cookie"]["key"],
config["cookie"]["expiry_days"],
)
return authenticator
def require_auth():
authenticator = init_auth()
name, authenticated, username = authenticator.login()
if not authenticated:
st.stop()
return name, username
7.2 Keycloak (Enterprise)
# auth/keycloak.py
import streamlit as st
from keycloak import KeycloakOpenID
def init_keycloak():
return KeycloakOpenID(
server_url=st.secrets["keycloak"]["url"],
client_id=st.secrets["keycloak"]["client_id"],
realm_name=st.secrets["keycloak"]["realm"],
)
def require_keycloak_auth():
if "token" not in st.session_state:
st.warning("Please login")
# Redirect to Keycloak login
st.stop()
keycloak = init_keycloak()
try:
userinfo = keycloak.userinfo(st.session_state["token"])
return userinfo
except:
del st.session_state["token"]
st.rerun()
8. Infraestrutura
| Componente | Escolha |
|---|---|
| Deploy | Streamlit Cloud / Docker |
| CI/CD | GitHub Actions |
Dockerfile típico
FROM python:3.12-slim
WORKDIR /app
# Instalar UV
RUN pip install uv
# Copiar dependências
COPY pyproject.toml .
RUN uv pip install --system -e ".[all]"
# Copiar código
COPY . .
EXPOSE 8501
HEALTHCHECK CMD curl --fail http://localhost:8501/_stcore/health
ENTRYPOINT ["streamlit", "run", "Home.py", "--server.port=8501", "--server.address=0.0.0.0"]
docker-compose.yml
version: "3.8"
services:
streamlit:
build: .
ports:
- "8501:8501"
environment:
- DB_HOST=db
- DB_PORT=5432
volumes:
- ./.streamlit:/app/.streamlit:ro
depends_on:
- db
db:
image: postgres:16-alpine
environment:
POSTGRES_DB: mydb
POSTGRES_USER: user
POSTGRES_PASSWORD: password
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:
9. O que NÃO usar
| Tecnologia | Motivo |
|---|---|
| Flask/FastAPI junto | Streamlit é self-contained |
| Matplotlib extensivo | Preferir Plotly (interativo) |
| Sessões complexas | Streamlit reruns on every action |
| Secrets em código | Usar .streamlit/secrets.toml |
10. Checklist de Novo Projeto
- Criar projeto com
uv init - Instalar Streamlit e dependências
- Criar
.streamlit/config.toml - Criar
.streamlit/secrets.toml(gitignore!) - Criar estrutura de pastas (se multi-page)
- Configurar tema
- Criar componentes reutilizáveis
- Configurar caching adequado
- Criar Dockerfile
- Criar README.md com instruções
11. Links de Referência
Nota: Este template é a base. Cada projeto pode ter ajustes específicos documentados no
technical_context.mddo projeto.