Skip to content

sinpres/sinapi-extractor

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

sinapi-extractor

Extrator único de fontes oficiais SINAPI — transforma os arquivos públicos da Caixa Econômica Federal (PDFs e XLSXs) em JSON estruturado consumível por qualquer sistema, em particular o sinpres-api.

Fontes suportadas

Fonte da Caixa Periodicidade Extrator Output
SINAPI_Referência_YYYY_MM.xlsx Mensal extract_reference.py output/reference/*.json
SINAPI_Manutenções_YYYY_MM.xlsx Mensal extract_maintenances.py output/maintenances.json
SINAPI_Fichas_Especificacao_Tecnica_Insumos.pdf Eventual (~anual) extract_technical_sheets.py output/items.json + output/items.csv + output/images/

Requisitos

  • Python 3.9+
  • Dependências: pip install -r requirements.txt

Os arquivos da Caixa podem ser baixados em https://www.caixa.gov.br/poder-publico/modernizacao-gestao/sinapi/

Uso

Tudo de uma vez (típico mensal)

Coloque os arquivos baixados da Caixa em input/ mantendo os nomes oficiais:

input/
├── SINAPI_Referência_AAAA_MM.xlsx                       (obrigatório)
├── SINAPI_Manutenções_AAAA_MM.xlsx                      (opcional — pula se ausente)
└── SINAPI_Fichas_Especificacao_Tecnica_Insumos.pdf      (opcional, ~anual)

Depois rode passando só o mês de referência:

python3 src/extract_all.py 2026-04

Para pular o PDF de fichas técnicas (que muda raramente, ~1x por ano):

python3 src/extract_all.py 2026-04 --skip-pdf

A pasta input/ está no .gitignore — você pode jogar os arquivos da Caixa lá sem se preocupar com versionamento.

Por extrator (uso direto)

# Referência (insumos, composições, analítico)
python3 src/extract_reference.py 2026-04 input/SINAPI_Referência_2026_04.xlsx

# Manutenções (substituições de código)
python3 src/extract_maintenances.py input/SINAPI_Manutenções_2026_04.xlsx

# Fichas técnicas (PDF — eventual, atualiza pouco)
python3 src/extract_technical_sheets.py
# (ou passa um caminho explícito como primeiro argumento)

Estrutura do output

output/
├── reference/
│   ├── metadata.json              { reference_month, generated_at, source_file }
│   ├── items_catalog.json         [{ code, description, unit }]
│   ├── items_prices.json          [{ code, state_code, reference_month, is_desonerated, unit_price }]
│   ├── compositions_catalog.json  [{ code, description, unit }]
│   ├── compositions_prices.json   [{ code, state_code, reference_month, is_desonerated, base_unit_cost }]
│   └── composition_items.json     [{ composition_code, item_type, item_code, description, unit, coefficient }]
├── maintenances.json              [{ old_code, new_code, type: 'INPUT' | 'COMPOSITION' }]
├── items.json                     [{ code, description, unit, technical_standards, general_info, image, source_updated_at }]
├── items.csv                      mesmo conteúdo de items.json em CSV
└── images/                        imagens individuais por código SINAPI (ex: 34.jpeg)

Sobre os preços

unit_price e base_unit_cost são inteiros em centavos (R$ × 100). Isso evita imprecisão de ponto flutuante e é o formato direto pra gravar em colunas integer no banco do sinpres-api.

Sobre os coeficientes

Coeficientes em composition_items.json são strings com ponto decimal (ex: "0.250000"). Esse formato preserva precisão e mapeia direto pra coluna numeric(12,6) no Postgres.

Sobre as substituições

O Relatório de Manutenções da Caixa mistura vários tipos de evento (criação, desativação, alteração de descrição, etc.). O extrator extrai apenas substituições explícitas — entradas onde a coluna "Manutenção" carrega o padrão SUBSTITUÍDO PELO CÓDIGO N. Os demais tipos são contados e impressos no log, mas não geram entradas.

No dataset 2026-03, por exemplo, a Caixa não usa substituições explícitas — ela usa DESATIVAÇÃO + CRIAÇÃO pareada. O extrator é defensivo e gera array vazio nesse caso, sem falsos positivos.

Volumetria típica (referência 2026-03)

Output Registros Tamanho aproximado
items_catalog.json 4.855 ~500 KB
items_prices.json 191.742 ~17 MB
compositions_catalog.json 10.230 ~1,3 MB
compositions_prices.json 444.854 ~38 MB
composition_items.json 54.529 ~7 MB
maintenances.json 0 a centenas <100 KB

Ecossistema SINPRES

Este extrator é uma peça independente. Ele lê fontes oficiais SINAPI (PDF e XLSX) e cospe JSONs estáveis em output/. O que você faz com esses JSONs depois é com você — eles são o contrato público do extractor.

Um dos consumidores conhecidos é o sinpres-api, que copia os JSONs gerados aqui para a sua própria pasta input/ e popula um banco PostgreSQL. Mas o extractor não sabe nada sobre o api e não depende dele — você pode subir os JSONs num bucket S3, mandar pra um data warehouse, abrir no DuckDB, ou qualquer outra coisa.

  • sinapi-extractor — você está aqui. Gera os JSONs.
  • sinpres-api — API REST pública que consome os JSONs.
  • sinpres-web — frontend público (docs + explorer).

Schema dos JSONs gerados

Cada arquivo tem um shape estável que serve como contrato:

Arquivo Shape
output/reference/items_catalog.json [{ code, description, unit }]
output/reference/items_prices.json [{ code, state_code, reference_month, is_desonerated, unit_price }]
output/reference/compositions_catalog.json [{ code, description, unit }]
output/reference/compositions_prices.json [{ code, state_code, reference_month, is_desonerated, base_unit_cost }]
output/reference/composition_items.json [{ composition_code, item_type, item_code, description, unit, coefficient }]
output/maintenances.json [{ old_code, new_code, type: 'INPUT' | 'COMPOSITION' }]
output/items.json [{ code, description, unit, technical_standards, general_info, image, source_updated_at }]

Mantido por

TREE.IA

Licença

MIT

About

Extrator de dados do SINAPI (Sistema Nacional de Pesquisa de Custos e Índices da Construção Civil). Transforma os PDFs públicos da Caixa Econômica Federal em JSON/CSV estruturado.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages