Se você trabalha com dados, provavelmente já viveu este pesadelo: a diretoria pede um novo dashboard de análise financeira. Você abre a sua ferramenta de BI tradicional (Power BI, Tableau, Looker), conecta no banco de dados, e de repente... a interface congela. O custo de licenciamento sobe a cada novo usuário, e você fica engessado nas limitações visuais da plataforma.
E se nós pudéssemos quebrar essa barreira? E se pudéssemos processar milhões de linhas em milissegundos, criar interfaces 100% customizáveis e rodar tudo sem pagar um centavo de licença por usuário?
Bem-vindo à Modern Data Stack 2.0. Hoje, vamos construir nosso próprio motor de Business Intelligence usando Python.
🏗️ A Arquitetura do Nosso BI Customizado
Para abandonar as ferramentas tradicionais, precisamos de uma arquitetura que suporte extração, processamento analítico (OLAP) e visualização reativa. Nossa stack de elite será:
-
Ambiente:
uv(para gestão de pacotes ultrarrápida) e OrbStack (se precisarmos subir serviços via Docker). -
Ingestão e Transformação:
Polars(adeus, Pandas e MemoryError!). -
Motor OLAP:
DuckDB(consultas SQL na velocidade da luz direto do disco). -
Frontend Reativo:
Marimo(o notebook de nova geração que vira uma aplicação web instantânea).
💻 Mão na Massa: O Caso de Uso Financeiro
Para tornar isso real, vamos construir um mini-BI financeiro que analisa o histórico de ações (como BBAS3, PETR4, VALE3). Queremos extrair os dados, salvar em um formato de alta performance e criar um dashboard interativo.
Passo 1: O Setup "V8"
Esqueça o pip demorado. Vamos inicializar nosso projeto com o uv:
# Inicializa o projeto e cria o ambiente virtual em segundos
uv init meu_bi_python
cd meu_bi_python
# Adiciona as nossas ferramentas de elite
uv add duckdb polars marimo yfinance
Passo 2: Ingestão e Formato de Ouro (Parquet)
BIs de verdade não leem CSV em produção. Eles leem Parquet. Vamos criar um script simples (ingestao.py) para puxar dados da bolsa e salvar de forma otimizada usando Polars.
import yfinance as yf
import polars as pl
print("Extraindo dados financeiros...")
# Baixando histórico de 5 anos do Banco do Brasil
df_pandas = yf.download("BBAS3.SA", period="5y")
# Convertendo para Polars para máxima performance
df_polars = pl.from_pandas(df_pandas).reset_index()
# Salvando no formato de ouro: Parquet
df_polars.write_parquet("historico_bbas3.parquet")
print("Dados salvos com sucesso em Parquet! 🚀")
Ao rodar esse script, você terá um arquivo Parquet ultra-comprimido, pronto para ser lido em milissegundos.
Passo 3: O Motor OLAP encontra o Frontend (DuckDB + Marimo)
Aqui é onde a mágica das ferramentas tradicionais morre de inveja. Vamos criar nosso dashboard. No terminal, inicie o Marimo:
uv run marimo edit dashboard.py
No Marimo, a execução é reativa. Quando um filtro muda, apenas o que depende dele é recalculado. Crie as seguintes células no seu ambiente Marimo:
Célula 1: Imports e Conexão OLAP
import marimo as mo
import duckdb
import polars as pl
# Conectando o DuckDB em memória (ele lerá o arquivo do disco direto)
con = duckdb.connect()
Célula 2: A Interface (UI)
Vamos criar um slider para o usuário do nosso BI escolher quantos dias de histórico ele quer analisar.
# O Marimo cria componentes nativos renderizados na tela
dias_filtro = mo.ui.slider(start=30, stop=1500, step=30, value=365, label="Dias de Histórico:")
dias_filtro
Célula 3: A Query SQL de Alta Performance
Aqui amarramos a interface do Marimo com o motor do DuckDB. O SQL será reexecutado na velocidade da luz toda vez que o slider se mover.
# Query lendo o Parquet com base no filtro reativo da UI
query = f"""
SELECT Date, Close
FROM 'historico_bbas3.parquet'
ORDER BY Date DESC
LIMIT {dias_filtro.value}
"""
# DuckDB executa o SQL e devolve um DataFrame Polars nativamente!
df_resultado = con.execute(query).pl()
Célula 4: A Visualização
# Renderizando um gráfico de linha interativo
mo.ui.table(df_resultado) # Tabela de dados
(Dica de Ouro: Você pode usar bibliotecas como Altair ou Plotly dentro do Marimo para gráficos ainda mais complexos, o Marimo renderiza nativamente).
Passo 4: Escalando com Redis e OpenSearch (O Próximo Nível)
Se o seu BI começar a escalar para toda a empresa e você precisar analisar logs ou processar filas assíncronas de relatórios pesados, a stack continua flexível:
- Você sobe um contêiner do Redis via OrbStack para cachear as consultas do DuckDB.
- Conecta o OpenSearch para adicionar uma barra de pesquisa textual (ex: "Buscar todas as atas de reunião onde 'dividendos' foi mencionado").
Nenhuma ferramenta de caixinha te dá essa liberdade arquitetural.
🎯 Conclusão
Criar seu próprio BI com Python não é mais um bicho de sete cabeças reservado para gigantes da tecnologia. Com DuckDB atuando como motor analítico, Polars quebrando limites de memória, e o Marimo transformando scripts em interfaces reativas, você retoma o controle dos seus dados.
Você ganha performance absoluta, governança de código real (via Git) e zera os custos de licenciamento abusivos. Você deixa de ser um passageiro da ferramenta e se torna o engenheiro da plataforma.
E você, já esbarrou nos limites estruturais de ferramentas como Power BI ou Metabase? Como você resolveu? Deixa aí nos comentários pra gente trocar uma ideia!
🎁 Bônus: Colocando seu BI em Produção (Modo Aplicativo)
Até agora, usamos o comando marimo edit dashboard.py, que abre a interface de desenvolvimento (com as células de código visíveis). Mas, e quando você quiser enviar esse painel para a diretoria ou para os analistas de negócio usarem?
Você não quer que eles vejam o código Python, apenas a interface limpa e reativa.
Para rodar o seu dashboard em modo de produção (como uma aplicação web standalone, ocultando o código e exibindo apenas os componentes visuais), basta usar este comando:
uv run marimo run dashboard.py
Esse comando sobe um servidor local incrivelmente rápido e entrega a experiência final do usuário. Se você quiser expor isso para a rede da empresa, basta adicionar a flag do host:
uv run marimo run dashboard.py --host 0.0.0.0 --port 8080
Pronto! Seu BI customizado, de alta performance e custo zero de licença, está no ar e pronto para ser acessado por qualquer pessoa na rede. 🚀
Top comments (0)