sidra-fetcher 0.7.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- sidra_fetcher-0.7.2/.github/workflows/publish.yml +66 -0
- sidra_fetcher-0.7.2/.github/workflows/test.yml +38 -0
- sidra_fetcher-0.7.2/.gitignore +42 -0
- sidra_fetcher-0.7.2/.python-version +1 -0
- sidra_fetcher-0.7.2/CHANGELOG.md +21 -0
- sidra_fetcher-0.7.2/CLAUDE.md +3 -0
- sidra_fetcher-0.7.2/LICENSE +21 -0
- sidra_fetcher-0.7.2/PKG-INFO +421 -0
- sidra_fetcher-0.7.2/README.md +396 -0
- sidra_fetcher-0.7.2/pyproject.toml +70 -0
- sidra_fetcher-0.7.2/src/sidra_fetcher/__init__.py +19 -0
- sidra_fetcher-0.7.2/src/sidra_fetcher/__main__.py +9 -0
- sidra_fetcher-0.7.2/src/sidra_fetcher/agregados.py +321 -0
- sidra_fetcher-0.7.2/src/sidra_fetcher/cli.py +148 -0
- sidra_fetcher-0.7.2/src/sidra_fetcher/fetcher.py +346 -0
- sidra_fetcher-0.7.2/src/sidra_fetcher/periodos.py +277 -0
- sidra_fetcher-0.7.2/src/sidra_fetcher/plugin.py +137 -0
- sidra_fetcher-0.7.2/src/sidra_fetcher/py.typed +0 -0
- sidra_fetcher-0.7.2/src/sidra_fetcher/reader.py +721 -0
- sidra_fetcher-0.7.2/src/sidra_fetcher/sidra.py +466 -0
- sidra_fetcher-0.7.2/src/sidra_fetcher/stats.py +136 -0
- sidra_fetcher-0.7.2/src/sidra_fetcher/storage.py +18 -0
- sidra_fetcher-0.7.2/tests/test_agregados.py +49 -0
- sidra_fetcher-0.7.2/tests/test_fetcher.py +349 -0
- sidra_fetcher-0.7.2/tests/test_periodos.py +271 -0
- sidra_fetcher-0.7.2/tests/test_sidra.py +148 -0
- sidra_fetcher-0.7.2/tests/test_stats.py +172 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
build:
|
|
10
|
+
name: Build distribution
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v4
|
|
14
|
+
|
|
15
|
+
- name: Install uv
|
|
16
|
+
uses: astral-sh/setup-uv@v5
|
|
17
|
+
|
|
18
|
+
- name: Build sdist and wheel
|
|
19
|
+
run: uv build
|
|
20
|
+
|
|
21
|
+
- name: Upload build artifacts
|
|
22
|
+
uses: actions/upload-artifact@v4
|
|
23
|
+
with:
|
|
24
|
+
name: dist
|
|
25
|
+
path: dist/
|
|
26
|
+
|
|
27
|
+
publish-testpypi:
|
|
28
|
+
name: Publish to TestPyPI
|
|
29
|
+
needs: build
|
|
30
|
+
runs-on: ubuntu-latest
|
|
31
|
+
environment:
|
|
32
|
+
name: testpypi
|
|
33
|
+
url: https://test.pypi.org/p/sidra-fetcher
|
|
34
|
+
permissions:
|
|
35
|
+
id-token: write
|
|
36
|
+
steps:
|
|
37
|
+
- name: Download build artifacts
|
|
38
|
+
uses: actions/download-artifact@v4
|
|
39
|
+
with:
|
|
40
|
+
name: dist
|
|
41
|
+
path: dist/
|
|
42
|
+
|
|
43
|
+
- name: Publish to TestPyPI
|
|
44
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
45
|
+
with:
|
|
46
|
+
repository-url: https://test.pypi.org/legacy/
|
|
47
|
+
skip-existing: true
|
|
48
|
+
|
|
49
|
+
publish-pypi:
|
|
50
|
+
name: Publish to PyPI
|
|
51
|
+
needs: publish-testpypi
|
|
52
|
+
runs-on: ubuntu-latest
|
|
53
|
+
environment:
|
|
54
|
+
name: pypi
|
|
55
|
+
url: https://pypi.org/p/sidra-fetcher
|
|
56
|
+
permissions:
|
|
57
|
+
id-token: write
|
|
58
|
+
steps:
|
|
59
|
+
- name: Download build artifacts
|
|
60
|
+
uses: actions/download-artifact@v4
|
|
61
|
+
with:
|
|
62
|
+
name: dist
|
|
63
|
+
path: dist/
|
|
64
|
+
|
|
65
|
+
- name: Publish to PyPI
|
|
66
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
name: Test
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
name: Test (Python ${{ matrix.python-version }})
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
strategy:
|
|
14
|
+
fail-fast: false
|
|
15
|
+
matrix:
|
|
16
|
+
python-version: ["3.13"]
|
|
17
|
+
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@v4
|
|
20
|
+
|
|
21
|
+
- name: Install uv
|
|
22
|
+
uses: astral-sh/setup-uv@v5
|
|
23
|
+
with:
|
|
24
|
+
enable-cache: true
|
|
25
|
+
|
|
26
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
27
|
+
run: uv python install ${{ matrix.python-version }}
|
|
28
|
+
|
|
29
|
+
- name: Install dependencies
|
|
30
|
+
run: uv sync --group dev
|
|
31
|
+
|
|
32
|
+
- name: Lint with ruff
|
|
33
|
+
run: |
|
|
34
|
+
uv run ruff check src/ tests/
|
|
35
|
+
uv run ruff format --check src/ tests/
|
|
36
|
+
|
|
37
|
+
- name: Run tests
|
|
38
|
+
run: uv run python -m unittest discover -v tests
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Build / packaging
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.egg-info/
|
|
5
|
+
build/
|
|
6
|
+
dist/
|
|
7
|
+
|
|
8
|
+
# Virtual envs e caches do uv
|
|
9
|
+
.venv/
|
|
10
|
+
.uv-cache/
|
|
11
|
+
|
|
12
|
+
# Lockfile — libs não versionam uv.lock
|
|
13
|
+
uv.lock
|
|
14
|
+
|
|
15
|
+
# Caches de teste / lint / tipos
|
|
16
|
+
.pytest_cache/
|
|
17
|
+
.ruff_cache/
|
|
18
|
+
.mypy_cache/
|
|
19
|
+
|
|
20
|
+
# Cobertura
|
|
21
|
+
.coverage
|
|
22
|
+
.coverage.*
|
|
23
|
+
htmlcov/
|
|
24
|
+
|
|
25
|
+
# Editor / IDE / OS
|
|
26
|
+
.vscode/
|
|
27
|
+
.idea/
|
|
28
|
+
.DS_Store
|
|
29
|
+
Thumbs.db
|
|
30
|
+
*.swp
|
|
31
|
+
|
|
32
|
+
# Logs e env locais
|
|
33
|
+
*.log
|
|
34
|
+
.env
|
|
35
|
+
.env.local
|
|
36
|
+
|
|
37
|
+
# Claude
|
|
38
|
+
.claude/
|
|
39
|
+
|
|
40
|
+
# Específico do repo
|
|
41
|
+
data/
|
|
42
|
+
*.ini
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.13
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
Todas as mudanças notáveis deste projeto serão documentadas neste arquivo.
|
|
4
|
+
|
|
5
|
+
O formato segue [Keep a Changelog](https://keepachangelog.com/pt-BR/1.1.0/),
|
|
6
|
+
e este projeto adere ao [Semantic Versioning](https://semver.org/lang/pt-BR/).
|
|
7
|
+
|
|
8
|
+
## [0.7.2] - 2026-07-16
|
|
9
|
+
|
|
10
|
+
### Corrigido
|
|
11
|
+
|
|
12
|
+
- Dependência de `quantilica-core` trocada de `git+https://...` para `quantilica-core[cli]>=0.3.1`
|
|
13
|
+
(versão publicada no PyPI, com o extra `cli` que fornece `typer`/`rich` exigidos pelo
|
|
14
|
+
entry point `quantilica.fetchers`, corrigindo um `ModuleNotFoundError: typer` em
|
|
15
|
+
instalações isoladas via `pip install sidra-fetcher`)
|
|
16
|
+
- Instrução de instalação no README (`pip install sidra-fetcher`, em vez de git+https)
|
|
17
|
+
|
|
18
|
+
### Adicionado
|
|
19
|
+
|
|
20
|
+
- `py.typed` (marcador de pacote tipado, consistente com o classifier `Typing :: Typed`)
|
|
21
|
+
- Primeiro release público no PyPI
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Quantilica
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,421 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: sidra-fetcher
|
|
3
|
+
Version: 0.7.2
|
|
4
|
+
Summary: A Python package for fetching data from IBGE's SIDRA and Agregados APIs
|
|
5
|
+
Project-URL: Homepage, https://github.com/Quantilica/sidra-fetcher
|
|
6
|
+
Project-URL: Repository, https://github.com/Quantilica/sidra-fetcher
|
|
7
|
+
Project-URL: Issues, https://github.com/Quantilica/sidra-fetcher/issues
|
|
8
|
+
Author-email: "Komesu, D.K." <daniel@dkko.me>
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: agregados,api-client,brazil,ibge,open-data,sidra,statistics
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Intended Audience :: Science/Research
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Topic :: Scientific/Engineering :: Information Analysis
|
|
20
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
21
|
+
Classifier: Typing :: Typed
|
|
22
|
+
Requires-Python: >=3.12
|
|
23
|
+
Requires-Dist: quantilica-core[cli]>=0.3.1
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
|
|
26
|
+
# sidra-fetcher: Cliente Python para a API do IBGE/SIDRA
|
|
27
|
+
|
|
28
|
+
 
|
|
29
|
+
|
|
30
|
+
Biblioteca Python para buscar e processar dados e metadados das APIs oficiais do [IBGE](https://www.ibge.gov.br/) — [Agregados v3](https://servicodados.ibge.gov.br/api/docs/agregados?versao=3) e [SIDRA](https://apisidra.ibge.gov.br). Fornece acesso tipado via dataclasses a pesquisas, agregados, períodos, territórios, variáveis e classificações, com clientes síncrono e assíncrono.
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Instalação
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
pip install sidra-fetcher
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Com [uv](https://github.com/astral-sh/uv):
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
uv add sidra-fetcher
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**Requisitos:** Python 3.12+
|
|
47
|
+
|
|
48
|
+
## Interface de Linha de Comando (CLI)
|
|
49
|
+
|
|
50
|
+
O `sidra-fetcher` inclui uma interface de linha de comando para exploração rápida de metadados.
|
|
51
|
+
|
|
52
|
+
### Uso Autônomo
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# Listar todas as pesquisas
|
|
56
|
+
sidra-fetcher list pesquisas
|
|
57
|
+
|
|
58
|
+
# Listar agregados de uma pesquisa (ex: 73)
|
|
59
|
+
sidra-fetcher list agregados 73
|
|
60
|
+
|
|
61
|
+
# Ver metadados detalhados de um agregado (ex: 1612)
|
|
62
|
+
sidra-fetcher info 1612
|
|
63
|
+
|
|
64
|
+
# Listar períodos disponíveis
|
|
65
|
+
sidra-fetcher periods 1612
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Integração com `quantilica-cli`
|
|
69
|
+
|
|
70
|
+
Se o `quantilica-cli` estiver instalado no mesmo ambiente, o `sidra-fetcher` será detectado automaticamente como um plugin:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
quantilica sidra info 1612
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Uso Rápido
|
|
79
|
+
|
|
80
|
+
```python
|
|
81
|
+
from sidra_fetcher.fetcher import SidraClient
|
|
82
|
+
|
|
83
|
+
with SidraClient() as client:
|
|
84
|
+
# Listar todas as pesquisas e seus agregados
|
|
85
|
+
index = client.get_indice_pesquisas_agregados()
|
|
86
|
+
print(index[0].nome, "->", index[0].agregados[0].nome)
|
|
87
|
+
|
|
88
|
+
# Metadados completos do agregado 1705 (IPCA-15)
|
|
89
|
+
agregado = client.get_agregado(1705)
|
|
90
|
+
print(agregado.nome)
|
|
91
|
+
print(f"Períodos: {len(agregado.periodos)}")
|
|
92
|
+
print(f"Localidades: {len(agregado.localidades)}")
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## API Python
|
|
98
|
+
|
|
99
|
+
### `SidraClient` (síncrono)
|
|
100
|
+
|
|
101
|
+
```python
|
|
102
|
+
from sidra_fetcher.fetcher import SidraClient
|
|
103
|
+
|
|
104
|
+
client = SidraClient(timeout=60)
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Todos os métodos abaixo também funcionam via context manager: `with SidraClient() as client:`.
|
|
108
|
+
|
|
109
|
+
#### `get_indice_pesquisas_agregados()`
|
|
110
|
+
|
|
111
|
+
Retorna todas as pesquisas com o índice de agregados aninhado.
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
index = client.get_indice_pesquisas_agregados()
|
|
115
|
+
# -> list[IndicePesquisaAgregados]
|
|
116
|
+
|
|
117
|
+
for pesquisa in index:
|
|
118
|
+
print(pesquisa.id, pesquisa.nome)
|
|
119
|
+
for agregado in pesquisa.agregados:
|
|
120
|
+
print(" ", agregado.id, agregado.nome)
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
#### `get_agregado_metadados(agregado_id)`
|
|
124
|
+
|
|
125
|
+
Retorna os metadados completos de um agregado — variáveis, classificações, níveis territoriais e periodicidade.
|
|
126
|
+
|
|
127
|
+
```python
|
|
128
|
+
meta = client.get_agregado_metadados(1705)
|
|
129
|
+
# -> Agregado
|
|
130
|
+
|
|
131
|
+
print(meta.id, meta.nome)
|
|
132
|
+
print(meta.periodicidade.frequencia) # ex: "mensal"
|
|
133
|
+
print([v.nome for v in meta.variaveis])
|
|
134
|
+
print([c.nome for c in meta.classificacoes])
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
#### `get_agregado_periodos(agregado_id)`
|
|
138
|
+
|
|
139
|
+
Retorna os períodos disponíveis de um agregado, com metadados temporais analisados.
|
|
140
|
+
|
|
141
|
+
```python
|
|
142
|
+
periodos = client.get_agregado_periodos(1705)
|
|
143
|
+
# -> list[Periodo]
|
|
144
|
+
|
|
145
|
+
for p in periodos:
|
|
146
|
+
print(p.id, p.frequencia, p.data_inicio, p.data_fim)
|
|
147
|
+
# ex: "202312 mensal 2023-12-01 2023-12-31"
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Veja [Análise de Períodos](#análise-de-períodos) para a lista completa de campos do objeto `Periodo`.
|
|
151
|
+
|
|
152
|
+
#### `get_agregado_localidades(agregado_id, localidades_nivel)`
|
|
153
|
+
|
|
154
|
+
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).
|
|
155
|
+
|
|
156
|
+
```python
|
|
157
|
+
localidades = client.get_agregado_localidades(1705, "N3")
|
|
158
|
+
# -> list[Localidade]
|
|
159
|
+
|
|
160
|
+
for loc in localidades:
|
|
161
|
+
print(loc.id, loc.nome, loc.nivel.id)
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
#### `get_agregado(agregado_id)`
|
|
165
|
+
|
|
166
|
+
Método de conveniência: busca metadados, períodos e todas as localidades declaradas em uma única chamada.
|
|
167
|
+
|
|
168
|
+
```python
|
|
169
|
+
agregado = client.get_agregado(1705)
|
|
170
|
+
# -> Agregado (com .periodos e .localidades preenchidos)
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
#### `get_acervo(acervo)`
|
|
174
|
+
|
|
175
|
+
Busca uma listagem de "acervo" (coleção). Use `AcervoEnum` para selecionar a coleção desejada.
|
|
176
|
+
|
|
177
|
+
```python
|
|
178
|
+
from sidra_fetcher.agregados import AcervoEnum
|
|
179
|
+
|
|
180
|
+
assuntos = client.get_acervo(AcervoEnum.ASSUNTO)
|
|
181
|
+
variaveis = client.get_acervo(AcervoEnum.VARIAVEL)
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Valores disponíveis no `AcervoEnum`:
|
|
185
|
+
|
|
186
|
+
| Membro | Descrição |
|
|
187
|
+
|---------------------|-------------------------|
|
|
188
|
+
| `ASSUNTO` | Tópicos / assuntos |
|
|
189
|
+
| `CLASSIFICACAO` | Classificações |
|
|
190
|
+
| `NIVELTERRITORIAL` | Níveis territoriais |
|
|
191
|
+
| `PERIODO` | Períodos |
|
|
192
|
+
| `PERIODICIDADE` | Periodicidades |
|
|
193
|
+
| `VARIAVEL` | Variáveis |
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
### `AsyncSidraClient` (assíncrono)
|
|
198
|
+
|
|
199
|
+
Equivalente assíncrono do `SidraClient`. Todos os métodos são corrotinas. `get_agregado` busca metadados e períodos concorrentemente via `asyncio.gather`.
|
|
200
|
+
|
|
201
|
+
```python
|
|
202
|
+
import asyncio
|
|
203
|
+
from sidra_fetcher.fetcher import AsyncSidraClient
|
|
204
|
+
|
|
205
|
+
async def main():
|
|
206
|
+
async with AsyncSidraClient() as client:
|
|
207
|
+
index = await client.get_indice_pesquisas_agregados()
|
|
208
|
+
agregado = await client.get_agregado(1705)
|
|
209
|
+
print(len(agregado.periodos))
|
|
210
|
+
|
|
211
|
+
asyncio.run(main())
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## Análise de Períodos
|
|
217
|
+
|
|
218
|
+
`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.
|
|
219
|
+
|
|
220
|
+
### Campos do objeto `Periodo`
|
|
221
|
+
|
|
222
|
+
| Campo | Tipo | Descrição |
|
|
223
|
+
|---------------|-------------------|--------------------------------------------------------------|
|
|
224
|
+
| `id` | `str` | ID bruto do período da API (ex: `"202312"`) |
|
|
225
|
+
| `literals` | `list[str]` | Representações legíveis (ex: `["dezembro de 2023"]`) |
|
|
226
|
+
| `modificacao` | `dt.date` | Data da última atualização dos dados do período |
|
|
227
|
+
| `frequencia` | `str \| None` | Tipo de frequência detectado (ver tabela abaixo) |
|
|
228
|
+
| `data_inicio` | `dt.date \| None` | Primeiro dia do período |
|
|
229
|
+
| `data_fim` | `dt.date \| None` | Último dia do período |
|
|
230
|
+
| `ano` | `int \| None` | Ano |
|
|
231
|
+
| `mes` | `int \| None` | Mês (1–12); em trimestres móveis, o último mês |
|
|
232
|
+
| `trimestre` | `int \| None` | Número do trimestre (1–4) |
|
|
233
|
+
| `semestre` | `int \| None` | Número do semestre (1–2) |
|
|
234
|
+
| `ano_fim` | `int \| None` | Ano final para períodos plurianuais |
|
|
235
|
+
|
|
236
|
+
### Tipos de frequência
|
|
237
|
+
|
|
238
|
+
| `frequencia` | Exemplo de literal | Intervalo de datas |
|
|
239
|
+
|---------------------|------------------------------|-------------------------------|
|
|
240
|
+
| `mensal` | `"janeiro de 2023"` | 1 jan – 31 jan |
|
|
241
|
+
| `trimestral` | `"1º trimestre de 2023"` | 1 jan – 31 mar |
|
|
242
|
+
| `trimestre_movel` | `"jan-fev-mar 2023"` | 1 jan – 31 mar |
|
|
243
|
+
| `semestral` | `"1º semestre de 2023"` | 1 jan – 30 jun |
|
|
244
|
+
| `anual` | `"2023"` | 1 jan – 31 dez |
|
|
245
|
+
| `plurianual` | `"2020/2023"` | 1 jan 2020 – 31 dez 2023 |
|
|
246
|
+
| `nao_reconhecida` | *(sem correspondência)* | `None` / `None` |
|
|
247
|
+
|
|
248
|
+
As constantes de frequência também são importáveis:
|
|
249
|
+
|
|
250
|
+
```python
|
|
251
|
+
from sidra_fetcher.periodos import (
|
|
252
|
+
FREQUENCIA_MENSAL,
|
|
253
|
+
FREQUENCIA_TRIMESTRAL,
|
|
254
|
+
FREQUENCIA_TRIMESTRE_MOVEL,
|
|
255
|
+
FREQUENCIA_SEMESTRAL,
|
|
256
|
+
FREQUENCIA_ANUAL,
|
|
257
|
+
FREQUENCIA_PLURIANUAL,
|
|
258
|
+
FREQUENCIA_NAO_RECONHECIDA,
|
|
259
|
+
)
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
---
|
|
263
|
+
|
|
264
|
+
## Construtor de URL SIDRA
|
|
265
|
+
|
|
266
|
+
A classe `Parametro` constrói e analisa URLs de requisição SIDRA (`/values`).
|
|
267
|
+
|
|
268
|
+
```python
|
|
269
|
+
from sidra_fetcher.sidra import Parametro, Formato, Precisao
|
|
270
|
+
|
|
271
|
+
params = Parametro(
|
|
272
|
+
agregado="1705",
|
|
273
|
+
territorios={"3": ["all"]}, # todos os estados
|
|
274
|
+
variaveis=["4099"], # taxa de desemprego
|
|
275
|
+
periodos=["202301", "202302"],
|
|
276
|
+
classificacoes={"2": ["6794"]},
|
|
277
|
+
formato=Formato.A,
|
|
278
|
+
decimais={"": Precisao.M},
|
|
279
|
+
)
|
|
280
|
+
|
|
281
|
+
print(params.url())
|
|
282
|
+
# https://apisidra.ibge.gov.br/values/t/1705/n3/all/v/4099/p/202301,202302/c2/6794/h/y/f/a/d/m
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
### Parâmetros do `Parametro`
|
|
286
|
+
|
|
287
|
+
| Parâmetro | Tipo | Segmento SIDRA | Exemplo |
|
|
288
|
+
|-----------------|-----------------------------|-------------------|---------------------------------------|
|
|
289
|
+
| `agregado` | `str` | `/t/{id}` | `"1705"` |
|
|
290
|
+
| `territorios` | `dict[str, list[str]]` | `/n{nivel}/{ids}` | `{"3": ["all"]}` → `/n3/all` |
|
|
291
|
+
| `variaveis` | `list[str]` | `/v/{ids}` | `["4099", "4100"]` ou `[]` → `/v/all` |
|
|
292
|
+
| `periodos` | `list[str]` | `/p/{ids}` | `["202301"]` ou `[]` → `/p/all` |
|
|
293
|
+
| `classificacoes`| `dict[str, list[str]]` | `/c{id}/{values}` | `{"2": ["6794"]}` |
|
|
294
|
+
| `cabecalho` | `bool` | `/h/y` ou `/h/n` | `True` |
|
|
295
|
+
| `formato` | `Formato` | `/f/{code}` | `Formato.A` |
|
|
296
|
+
| `decimais` | `dict[str, Precisao]` | `/d/{precisao}` | `{"": Precisao.M}` → `/d/m` |
|
|
297
|
+
|
|
298
|
+
### Analisar uma URL SIDRA existente
|
|
299
|
+
|
|
300
|
+
```python
|
|
301
|
+
from sidra_fetcher.sidra import parameter_from_url, parse_url
|
|
302
|
+
|
|
303
|
+
url = "https://apisidra.ibge.gov.br/values/t/1705/n3/all/v/4099/p/all/h/y/f/a/d/m"
|
|
304
|
+
|
|
305
|
+
params = parameter_from_url(url)
|
|
306
|
+
print(params.agregado) # "1705"
|
|
307
|
+
print(params.territorios) # {"3": ["all"]}
|
|
308
|
+
|
|
309
|
+
parsed = parse_url(url)
|
|
310
|
+
print(parsed["aggregate"]) # "1705"
|
|
311
|
+
print(parsed["territories"]) # {"3": ["all"]}
|
|
312
|
+
print(parsed["periods"]) # ["all"]
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
---
|
|
316
|
+
|
|
317
|
+
## Utilitários de Leitura e Achatamento
|
|
318
|
+
|
|
319
|
+
### Salvar e carregar metadados de agregados
|
|
320
|
+
|
|
321
|
+
```python
|
|
322
|
+
from sidra_fetcher.reader import save_agregado, load_agregado
|
|
323
|
+
|
|
324
|
+
# Salvar em JSON
|
|
325
|
+
save_agregado(agregado, "agregado_1705.json")
|
|
326
|
+
|
|
327
|
+
# Carregar do JSON (períodos são reanalisados automaticamente)
|
|
328
|
+
agregado = load_agregado("agregado_1705.json")
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
### Achatar metadados para análise
|
|
332
|
+
|
|
333
|
+
`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:
|
|
334
|
+
|
|
335
|
+
```python
|
|
336
|
+
from sidra_fetcher.reader import flatten_aggregate_metadata
|
|
337
|
+
|
|
338
|
+
raw_meta = client.get("https://servicodados.ibge.gov.br/api/v3/agregados/1705/metadados")
|
|
339
|
+
|
|
340
|
+
for row in flatten_aggregate_metadata(raw_meta):
|
|
341
|
+
print(row["agregado"], row["D4N"], row.get("C5N"), row["MN"])
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
Cada linha contém:
|
|
345
|
+
|
|
346
|
+
| Chave | Descrição |
|
|
347
|
+
|----------------|---------------------------------------------|
|
|
348
|
+
| `agregado` | Nome do agregado |
|
|
349
|
+
| `pesquisa` | Nome da pesquisa |
|
|
350
|
+
| `assunto` | Assunto / tópico |
|
|
351
|
+
| `frequencia` | Frequência do agregado |
|
|
352
|
+
| `url_agregado` | URL do agregado |
|
|
353
|
+
| `D4C`/`D4N` | ID / nome da variável |
|
|
354
|
+
| `D5C`/`D5N` | ID / nome da primeira classificação |
|
|
355
|
+
| `C5C`/`C5N` | ID / nome da primeira categoria |
|
|
356
|
+
| `MN` | Unidade de medida |
|
|
357
|
+
| `nivel` | Nível hierárquico da categoria |
|
|
358
|
+
|
|
359
|
+
`flatten_surveys_metadata` achata o índice de pesquisas em uma lista de dicts `{pesquisa_id, pesquisa, agregado_id, agregado}`:
|
|
360
|
+
|
|
361
|
+
```python
|
|
362
|
+
from sidra_fetcher.reader import flatten_surveys_metadata
|
|
363
|
+
|
|
364
|
+
raw_index = client.get("https://servicodados.ibge.gov.br/api/v3/agregados")
|
|
365
|
+
rows = flatten_surveys_metadata(raw_index)
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
---
|
|
369
|
+
|
|
370
|
+
## Utilitários de Tamanho e Estatísticas
|
|
371
|
+
|
|
372
|
+
```python
|
|
373
|
+
from sidra_fetcher.stats import calculate_aggregate
|
|
374
|
+
|
|
375
|
+
stats = calculate_aggregate(agregado)
|
|
376
|
+
print(stats)
|
|
377
|
+
# {
|
|
378
|
+
# "pesquisa_id": "...",
|
|
379
|
+
# "agregado_id": 1705,
|
|
380
|
+
# "n_localidades": 27,
|
|
381
|
+
# "n_variaveis": 1,
|
|
382
|
+
# "n_classificacoes": 1,
|
|
383
|
+
# "n_dimensoes": 2,
|
|
384
|
+
# "n_periodos": 84,
|
|
385
|
+
# "period_size": 54, # linhas por período
|
|
386
|
+
# "total_size": 4536, # total estimado de linhas
|
|
387
|
+
# ...
|
|
388
|
+
# }
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
---
|
|
392
|
+
|
|
393
|
+
## Estrutura do Projeto
|
|
394
|
+
|
|
395
|
+
```
|
|
396
|
+
src/sidra_fetcher/
|
|
397
|
+
├── __init__.py — logger do pacote
|
|
398
|
+
├── agregados.py — dataclasses e construtores de URL para a API Agregados
|
|
399
|
+
├── fetcher.py — SidraClient e AsyncSidraClient
|
|
400
|
+
├── periodos.py — análise de strings de período e detecção de frequência
|
|
401
|
+
├── reader.py — parsers JSON → dataclass e achatamento de metadados
|
|
402
|
+
├── sidra.py — construtor de URL SIDRA (Parametro) e parsers
|
|
403
|
+
└── stats.py — estatísticas de tamanho e dimensões
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
---
|
|
407
|
+
|
|
408
|
+
## Desenvolvimento
|
|
409
|
+
|
|
410
|
+
```bash
|
|
411
|
+
git clone https://github.com/Quantilica/sidra-fetcher.git
|
|
412
|
+
cd sidra-fetcher
|
|
413
|
+
uv sync --extra dev
|
|
414
|
+
uv run ruff check src/ tests/
|
|
415
|
+
uv run ruff format src/ tests/
|
|
416
|
+
uv run python -m unittest discover -v tests
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
## Licença
|
|
420
|
+
|
|
421
|
+
MIT — veja [LICENSE](LICENSE).
|