Pular para conteúdo

Arquitetura do Ecossistema

Como o Ecossistema Quantilica é organizado e como as partes se conectam. Esta página descreve a forma do sistema; os Princípios de Design explicam por que ele tem essa forma.

Visão de sistema

graph TD
    Sources["Fontes de Dados Governamentais<br/>(IBGE, Tesouro/STN, BCB, Trabalho, Comércio, Saúde, Clima)"]

    Sources -->|IBGE SIDRA| SF["sidra-fetcher"]
    Sources -->|IBGE SIDRA| SQL["sidra-sql"]
    Sources -->|Tesouro Direto| TD["tesouro-direto-fetcher"]
    Sources -->|RTN/STN| RTN["rtn-fetcher"]
    Sources -->|BCB SGS| BCB["bcb-sgs-fetcher"]
    Sources -->|RAIS/CAGED| PD["pdet-fetcher"]
    Sources -->|Siscomex| CX["comex-fetcher"]
    Sources -->|DATASUS| DS["datasus-fetcher"]
    Sources -->|INMET BDMEP| IN["inmet-fetcher"]

    SF --> Processing["Processamento & Transformação<br/>(Polars vetorial / Pandas)"]
    SQL --> Processing
    TD --> Processing
    RTN --> Processing
    BCB --> Processing
    PD --> Processing
    CX --> Processing
    DS --> Processing
    IN --> Processing

    Processing --> Storage["Armazenamento Estruturado"]
    Storage --> PQ["Arquivos Parquet<br/>(analítico)"]
    Storage --> PG["PostgreSQL<br/>(operacional)"]

    PQ --> Analytics["Analytics & BI<br/>(dashboards, ML, relatórios)"]
    PG --> Analytics

O ecossistema é organizado em quatro camadas: extração, processamento, armazenamento, análise. Cada camada tem responsabilidades estritas — o que ela deve e o que ela não deve fazer.

Fundações Técnicas

A infraestrutura da Quantilica repousa sobre o princípio da Neutralidade de Domínio. O pacote quantilica-core não possui conhecimento sobre fontes específicas (SIDRA, DATASUS, etc); ele lida exclusivamente com abstrações técnicas.

A fundação é dividida em dois pilares para equilibrar leveza e poder:

  1. quantilica-core (Infraestrutura de I/O): Base estável e sem dependências binárias pesadas. Contém clientes HTTP/FTP resilientes, gerenciamento de manifestos (proveniência) e interface de storage.
  2. quantilica-io (Data Access Layer): Camada analítica que depende do Polars. Responsável por leitura multi-formato, conversão otimizada para Parquet e contratos de dados (schemas).

Tipos de Pacotes no Ecossistema

Tipo Padrão Esperado Exemplos
Client (Fetcher) Biblioteca Python + CLI simples sidra-fetcher, datasus-fetcher, bcb-sgs-fetcher
Pipeline Motor ETL + definições TOML/SQL sidra-sql, sidra-pipelines
Data Package Download + Transformação + Export rtn-fetcher, inmet-fetcher
CLI Host CLI unificada com descoberta por entry points quantilica-cli

Camadas e responsabilidades

Extração (sidra-fetcher, tesouro-direto-fetcher, rtn-fetcher, bcb-sgs-fetcher, pdet-fetcher, comex-fetcher, datasus-fetcher, inmet-fetcher)

Obter dados de APIs/FTPs governamentais com confiabilidade.

Faz:

  • Trata características das fontes (paginação, rate limits, retries, SSL).
  • Normaliza formatos de data quando necessário para extração.
  • Valida schema na origem.
  • Exporta em formatos padrão (Parquet, DataFrame, CSV).

Não faz:

  • Transforma dados analiticamente (responsabilidade do usuário).
  • Faz suposições sobre uso downstream.
  • Esconde falhas silenciosamente.

Processamento (Polars, Pandas)

Transformação rápida e flexível.

  • Polars — arquivos grandes, transformações complexas, lazy evaluation. Default do ecossistema.
  • Pandas — integração com bibliotecas estatísticas, funções customizadas, datasets menores.

Armazenamento (Parquet, PostgreSQL)

Persistência eficiente e confiável.

Critério Parquet PostgreSQL
Caso de uso Análise, arquivamento Operacional, dashboards ao vivo
Tamanho típico TBs em disco 100M+ linhas indexadas
Compressão 80-90% vs. CSV Moderada
Concorrência Leitura única por arquivo Multi-usuário ACID
Schema Preservado Estrito
Tempo real Não Sim
Custo de infra Apenas arquivos Instância de banco

Estratégia comum: Parquet para histórico longo + PostgreSQL para últimos meses ao vivo. Arquive para Parquet quando dados saem da janela operacional.

Análise (Jupyter, R, dashboards)

A camada que consome o resto. Fora do escopo do ecossistema — você pluga sua ferramenta de BI/ciência de dados favorita nos arquivos Parquet ou no PostgreSQL.

ETL vs. ELT

O ecossistema adota predominantemente ELT (Extract → Load → Transform), não ETL clássico.

graph LR
    A[Dados brutos] --> B[Load<br/>armazenar como-é]
    B --> C[Raw Parquet]
    C --> D[Transform<br/>on-demand]
    D --> E[Análise]
ETL clássico ELT (escolha do ecossistema)
Onde transforma Antes de armazenar Depois de armazenar
Dados brutos Descartados após transformação Preservados
Re-transformar Requer re-fetch Trivial — leia o raw e reprocesse
Armazenamento Menor Maior (raw + processado)
Flexibilidade Baixa Alta
Quando usa ETL Datasets pequenos com transformações estáveis

Datasets brasileiros são grandes e fontes governamentais publicam revisões com frequência. Preservar o raw é essencial para reprodutibilidade e re-processamento sem custo de rede.

Exemplo de ELT na prática

import polars as pl
from sidra_fetcher import SidraClient
from sidra_fetcher.sidra import Parametro, Formato, Precisao

# EXTRACT & LOAD: armazenar linhas brutas do SIDRA
param = Parametro(
    agregado="1620",
    territorios={"1": ["all"]},
    variaveis=["116"],
    periodos=[],
    classificacoes={},
    formato=Formato.A,
    decimais={"": Precisao.M},
)
with SidraClient(timeout=60) as client:
    rows = client.get(param.url())  # list[dict]

pl.DataFrame(rows).write_parquet("gdp_raw.parquet")  # raw preservado

# TRANSFORM: on-demand, re-rodável sem re-fetch
gdp = pl.read_parquet("gdp_raw.parquet").with_columns(
    pl.col("V").cast(pl.Float64, strict=False).pct_change().alias("growth")
)

Padrões de deployment

O ecossistema suporta quatro padrões principais de deployment, do mais simples ao mais complexo.

1. Local development

graph TD
    A["Seu computador"] --> B["Extrair"]
    B --> C["Transformar"]
    C --> D["Arquivos Parquet"]
    D --> E["Jupyter / Script Python"]

Melhor para: análise exploratória, prototipagem, pesquisa acadêmica de uma pessoa.

2. Daily batch pipeline

graph TD
    A["Tarefa agendada<br/>(cron / orquestrador)"] --> B["Extrair dados recentes"]
    B --> C["Validar"]
    C --> D["Transformar"]
    D --> E["Adicionar ao armazenamento"]
    E --> F["PostgreSQL<br/>(aplicações)"]
    E --> G["Parquet<br/>(análise)"]

Melhor para: dados operacionais regulares, dashboards, relatórios diários/semanais.

3. Real-time streaming

graph TD
    A["API/FTP Governamental"] --> B["Monitorar novos dados"]
    B --> C["Validar"]
    C --> D["Transformar"]
    D --> E["Banco em tempo real"]
    E --> F["Dashboard ao vivo / alertas"]

Melhor para: vigilância (epidemiologia, monitoramento comercial, picos de preços). Raro — fontes brasileiras quase nunca publicam em tempo real.

4. Integração multi-fonte

graph TD
    A["Múltiplas APIs<br/>(IBGE, Tesouro, Trabalho, etc.)"] --> B["Extrair em paralelo"]
    B --> C["Unir por chaves comuns<br/>(data, geografia, setor)"]
    C --> D["Dataset unificado"]
    D --> E["Data warehouse / data lake"]
    E --> F["Analytics, ML, relatórios"]

Melhor para: análise macroeconômica, modelagem econométrica, dashboards integrados de política pública. Veja a receita Análise Econômica Multi-Fonte.

Características de performance

Tempo típico de extração

Ferramenta Tempo Volume
sidra-fetcher (série única) 5-10 s 100-1 000 linhas
sidra-fetcher (varredura) 30-60 s 10k-100k linhas
tesouro-direto-fetcher (todos os títulos) 5-10 s ~1 000 títulos
pdet-fetcher (RAIS ano completo) 30-60 s 60M registros
pdet-fetcher (CAGED mensal) 5-10 s 10k-100k linhas
comex-fetcher (anual) 10-20 s 1M-10M transações
datasus-fetcher (doença/ano) 5-15 s 100k-1M registros

Compressão Parquet

Dataset CSV bruto Parquet Compressão
RAIS 2023 ~850 MB ~100 MB 88%
Tesouro (20 anos) ~5 MB ~1 MB 80%
CAGED mensal ~50 MB ~6 MB 88%
Siscomex anual ~500 MB ~50 MB 90%

Escalabilidade

Para a maioria dos casos (até bilhões de linhas):

  • Parquet em disco escala para TBs facilmente.
  • Polars processa arquivos maiores que a RAM via streaming.
  • PostgreSQL lida com 100M+ linhas com indexação adequada.

Para escala extrema (petabytes):

  • Data lake (S3 / object storage em nuvem).
  • Processamento distribuído (Spark, Dask, DuckDB).
  • Data warehouse cloud (BigQuery, Redshift, Snowflake).

Exemplo: pipeline de análise econômica

Combinando IBGE + Tesouro num pipeline ELT canônico:

import polars as pl
from sidra_fetcher import SidraClient
from sidra_fetcher.sidra import Parametro, Formato, Precisao
from tesouro_direto_fetcher.converter import convert_to_parquet

# 1. EXTRACT: cada ferramenta usa seu próprio padrão de acesso
gdp_param = Parametro(
    agregado="1620",
    territorios={"1": ["all"]},
    variaveis=["116"],
    periodos=[],
    classificacoes={},
    formato=Formato.A,
    decimais={"": Precisao.M},
)
with SidraClient(timeout=60) as client:
    gdp = pl.DataFrame(client.get(gdp_param.url()))

convert_to_parquet(src_dir="raw/tesouro", dest_dir="data/tesouro", dataset_type="precos")
bonds = pl.read_parquet("data/tesouro/precos.parquet")

# 2. TRANSFORM: Polars vetorizado
combined = gdp.join(bonds, on="date", how="inner").with_columns([
    pl.col("V").cast(pl.Float64, strict=False).pct_change().alias("gdp_growth"),
    pl.col("yield").pct_change().alias("yield_change"),
])

# 3. LOAD: dois destinos coexistindo (Parquet + PostgreSQL)
combined.write_parquet("gdp_bonds_analysis.parquet")
combined.write_database(
    "gdp_bonds",
    connection="postgresql://user:pass@host/db",
    if_table_exists="replace",
)

# 4. ANALYZE
print(combined.select(pl.corr("gdp_growth", "yield_change")))

Integração com ferramentas externas

A camada de armazenamento é deliberadamente agnóstica — Parquet e PostgreSQL conectam-se com qualquer ferramenta padrão.

Categoria Ferramentas comuns
BI Tableau, Power BI, Metabase (via PostgreSQL)
Notebooks Jupyter, Quarto (lendo Parquet diretamente)
ML Scikit-learn, XGBoost, Prophet, TensorFlow
Distribuído Spark, Dask, DuckDB
Data warehouse Snowflake, BigQuery, Redshift
Reverse ETL Exportar insights de volta a sistemas operacionais

Saiba mais