pluvia 0.1.0__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.
Files changed (47) hide show
  1. pluvia-0.1.0/.git-cliff.toml +59 -0
  2. pluvia-0.1.0/.gitignore +223 -0
  3. pluvia-0.1.0/.pre-commit-config.yaml +27 -0
  4. pluvia-0.1.0/.vscode/settings.json +3 -0
  5. pluvia-0.1.0/CHANGELOG.md +11 -0
  6. pluvia-0.1.0/PKG-INFO +13 -0
  7. pluvia-0.1.0/README.md +136 -0
  8. pluvia-0.1.0/assets/static/logo.png +0 -0
  9. pluvia-0.1.0/pixi.lock +4241 -0
  10. pluvia-0.1.0/pyproject.toml +130 -0
  11. pluvia-0.1.0/src/pluvia/__init__.py +177 -0
  12. pluvia-0.1.0/src/pluvia/__main__.py +307 -0
  13. pluvia-0.1.0/src/pluvia/application/__init__.py +6 -0
  14. pluvia-0.1.0/src/pluvia/application/ana_service.py +575 -0
  15. pluvia-0.1.0/src/pluvia/data/shapes/uf.cpg +1 -0
  16. pluvia-0.1.0/src/pluvia/data/shapes/uf.dbf +0 -0
  17. pluvia-0.1.0/src/pluvia/data/shapes/uf.prj +1 -0
  18. pluvia-0.1.0/src/pluvia/data/shapes/uf.shp +0 -0
  19. pluvia-0.1.0/src/pluvia/data/shapes/uf.shx +0 -0
  20. pluvia-0.1.0/src/pluvia/domain/__init__.py +15 -0
  21. pluvia-0.1.0/src/pluvia/domain/entities.py +52 -0
  22. pluvia-0.1.0/src/pluvia/domain/exceptions.py +5 -0
  23. pluvia-0.1.0/src/pluvia/domain/ports.py +82 -0
  24. pluvia-0.1.0/src/pluvia/infrastructure/__init__.py +7 -0
  25. pluvia-0.1.0/src/pluvia/infrastructure/ana/__init__.py +5 -0
  26. pluvia-0.1.0/src/pluvia/infrastructure/ana/client.py +292 -0
  27. pluvia-0.1.0/src/pluvia/infrastructure/ana/constants.py +25 -0
  28. pluvia-0.1.0/src/pluvia/infrastructure/ana/parser.py +160 -0
  29. pluvia-0.1.0/src/pluvia/infrastructure/cache/__init__.py +6 -0
  30. pluvia-0.1.0/src/pluvia/infrastructure/cache/intervals.py +221 -0
  31. pluvia-0.1.0/src/pluvia/infrastructure/cache/station_cache.py +315 -0
  32. pluvia-0.1.0/src/pluvia/infrastructure/config.py +3 -0
  33. pluvia-0.1.0/src/pluvia/infrastructure/logging.py +59 -0
  34. pluvia-0.1.0/src/pluvia/infrastructure/spatial/__init__.py +5 -0
  35. pluvia-0.1.0/src/pluvia/infrastructure/spatial/spatial_extent.py +96 -0
  36. pluvia-0.1.0/tests/__init__.py +0 -0
  37. pluvia-0.1.0/tests/test_api.py +160 -0
  38. pluvia-0.1.0/tests/test_cache.py +253 -0
  39. pluvia-0.1.0/tests/test_cli.py +246 -0
  40. pluvia-0.1.0/tests/test_client.py +344 -0
  41. pluvia-0.1.0/tests/test_client_parser.py +265 -0
  42. pluvia-0.1.0/tests/test_error_handling.py +200 -0
  43. pluvia-0.1.0/tests/test_intervals.py +200 -0
  44. pluvia-0.1.0/tests/test_service_scan.py +156 -0
  45. pluvia-0.1.0/tests/test_service_stations.py +144 -0
  46. pluvia-0.1.0/tests/test_spatial.py +35 -0
  47. pluvia-0.1.0/tests/test_station.py +38 -0
@@ -0,0 +1,59 @@
1
+ # git-cliff configuration for pluvia
2
+
3
+ [changelog]
4
+ header = """
5
+ # Changelog
6
+
7
+ All notable changes to this project will be documented in this file.
8
+
9
+ """
10
+ body = """
11
+ {% if version %}\
12
+ ## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }}
13
+ {% else %}\
14
+ ## [unreleased]
15
+ {% endif %}\
16
+ {% for group, commits in commits | group_by(attribute="group") %}
17
+ ### {{ group | striptags | trim | upper_first }}
18
+ {% for commit in commits %}
19
+ - {% if commit.breaking %}[**breaking**] {% endif %}{{ commit.message | upper_first }}
20
+ {% endfor %}
21
+ {% endfor %}
22
+ """
23
+ footer = """
24
+ {% for release in releases %}
25
+ {% if release.version %}
26
+ [{{ release.version | trim_start_matches(pat="v") }}]: https://github.com/ericmiguel/pluvia/compare/{{ release.previous.version }}...{{ release.version }}
27
+ {% endif %}
28
+ {% endfor %}
29
+ """
30
+ trim = true
31
+
32
+ [git]
33
+ conventional_commits = true
34
+ filter_unconventional = true
35
+ split_commits = false
36
+ commit_preprocessors = [
37
+ { pattern = '\\(\\([0-9]+\\)\\)$', replace = "" },
38
+ ]
39
+ commit_parsers = [
40
+ { message = "^feat", group = "Features" },
41
+ { message = "^fix", group = "Bug Fixes" },
42
+ { message = "^doc", group = "Documentation" },
43
+ { message = "^docs", group = "Documentation" },
44
+ { message = "^perf", group = "Performance" },
45
+ { message = "^refactor", group = "Refactor" },
46
+ { message = "^style", group = "Styling" },
47
+ { message = "^test", group = "Testing" },
48
+ { message = "^chore\\(release\\): prepare for", skip = true },
49
+ { message = "^chore", group = "Miscellaneous Tasks" },
50
+ { body = "^.+breaking change", group = "Breaking Changes" },
51
+ ]
52
+ protect_breaking_commits = false
53
+ filter_commits = false
54
+ topology_order = false
55
+ sort_commits = "oldest"
56
+
57
+ [bump]
58
+ features_always_bump_minor = true
59
+ breaking_always_bump_major = true
@@ -0,0 +1,223 @@
1
+ .cache
2
+
3
+
4
+ # Byte-compiled / optimized / DLL files
5
+ __pycache__/
6
+ *.py[codz]
7
+ *$py.class
8
+
9
+ # C extensions
10
+ *.so
11
+
12
+ # Distribution / packaging
13
+ .Python
14
+ build/
15
+ develop-eggs/
16
+ dist/
17
+ downloads/
18
+ eggs/
19
+ .eggs/
20
+ lib/
21
+ lib64/
22
+ parts/
23
+ sdist/
24
+ var/
25
+ wheels/
26
+ share/python-wheels/
27
+ *.egg-info/
28
+ .installed.cfg
29
+ *.egg
30
+ MANIFEST
31
+
32
+ # PyInstaller
33
+ # Usually these files are written by a python script from a template
34
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
35
+ *.manifest
36
+ *.spec
37
+
38
+ # Installer logs
39
+ pip-log.txt
40
+ pip-delete-this-directory.txt
41
+
42
+ # Unit test / coverage reports
43
+ htmlcov/
44
+ .tox/
45
+ .nox/
46
+ .coverage
47
+ .coverage.*
48
+ .cache
49
+ nosetests.xml
50
+ coverage.xml
51
+ *.cover
52
+ *.py.cover
53
+ *.lcov
54
+ .hypothesis/
55
+ .pytest_cache/
56
+ cover/
57
+
58
+ # Translations
59
+ *.mo
60
+ *.pot
61
+
62
+ # Django stuff:
63
+ *.log
64
+ local_settings.py
65
+ db.sqlite3
66
+ db.sqlite3-journal
67
+
68
+ # Flask stuff:
69
+ instance/
70
+ .webassets-cache
71
+
72
+ # Scrapy stuff:
73
+ .scrapy
74
+
75
+ # Sphinx documentation
76
+ docs/_build/
77
+
78
+ # PyBuilder
79
+ .pybuilder/
80
+ target/
81
+
82
+ # Jupyter Notebook
83
+ .ipynb_checkpoints
84
+
85
+ # IPython
86
+ profile_default/
87
+ ipython_config.py
88
+
89
+ # pyenv
90
+ # For a library or package, you might want to ignore these files since the code is
91
+ # intended to run in multiple environments; otherwise, check them in:
92
+ # .python-version
93
+
94
+ # pipenv
95
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
96
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
97
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
98
+ # install all needed dependencies.
99
+ # Pipfile.lock
100
+
101
+ # UV
102
+ # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
103
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
104
+ # commonly ignored for libraries.
105
+ # uv.lock
106
+
107
+ # poetry
108
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
109
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
110
+ # commonly ignored for libraries.
111
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
112
+ # poetry.lock
113
+ # poetry.toml
114
+
115
+ # pdm
116
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
117
+ # pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
118
+ # https://pdm-project.org/en/latest/usage/project/#working-with-version-control
119
+ # pdm.lock
120
+ # pdm.toml
121
+ .pdm-python
122
+ .pdm-build/
123
+
124
+ # pixi
125
+ # Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
126
+ # pixi.lock
127
+ # Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
128
+ # in the .venv directory. It is recommended not to include this directory in version control.
129
+ .pixi/*
130
+ !.pixi/config.toml
131
+
132
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
133
+ __pypackages__/
134
+
135
+ # Celery stuff
136
+ celerybeat-schedule*
137
+ celerybeat.pid
138
+
139
+ # Redis
140
+ *.rdb
141
+ *.aof
142
+ *.pid
143
+
144
+ # RabbitMQ
145
+ mnesia/
146
+ rabbitmq/
147
+ rabbitmq-data/
148
+
149
+ # ActiveMQ
150
+ activemq-data/
151
+
152
+ # SageMath parsed files
153
+ *.sage.py
154
+
155
+ # Environments
156
+ .env
157
+ .envrc
158
+ .venv
159
+ env/
160
+ venv/
161
+ ENV/
162
+ env.bak/
163
+ venv.bak/
164
+
165
+ # Spyder project settings
166
+ .spyderproject
167
+ .spyproject
168
+
169
+ # Rope project settings
170
+ .ropeproject
171
+
172
+ # mkdocs documentation
173
+ /site
174
+
175
+ # mypy
176
+ .mypy_cache/
177
+ .dmypy.json
178
+ dmypy.json
179
+
180
+ # Pyre type checker
181
+ .pyre/
182
+
183
+ # pytype static type analyzer
184
+ .pytype/
185
+
186
+ # Cython debug symbols
187
+ cython_debug/
188
+
189
+ # PyCharm
190
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
191
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
192
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
193
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
194
+ # .idea/
195
+
196
+ # Abstra
197
+ # Abstra is an AI-powered process automation framework.
198
+ # Ignore directories containing user credentials, local state, and settings.
199
+ # Learn more at https://abstra.io/docs
200
+ .abstra/
201
+
202
+ # Visual Studio Code
203
+ # Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
204
+ # that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
205
+ # and can be added to the global gitignore or merged into this file. However, if you prefer,
206
+ # you could uncomment the following to ignore the entire vscode folder
207
+ # .vscode/
208
+ # Temporary file for partial code execution
209
+ tempCodeRunnerFile.py
210
+
211
+ # Ruff stuff:
212
+ .ruff_cache/
213
+
214
+ # PyPI configuration file
215
+ .pypirc
216
+
217
+ # Marimo
218
+ marimo/_static/
219
+ marimo/_lsp/
220
+ __marimo__/
221
+
222
+ # Streamlit
223
+ .streamlit/secrets.toml
@@ -0,0 +1,27 @@
1
+ repos:
2
+ - repo: local
3
+ hooks:
4
+ - id: ruff-check
5
+ name: ruff check
6
+ entry: pixi run -e dev ruff check src/ tests/
7
+ language: system
8
+ types: [python]
9
+ pass_filenames: false
10
+ - id: ruff-format
11
+ name: ruff format
12
+ entry: pixi run -e dev ruff format src/ tests/
13
+ language: system
14
+ types: [python]
15
+ pass_filenames: false
16
+ - id: pyrefly
17
+ name: pyrefly
18
+ entry: pixi run -e dev typecheck
19
+ language: system
20
+ types: [python]
21
+ pass_filenames: false
22
+ - id: pytest
23
+ name: pytest
24
+ entry: pixi run test
25
+ language: system
26
+ types: [python]
27
+ pass_filenames: false
@@ -0,0 +1,3 @@
1
+ {
2
+ "python-envs.defaultEnvManager": "ms-python.python:system"
3
+ }
@@ -0,0 +1,11 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ ## [0.1.0] - 2026-06-11
6
+
7
+ ### 🚀 Features
8
+
9
+ - Initial release v0.1.0
10
+
11
+ <!-- generated by git-cliff -->
pluvia-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,13 @@
1
+ Metadata-Version: 2.4
2
+ Name: pluvia
3
+ Version: 0.1.0
4
+ Summary: Catalogação de estações hidrometeorológicas da ANA
5
+ Author-email: Grenda Menezes <grenda.menezes@gmail.com>
6
+ License: MIT
7
+ Classifier: Development Status :: 4 - Beta
8
+ Classifier: Intended Audience :: Science/Research
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Topic :: Scientific/Engineering :: Hydrology
13
+ Requires-Python: >=3.11
pluvia-0.1.0/README.md ADDED
@@ -0,0 +1,136 @@
1
+ ![Pluvia logo](https://raw.githubusercontent.com/ericmiguel/pluvia/v0.1.0/assets/static/logo.png)
2
+
3
+ Cliente para coleta de dados hidrometeorológicos do Brasil.
4
+
5
+ ## Instalação
6
+
7
+ ```bash
8
+ pip install pluvia
9
+ ```
10
+
11
+ ## Como usar
12
+
13
+ ### Uso via CLI
14
+
15
+ Após a instalação, o comando `pluvia` fica disponível no PATH do seu ambiente Python.
16
+
17
+ Por conveniência, o pacote inclui contornos dos estados brasileiros (IBGE) embutidos.
18
+
19
+ ```bash
20
+ pluvia --state SP --start 2026-01-01 --end 2026-06-30 --output ./dados
21
+ ```
22
+
23
+ Para filtrar estações por qualquer limite vetorial (bacias hidrográficas, municípios, áreas de estudo etc.):
24
+
25
+ ```bash
26
+ pluvia --shapefile ./bacias.shp --shape-column codigo --shape-id 01 --output ./dados
27
+ ```
28
+
29
+ | Argumento | Descrição |
30
+ | ----------------- | -------------------------------------------------------------------------------------------- |
31
+ | `--state` | Sigla do estado brasileiro (ex: CE, SP, RJ). Obrigatório se `--shapefile` não for informado. |
32
+ | `--start` | Data de início no formato YYYY-MM-DD (padrão: ontem). |
33
+ | `--end` | Data de fim no formato YYYY-MM-DD (padrão: hoje). |
34
+ | `--output` | Diretório para salvar os dados CSV (padrão: diretório atual). |
35
+ | `--rebuild` | Ignora o cache e re-consulta todas as estações. |
36
+ | `--update-active` | Re-consulta estações ativas mesmo que o intervalo já esteja coberto (padrão: True). |
37
+ | `--shapefile` | Caminho para shapefile vetorial customizado (.shp, .gpkg, .geojson). |
38
+ | `--shape-column` | Coluna de atributo do shapefile para filtrar (padrão: `acronym`). |
39
+ | `--shape-id` | Valor do ID na coluna de atributo do shapefile. |
40
+ | `--station-type` | Tipo de estação: `fluviometrica`, `pluviometrica`, `telemetric`. |
41
+
42
+ ### Uso via API
43
+
44
+ ```python
45
+ import pluvia
46
+
47
+ client = pluvia.ANA()
48
+
49
+ # Contornos embutidos (estados brasileiros)
50
+ stations = client.get_stations(
51
+ contour="uf.shp", column="acronym", value="SP"
52
+ )
53
+
54
+ # Shapefile customizado
55
+ stations = client.get_stations(
56
+ contour="./bacias.shp", column="codigo", value="01"
57
+ )
58
+
59
+ # Filtro por tipo de estação
60
+ stations = client.get_stations(
61
+ contour="uf.shp", column="acronym", value="SP",
62
+ station_type="fluviometrica"
63
+ )
64
+
65
+ data = client.fetch_data(
66
+ stations=stations,
67
+ start="2026-01-01",
68
+ end="2026-06-30",
69
+ variable="chuva", # chuva, nivel, vazao, cota
70
+ rebuild=True, # força re-consulta completa (use na primeira execução)
71
+ update_active=True, # re-consulta estações ativas mesmo com cache válido
72
+ )
73
+ ```
74
+
75
+ ## Caching
76
+
77
+ O serviço de dados da ANA (Agência Nacional de Águas) é lento e com limitações diversas.
78
+ Para otimizar o uso dos dados, a biblioteca implementa uma estratégia de caching incremental
79
+ e orientado a intervalos.
80
+
81
+ 1. Apenas os períodos ainda não baixados são consultados na API.
82
+ 2. O inventário de estações é re-buscado apenas quando expira (padrão: 7 dias).
83
+ 3. Estações sem dados são marcadas como inativas e re-consultadas com TTL dinâmico.
84
+ 4. Erros de rede consecutivos colocam a estação em cooldown de 24 h.
85
+
86
+ O TTL dinâmico dita a frequência com que as estações são re-consultadas:
87
+
88
+ - diariamente se tiveram dados recentes
89
+ - a cada 3 dias se o último dado tem entre 30 dias e 1 ano
90
+ - semanalmente se ainda mais antigo
91
+
92
+ Essa estratégia visa reduzir tempo de coleta de dados ao mesmo tempo em que busca não
93
+ desperdiçar estações que, por eventual (milagre) voltem a operar ou que tenham sofrido
94
+ interrupções temporárias no serviço.
95
+
96
+ ## Desenvolvimento
97
+
98
+ ```bash
99
+ pixi run -e dev lint # ruff check
100
+ pixi run -e dev format # ruff format
101
+ pixi run -e dev typecheck # pyrefly
102
+ pixi run test # pytest
103
+ ```
104
+
105
+ ### Build e publicação no PyPI
106
+
107
+ O projeto usa [Conventional Commits](https://www.conventionalcommits.org/) e versionamento
108
+ semântico automatizado com `bump-my-version`. O changelog é gerado automaticamente com
109
+ `git-cliff` a partir dos commits seguindo Conventional Commits.
110
+
111
+ Configure um token em [pypi.org/manage/account/token](https://pypi.org/manage/account/token/) e salve em `~/.pypirc`.
112
+
113
+ ```ini
114
+ # ~/.pypirc
115
+ [pypi]
116
+ username = __token__
117
+ password = pypi-xxxxxxxxxxxx
118
+ ```
119
+
120
+ Siga o fluxo para release de uma nova versão:
121
+
122
+ ```bash
123
+ # 1. Atualizar versão (cria tag automaticamente)
124
+ pixi run -e dev bump # patch
125
+ pixi run -e dev bump minor # minor
126
+ pixi run -e dev bump major # major
127
+
128
+ # 2. Atualizar changelog
129
+ pixi run -e dev changelog
130
+
131
+ # 3. Build
132
+ pixi run -e dev build
133
+
134
+ # 4. Publicar (requer API token no PyPI)
135
+ pixi run -e dev publish
136
+ ```
Binary file