Pular para o conteúdo
Todos os artigos
  • Engenharia de dados
  • Dados abertos
  • Civic tech

Construindo um pipeline de dados sobre as APIs de dados abertos da Câmara e do Senado

Lições de design para um pipeline automatizado sobre os dados abertos da Câmara dos Deputados e do Senado: cargas idempotentes, sincronização incremental e reconciliação.

AL

Por

3 min de leitura

Read in English
Senadores sentados à mesa de uma comissão com notebooks e microfones no Senado Federal
Capa: 2024-11-12, Senado Federal do Brasil - 399, Senado Federal, CC BY 2.0, via Wikimedia Commons

A fonte: duas APIs públicas

As duas casas legislativas do Brasil publicam dados abertos. A Câmara dos Deputados expõe coleções como deputados, partidos, órgãos, proposições e votações, com documentação interativa em Swagger e uma coleção que lista as atualizações recentes. O Senado Federal tem seu próprio serviço de dados abertos, com estrutura diferente.

Para o Como Votam, construí um pipeline automatizado que coleta das duas e mantém nosso banco atualizado, com orçamento de ONG. Este artigo reúne as lições de design que valem para qualquer pipeline sobre dados públicos, sem entrar nos detalhes internos do projeto.

Duas fontes, um modelo

A Câmara e o Senado descrevem coisas parecidas (pessoas, partidos, matérias, votos) em formatos diferentes. A primeira decisão é onde a diferença mora. Mantenha cada fonte atrás de seu próprio adaptador, que fala o formato dela e entrega um modelo interno comum. Tudo o que vem depois, do armazenamento à análise, não sabe de qual casa o dado veio.

Essa única fronteira se paga toda vez que uma fonte muda o nome de um campo ou um endpoint.

Faça toda carga idempotente

Um pipeline agendado, mais cedo ou mais tarde, vai rodar duas vezes, ou quebrar no meio e rodar de novo. A única regra sensata é que repetir uma carga produza o mesmo resultado que rodá-la uma vez.

Em um banco relacional, isso normalmente significa upserts por um identificador estável da fonte:

INSERT INTO votes (source, source_id, matter_id, choice, voted_at)
VALUES ($1, $2, $3, $4, $5)
ON CONFLICT (source, source_id)
DO UPDATE SET
  choice = EXCLUDED.choice,
  voted_at = EXCLUDED.voted_at;

O trecho é ilustrativo. Repare na chave composta: as duas casas podem reutilizar os mesmos identificadores numéricos, então a fonte faz parte da chave.

Sincronize de forma incremental, usando o sinal da própria fonte

Baixar tudo de novo a cada execução é lento e deselegante com um serviço público. Quando a fonte informa o que mudou, use isso. Os dados abertos da Câmara incluem uma coleção de atualizações exatamente para esse fim: pergunte o que mudou em uma janela de tempo e busque só esses registros.

Dois hábitos tornam a sincronização incremental segura:

  • Sobreponha as janelas. Peça um pouco mais do que o tempo desde a última execução e conte com cargas idempotentes para absorver as duplicatas.
  • Grave o cursor só depois que a carga der certo. Se uma execução falhar, a próxima recomeça do mesmo ponto.

Reconcilie, porque a sincronização pode derivar

A sincronização incremental é eficiente, e também pode derivar em silêncio: uma atualização perdida, um registro corrigido na origem sem aviso, um bug do seu lado. A resposta é uma etapa de reconciliação separada, que compara periodicamente o que você tem com o que a fonte informa (contagens, totais, uma amostra de registros) e sinaliza diferenças.

Manter sincronização e reconciliação como preocupações distintas importa. A sincronização é otimizada para velocidade. A reconciliação é otimizada para confiança, e é ela que permite dizer aos usuários, com honestidade, que os números batem com o registro oficial.

Seja um bom cidadão de uma API pública

Serviços públicos têm limites que talvez você não veja na documentação. Limite a concorrência, faça recuo em caso de erro, identifique bem o seu cliente e guarde em cache o que não muda. Isso mantém o pipeline confiável e o serviço disponível para todos.

Resumo

  • Isole cada fonte atrás de um adaptador e de um modelo comum.
  • Cargas idempotentes tornam a falha entediante.
  • Use o feed de mudanças da fonte, sobreponha as janelas e grave o cursor por último.
  • Reconcilie separadamente, porque a confiança precisa de uma verificação própria.

Referências

Compartilhar
AL

Escrito por Adriano Leão

Sou engenheiro de software em Goiânia e construo sistemas de backend e IA. Estas notas vêm dos sistemas que entreguei: coarquitetar o GuaIA, escalar o Como Votam e levar o MusicPlayce Hub do zero a usuários reais.

Vamos conversar

O projeto por trás deste artigo

Como Votam

Continue lendo

As torres do Congresso Nacional, em Brasília, iluminadas à noite
BackendCloudCivic tech

Como escalar um banco relacional em 10x com orçamento de ONG usando nuvem híbrida

Como o Como Votam obteve 10x mais capacidade de banco relacional com uma migração para nuvem híbrida, sem custo adicional significativo, e o raciocínio por trás disso.

3 min de leitura
Mãos enluvadas manuseando um livro histórico manuscrito sobre uma mesa branca
IANLPBusca

Por que a busca por palavras-chave falha em decisões de tribunal, e o que a busca semântica muda

Como o ChatDoc permite que a equipe de um tribunal de contas busque decisões e normas em linguagem natural, e o que a busca semântica precisa para ser confiável.

3 min de leitura