Skip to main content

sidra-fetcher: Cliente Python para a API do IBGE/SIDRA

License: MIT Python

Biblioteca Python para buscar e processar dados e metadados das APIs oficiais do IBGEAgregados v3 e SIDRA. Fornece acesso tipado via dataclasses a pesquisas, agregados, períodos, territórios, variáveis e classificações, com clientes síncrono e assíncrono.


Instalação

pip install sidra-fetcher

Com uv:

uv add sidra-fetcher

Requisitos: Python 3.12+

Interface de Linha de Comando (CLI)

O sidra-fetcher inclui uma interface de linha de comando para exploração rápida de metadados.

Uso Autônomo

# Listar todas as pesquisas
sidra-fetcher list pesquisas

# Listar agregados de uma pesquisa (ex: 73)
sidra-fetcher list agregados 73

# Ver metadados detalhados de um agregado (ex: 1612)
sidra-fetcher info 1612

# Listar períodos disponíveis
sidra-fetcher periods 1612

# Baixar TODOS os dados de um agregado (ver seção dedicada abaixo)
sidra-fetcher download 1705 --dry-run
sidra-fetcher download 1705 -o ./sidra_data

Integração com quantilica-cli

Se o quantilica-cli estiver instalado no mesmo ambiente, o sidra-fetcher será detectado automaticamente como um plugin:

quantilica sidra info 1612
quantilica sidra download 1705 -o ./sidra_data

Uso Rápido

from sidra_fetcher.fetcher import SidraClient

with SidraClient() as client:
    # Listar todas as pesquisas e seus agregados
    index = client.get_indice_pesquisas_agregados()
    print(index[0].nome, "->", index[0].agregados[0].nome)

    # Metadados completos do agregado 1705 (IPCA-15)
    agregado = client.get_agregado(1705)
    print(agregado.nome)
    print(f"Períodos: {len(agregado.periodos)}")
    print(f"Localidades: {len(agregado.localidades)}")

API Python

SidraClient (síncrono)

from sidra_fetcher.fetcher import SidraClient

client = SidraClient(timeout=60)

Todos os métodos abaixo também funcionam via context manager: with SidraClient() as client:.

get_indice_pesquisas_agregados()

Retorna todas as pesquisas com o índice de agregados aninhado.

index = client.get_indice_pesquisas_agregados()
# -> list[IndicePesquisaAgregados]

for pesquisa in index:
    print(pesquisa.id, pesquisa.nome)
    for agregado in pesquisa.agregados:
        print("  ", agregado.id, agregado.nome)

get_agregado_metadados(agregado_id)

Retorna os metadados completos de um agregado — variáveis, classificações, níveis territoriais e periodicidade.

meta = client.get_agregado_metadados(1705)
# -> Agregado

print(meta.id, meta.nome)
print(meta.periodicidade.frequencia)   # ex: "mensal"
print([v.nome for v in meta.variaveis])
print([c.nome for c in meta.classificacoes])

get_agregado_periodos(agregado_id)

Retorna os períodos disponíveis de um agregado, com metadados temporais analisados.

periodos = client.get_agregado_periodos(1705)
# -> list[Periodo]

for p in periodos:
    print(p.id, p.frequencia, p.data_inicio, p.data_fim)
    # ex: "202312  mensal  2023-12-01  2023-12-31"

Veja Análise de Períodos para a lista completa de campos do objeto Periodo.

get_agregado_localidades(agregado_id, localidades_nivel)

Retorna as localidades filtradas por um ou mais códigos de nível territorial (ex: "N1" para Brasil, "N3" para estados, "N6" para municípios).

localidades = client.get_agregado_localidades(1705, "N3")
# -> list[Localidade]

for loc in localidades:
    print(loc.id, loc.nome, loc.nivel.id)

get_agregado(agregado_id)

Método de conveniência: busca metadados, períodos e todas as localidades declaradas em uma única chamada.

agregado = client.get_agregado(1705)
# -> Agregado (com .periodos e .localidades preenchidos)

get_acervo(acervo)

Busca uma listagem de "acervo" (coleção). Use AcervoEnum para selecionar a coleção desejada.

from sidra_fetcher.agregados import AcervoEnum

assuntos = client.get_acervo(AcervoEnum.ASSUNTO)
variaveis = client.get_acervo(AcervoEnum.VARIAVEL)

Valores disponíveis no AcervoEnum:

Membro Descrição
ASSUNTO Tópicos / assuntos
CLASSIFICACAO Classificações
NIVELTERRITORIAL Níveis territoriais
PERIODO Períodos
PERIODICIDADE Periodicidades
VARIAVEL Variáveis

Baixando Todos os Dados de um Agregado

A API SIDRA limita cada requisição ao endpoint /values a 100.000 valores (SIDRA_API_VALUES_LIMIT, produto das quantidades selecionadas em cada dimensão: localidades × variáveis × categorias por classificação × períodos). O sidra-fetcher descobre automaticamente todas as dimensões de um agregado (via metadados) e divide o download em quantas requisições forem necessárias para nunca ultrapassar esse limite — sem o usuário precisar saber de antemão o tamanho da tabela.

Isso é um recurso ad-hoc: basta um agregado_id arbitrário, ao contrário do sidra-sql, que exige um pipeline curado (fetch.toml) por tabela. A ordem de divisão (chunking) é, em prioridade: período → lote de localidades → variável → combinação de categorias de classificação — cada nível territorial do agregado (administrativo, especial, ibge) é baixado separadamente.

Planejar antes de baixar

from sidra_fetcher.fetcher import SidraClient
from sidra_fetcher.download import describe_download_plan

with SidraClient() as client:
    chunks = client.plan_dados_agregado(1705)
    resumo = describe_download_plan(chunks)
    print(resumo)
    # {'n_requests': 192, 'n_valores': 513792,
    #  'por_nivel': {'N1': {...}, 'N6': {...}}}

Cada item de chunks é um DownloadChunk(nivel_territorial, parametro, n_valores)parametro é o Parametro de sidra_fetcher.sidra pronto para virar URL.

Baixar os dados

Três formas, dependendo do tamanho da tabela:

# Tabelas pequenas: mescla tudo em uma lista única (mantém 1 cabeçalho).
linhas = client.get_dados_agregado(1705)

# Tabelas grandes: um chunk por vez, sem bufferizar tudo em memória.
for chunk, linhas in client.iter_dados_agregado(1705):
    ...

# Grava em disco: um NDJSON + manifest (SHA-256) por nível territorial.
paths = client.download_dados_agregado(1705, "./sidra_data", max_workers=4)

download_dados_agregado grava dados_{nivel}.ndjson (uma linha JSON por registro — a primeira é o cabeçalho, mantido uma única vez mesmo quando o download exige múltiplos requests) e dados_{nivel}.ndjson.manifest.json (mesma convenção de proveniência de save_agregado/load_agregado) para cada nível territorial efetivamente baixado.

Todos os métodos aceitam restringir a seleção (por padrão, baixam tudo):

client.plan_dados_agregado(
    1705,
    niveis_territoriais=["N3", "N6"],   # padrão: todos os níveis do agregado
    variaveis=["355"],                   # padrão: todas
    periodos=["202301", "202302"],       # padrão: todos
    classificacoes={"315": ["7169"]},    # padrão: todas as categorias
)

Via CLI

# Só mostra o plano (requests e valores estimados por nível), sem baixar.
sidra-fetcher download 1705 --dry-run

# Baixa de fato, com concorrência e uma pequena pausa entre requests.
sidra-fetcher download 1705 -o ./sidra_data --niveis N3,N6 --max-workers 4 --delay 0.5

# Via quantilica-cli (mesmos argumentos)
quantilica sidra download 1705 -o ./sidra_data

AsyncSidraClient (assíncrono)

Equivalente assíncrono do SidraClient. Todos os métodos são corrotinas. get_agregado busca metadados e períodos concorrentemente via asyncio.gather. Também expõe plan_dados_agregado (mesmo planejamento de chunking, sem I/O extra) — o download em si (get_dados_agregado/iter_dados_agregado/download_dados_agregado) está disponível apenas no SidraClient síncrono.

import asyncio
from sidra_fetcher.fetcher import AsyncSidraClient

async def main():
    async with AsyncSidraClient() as client:
        index = await client.get_indice_pesquisas_agregados()
        agregado = await client.get_agregado(1705)
        print(len(agregado.periodos))

asyncio.run(main())

Análise de Períodos

get_agregado_periodos analisa as strings de período retornadas pela API e as converte em objetos Periodo estruturados, com frequência detectada e intervalo de datas calculado automaticamente.

Campos do objeto Periodo

Campo Tipo Descrição
id str ID bruto do período da API (ex: "202312")
literals list[str] Representações legíveis (ex: ["dezembro de 2023"])
modificacao dt.date Data da última atualização dos dados do período
frequencia str | None Tipo de frequência detectado (ver tabela abaixo)
data_inicio dt.date | None Primeiro dia do período
data_fim dt.date | None Último dia do período
ano int | None Ano
mes int | None Mês (1–12); em trimestres móveis, o último mês
trimestre int | None Número do trimestre (1–4)
semestre int | None Número do semestre (1–2)
ano_fim int | None Ano final para períodos plurianuais

Tipos de frequência

frequencia Exemplo de literal Intervalo de datas
mensal "janeiro de 2023" 1 jan – 31 jan
trimestral "1º trimestre de 2023" 1 jan – 31 mar
trimestre_movel "jan-fev-mar 2023" 1 jan – 31 mar
semestral "1º semestre de 2023" 1 jan – 30 jun
anual "2023" 1 jan – 31 dez
plurianual "2020/2023" 1 jan 2020 – 31 dez 2023
nao_reconhecida (sem correspondência) None / None

As constantes de frequência também são importáveis:

from sidra_fetcher.periodos import (
    FREQUENCIA_MENSAL,
    FREQUENCIA_TRIMESTRAL,
    FREQUENCIA_TRIMESTRE_MOVEL,
    FREQUENCIA_SEMESTRAL,
    FREQUENCIA_ANUAL,
    FREQUENCIA_PLURIANUAL,
    FREQUENCIA_NAO_RECONHECIDA,
)

Construtor de URL SIDRA

A classe Parametro constrói e analisa URLs de requisição SIDRA (/values).

from sidra_fetcher.sidra import Parametro, Formato, Precisao

params = Parametro(
    agregado="1705",
    territorios={"3": ["all"]},   # todos os estados
    variaveis=["4099"],            # taxa de desemprego
    periodos=["202301", "202302"],
    classificacoes={"2": ["6794"]},
    formato=Formato.A,
    decimais={"": Precisao.M},
)

print(params.url())
# https://apisidra.ibge.gov.br/values/t/1705/n3/all/v/4099/p/202301,202302/c2/6794/h/y/f/a/d/m

Parâmetros do Parametro

Parâmetro Tipo Segmento SIDRA Exemplo
agregado str /t/{id} "1705"
territorios dict[str, list[str]] /n{nivel}/{ids} {"3": ["all"]}/n3/all
variaveis list[str] /v/{ids} ["4099", "4100"] ou []/v/all
periodos list[str] /p/{ids} ["202301"] ou []/p/all
classificacoes dict[str, list[str]] /c{id}/{values} {"2": ["6794"]}
cabecalho bool /h/y ou /h/n True
formato Formato /f/{code} Formato.A
decimais dict[str, Precisao] /d/{precisao} {"": Precisao.M}/d/m

Analisar uma URL SIDRA existente

from sidra_fetcher.sidra import parameter_from_url, parse_url

url = "https://apisidra.ibge.gov.br/values/t/1705/n3/all/v/4099/p/all/h/y/f/a/d/m"

params = parameter_from_url(url)
print(params.agregado)     # "1705"
print(params.territorios)  # {"3": ["all"]}

parsed = parse_url(url)
print(parsed["aggregate"])    # "1705"
print(parsed["territories"])  # {"3": ["all"]}
print(parsed["periods"])      # ["all"]

Utilitários de Leitura e Achatamento

Salvar e carregar metadados de agregados

from sidra_fetcher.reader import save_agregado, load_agregado

# Salvar em JSON
save_agregado(agregado, "agregado_1705.json")

# Carregar do JSON (períodos são reanalisados automaticamente)
agregado = load_agregado("agregado_1705.json")

Achatar metadados para análise

flatten_aggregate_metadata transforma a estrutura hierárquica variável × classificação em uma sequência de dicts — uma linha por combinação única de variável + categoria:

from sidra_fetcher.reader import flatten_aggregate_metadata

raw_meta = client.get("https://servicodados.ibge.gov.br/api/v3/agregados/1705/metadados")

for row in flatten_aggregate_metadata(raw_meta):
    print(row["agregado"], row["D4N"], row.get("C5N"), row["MN"])

Cada linha contém:

Chave Descrição
agregado Nome do agregado
pesquisa Nome da pesquisa
assunto Assunto / tópico
frequencia Frequência do agregado
url_agregado URL do agregado
D4C/D4N ID / nome da variável
D5C/D5N ID / nome da primeira classificação
C5C/C5N ID / nome da primeira categoria
MN Unidade de medida
nivel Nível hierárquico da categoria

flatten_surveys_metadata achata o índice de pesquisas em uma lista de dicts {pesquisa_id, pesquisa, agregado_id, agregado}:

from sidra_fetcher.reader import flatten_surveys_metadata

raw_index = client.get("https://servicodados.ibge.gov.br/api/v3/agregados")
rows = flatten_surveys_metadata(raw_index)

Utilitários de Tamanho e Estatísticas

from sidra_fetcher.stats import calculate_aggregate

stats = calculate_aggregate(agregado)
print(stats)
# {
#   "pesquisa_id": "...",
#   "agregado_id": 1705,
#   "n_localidades": 27,
#   "n_variaveis": 1,
#   "n_classificacoes": 1,
#   "n_dimensoes": 2,
#   "n_periodos": 84,
#   "period_size": 54,    # linhas por período
#   "total_size": 4536,   # total estimado de linhas
#   ...
# }

Estrutura do Projeto

src/sidra_fetcher/
├── __init__.py          — logger do pacote
├── agregados.py         — dataclasses e construtores de URL para a API Agregados
├── download.py          — planejamento (chunking) e download completo de um agregado
├── fetcher.py           — SidraClient e AsyncSidraClient
├── periodos.py          — análise de strings de período e detecção de frequência
├── reader.py            — parsers JSON → dataclass e achatamento de metadados
├── sidra.py             — construtor de URL SIDRA (Parametro) e parsers
└── stats.py             — estatísticas de tamanho e dimensões

Desenvolvimento

git clone https://github.com/Quantilica/sidra-fetcher.git
cd sidra-fetcher
uv sync --extra dev
uv run ruff check src/ tests/
uv run ruff format src/ tests/
uv run python -m unittest discover -v tests

Licença

MIT — veja LICENSE.

Release files for sidra-fetcher 0.8.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for sidra-fetcher 0.8.0
File Size Uploaded
sidra_fetcher-0.8.0.tar.gz 51.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for sidra-fetcher 0.8.0
File Interpreter ABI Platform
sidra_fetcher-0.8.0-py3-none-any.whl Python 3 none any Details

Total release size: 95.6 kB

Release files / sidra_fetcher-0.8.0.tar.gz

Download URL sidra_fetcher-0.8.0.tar.gz
Size 51.1 kB
Tags Source
SHA-256 checksum
How to use checksums
5aad9ffdda05e52dab9ba2de07fb697c0299c3e228b000f58b2c786297b4d487
BLAKE2b-256 checksum
How to use checksums
8588519c4318f5c99727114d3051177205e9c835b6fe493f67bcb207b70257cc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 7, 2026.

Transparency log

Release files / sidra_fetcher-0.8.0-py3-none-any.whl

Download URL sidra_fetcher-0.8.0-py3-none-any.whl
Size 44.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
054508058e04898f8645b748f3b580a789ce16ff152ac0c5f33ac37b88dfee4c
BLAKE2b-256 checksum
How to use checksums
30cbe9013dfd4243437a4573ea8cf55f28b6308b651c942a295b30ff84728733
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 7, 2026.

Transparency log

Release history Release notifications | RSS feed

0.10.3

2 release files

0.10.2

2 release files

0.10.1

2 release files

0.10.0

2 release files

0.9.0

2 release files

0.8.1

2 release files

This release

0.8.0 This release

2 release files

0.7.3

2 release files

0.7.2

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page