worldbank-commodities 0.5.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.
- worldbank_commodities-0.5.0/.github/workflows/ci.yml +52 -0
- worldbank_commodities-0.5.0/.github/workflows/publish.yml +26 -0
- worldbank_commodities-0.5.0/.gitignore +34 -0
- worldbank_commodities-0.5.0/.pre-commit-config.yaml +32 -0
- worldbank_commodities-0.5.0/CHANGELOG.md +133 -0
- worldbank_commodities-0.5.0/CITATION.cff +32 -0
- worldbank_commodities-0.5.0/LICENSE +21 -0
- worldbank_commodities-0.5.0/PKG-INFO +381 -0
- worldbank_commodities-0.5.0/README.md +363 -0
- worldbank_commodities-0.5.0/examples/incremental.py +67 -0
- worldbank_commodities-0.5.0/pyproject.toml +229 -0
- worldbank_commodities-0.5.0/src/worldbank_commodities/__init__.py +21 -0
- worldbank_commodities-0.5.0/src/worldbank_commodities/__main__.py +15 -0
- worldbank_commodities-0.5.0/src/worldbank_commodities/core.py +1206 -0
- worldbank_commodities-0.5.0/src/worldbank_commodities/py.typed +0 -0
- worldbank_commodities-0.5.0/tests/test_worldbank_commodities.py +679 -0
- worldbank_commodities-0.5.0/uv.lock +1473 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
quality:
|
|
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
|
+
with:
|
|
18
|
+
enable-cache: true
|
|
19
|
+
|
|
20
|
+
- name: Set up Python
|
|
21
|
+
run: uv python install 3.10
|
|
22
|
+
|
|
23
|
+
- name: Install dependencies
|
|
24
|
+
run: uv sync
|
|
25
|
+
|
|
26
|
+
- name: Ruff lint
|
|
27
|
+
run: uv run ruff check --output-format=github .
|
|
28
|
+
|
|
29
|
+
- name: Ruff format check
|
|
30
|
+
run: uv run ruff format --check .
|
|
31
|
+
|
|
32
|
+
- name: Codespell
|
|
33
|
+
run: uv run codespell src tests README.md CHANGELOG.md
|
|
34
|
+
|
|
35
|
+
- name: Deptry
|
|
36
|
+
run: uv run deptry src
|
|
37
|
+
|
|
38
|
+
- name: Docstring coverage (interrogate)
|
|
39
|
+
run: uv run interrogate -c pyproject.toml src tests
|
|
40
|
+
|
|
41
|
+
- name: Type check (mypy)
|
|
42
|
+
run: uv run mypy
|
|
43
|
+
|
|
44
|
+
- name: Tests
|
|
45
|
+
run: uv run pytest --cov-report=xml
|
|
46
|
+
|
|
47
|
+
- name: Upload coverage to Codecov
|
|
48
|
+
uses: codecov/codecov-action@v5
|
|
49
|
+
with:
|
|
50
|
+
token: ${{ secrets.CODECOV_TOKEN }}
|
|
51
|
+
files: ./coverage.xml
|
|
52
|
+
fail_ci_if_error: false
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
name: Publish
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
id-token: write # required for PyPI Trusted Publishing (OIDC)
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
pypi:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
environment: pypi
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- name: Install uv
|
|
20
|
+
uses: astral-sh/setup-uv@v5
|
|
21
|
+
|
|
22
|
+
- name: Build
|
|
23
|
+
run: uv build
|
|
24
|
+
|
|
25
|
+
- name: Publish to PyPI
|
|
26
|
+
run: uv publish
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.egg-info/
|
|
5
|
+
.venv/
|
|
6
|
+
venv/
|
|
7
|
+
.env
|
|
8
|
+
|
|
9
|
+
# Build artifacts
|
|
10
|
+
dist/
|
|
11
|
+
build/
|
|
12
|
+
|
|
13
|
+
# Tooling caches / reports
|
|
14
|
+
.pytest_cache/
|
|
15
|
+
.mypy_cache/
|
|
16
|
+
.ruff_cache/
|
|
17
|
+
.coverage
|
|
18
|
+
.coverage.*
|
|
19
|
+
coverage.xml
|
|
20
|
+
htmlcov/
|
|
21
|
+
|
|
22
|
+
# Local cache of downloaded World Bank workbooks
|
|
23
|
+
.cache/
|
|
24
|
+
*.xlsx
|
|
25
|
+
*.xls
|
|
26
|
+
|
|
27
|
+
# Extracted data outputs (re-downloadable via the wrapper)
|
|
28
|
+
wb_commodities_*.csv
|
|
29
|
+
wb_commodities_*.xlsx
|
|
30
|
+
|
|
31
|
+
# OS / editors
|
|
32
|
+
.DS_Store
|
|
33
|
+
.idea/
|
|
34
|
+
.vscode/
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
3
|
+
rev: v6.0.0
|
|
4
|
+
hooks:
|
|
5
|
+
- id: trailing-whitespace
|
|
6
|
+
- id: end-of-file-fixer
|
|
7
|
+
- id: check-yaml
|
|
8
|
+
- id: check-toml
|
|
9
|
+
- id: check-added-large-files
|
|
10
|
+
args: ["--maxkb=1024"]
|
|
11
|
+
|
|
12
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
13
|
+
rev: v0.16.1
|
|
14
|
+
hooks:
|
|
15
|
+
- id: ruff-check
|
|
16
|
+
args: ["--fix"]
|
|
17
|
+
- id: ruff-format
|
|
18
|
+
|
|
19
|
+
- repo: https://github.com/codespell-project/codespell
|
|
20
|
+
rev: v2.4.1
|
|
21
|
+
hooks:
|
|
22
|
+
- id: codespell
|
|
23
|
+
additional_dependencies: ["tomli"]
|
|
24
|
+
|
|
25
|
+
- repo: https://github.com/pre-commit/mirrors-mypy
|
|
26
|
+
rev: v1.18.2
|
|
27
|
+
hooks:
|
|
28
|
+
- id: mypy
|
|
29
|
+
additional_dependencies:
|
|
30
|
+
- pandas-stubs
|
|
31
|
+
- types-openpyxl
|
|
32
|
+
- types-requests
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.5.0] - 2026-08-01
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- Wide output now includes a leading `mdates` column (monthly frequency only),
|
|
15
|
+
so wide CSV/Excel extracts also carry the Stata monthly id
|
|
16
|
+
([#11](https://github.com/hmorao95/worldbank-commodities/issues/11)).
|
|
17
|
+
|
|
18
|
+
## [0.4.1] - 2026-08-01
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
|
|
22
|
+
- `mdates` is now added only for the monthly frequency. On annual data it was a
|
|
23
|
+
misleading `<year>m1` for every row; annual output omits the column
|
|
24
|
+
([#9](https://github.com/hmorao95/worldbank-commodities/issues/9)).
|
|
25
|
+
- CLI `get-prices --out` routes by file extension, so `--out data.xlsx` writes a
|
|
26
|
+
real Excel workbook instead of CSV content under an `.xlsx` name
|
|
27
|
+
([#9](https://github.com/hmorao95/worldbank-commodities/issues/9)).
|
|
28
|
+
|
|
29
|
+
## [0.4.0] - 2026-08-01
|
|
30
|
+
|
|
31
|
+
### Added
|
|
32
|
+
|
|
33
|
+
- Long output now includes an `mdates` column, a Stata-style monthly id such as
|
|
34
|
+
`1960m1` (lowercase `m`, no zero-padding), for merging with Stata series
|
|
35
|
+
([#7](https://github.com/hmorao95/worldbank-commodities/issues/7)).
|
|
36
|
+
|
|
37
|
+
### Fixed
|
|
38
|
+
|
|
39
|
+
- `to_excel` writes dates without a time component, so Excel shows `1960-01-01`
|
|
40
|
+
rather than `1960-01-01 00:00:00`
|
|
41
|
+
([#7](https://github.com/hmorao95/worldbank-commodities/issues/7)).
|
|
42
|
+
|
|
43
|
+
## [0.3.0] - 2026-08-01
|
|
44
|
+
|
|
45
|
+
### Added
|
|
46
|
+
|
|
47
|
+
- `to_excel()` and the CLI `to-excel` subcommand write prices to an Excel
|
|
48
|
+
(`.xlsx`) workbook, mirroring `to_csv`
|
|
49
|
+
([#3](https://github.com/hmorao95/worldbank-commodities/issues/3)).
|
|
50
|
+
|
|
51
|
+
## [0.2.1] - 2026-08-01
|
|
52
|
+
|
|
53
|
+
### Fixed
|
|
54
|
+
|
|
55
|
+
- `get_prices` now accepts a single commodity name as a plain string. Previously
|
|
56
|
+
a string filter was iterated character-by-character and matched essentially
|
|
57
|
+
every commodity; a non-matching string now raises `ValueError` as expected
|
|
58
|
+
([#1](https://github.com/hmorao95/worldbank-commodities/issues/1)).
|
|
59
|
+
- The CLI prints a concise `Error: ...` line and exits 1 for expected errors
|
|
60
|
+
(unknown commodity or frequency, changed page layout, malformed CSV) instead
|
|
61
|
+
of dumping a full Python traceback.
|
|
62
|
+
|
|
63
|
+
## [0.2.0] - 2026-08-01
|
|
64
|
+
|
|
65
|
+
### Changed
|
|
66
|
+
|
|
67
|
+
- The command-line interface is now generated from the library with
|
|
68
|
+
[python-fire](https://github.com/google/python-fire): each operation is a
|
|
69
|
+
subcommand (`list-commodities`, `get-prices`, `to-csv`, `update-csv`,
|
|
70
|
+
`new-observations`) with flags derived from the method signatures, replacing
|
|
71
|
+
the hand-written argparse flags. **Breaking**: `--list`, `--out`, `--update`
|
|
72
|
+
and the other old flags are gone; see the README for the new syntax.
|
|
73
|
+
|
|
74
|
+
### Fixed
|
|
75
|
+
|
|
76
|
+
- Removed the fixed mypy `python_version = "3.10"` so recent numpy/pandas stubs
|
|
77
|
+
that use PEP 695 `type` syntax type-check on Python 3.12+.
|
|
78
|
+
|
|
79
|
+
### Documentation
|
|
80
|
+
|
|
81
|
+
- Rewrote module, class, method and inline docstrings/comments in a fuller,
|
|
82
|
+
fully-explained style (typed Args/Returns/Raises and per-step commentary).
|
|
83
|
+
|
|
84
|
+
## [0.1.0] - 2026-08-01
|
|
85
|
+
|
|
86
|
+
### Added
|
|
87
|
+
|
|
88
|
+
- `WorldBankCommodities` client for the World Bank "Pink Sheet" (Commodity
|
|
89
|
+
Markets) price data, with automatic discovery of the current monthly/annual
|
|
90
|
+
workbook URLs (which carry a monthly-changing hash).
|
|
91
|
+
- `get_prices()` — tidy long or wide DataFrames, with case-insensitive
|
|
92
|
+
substring filtering by commodity and inclusive `start`/`end` date bounds.
|
|
93
|
+
- `list_commodities()` — catalog of the 71 available series and their units.
|
|
94
|
+
- `to_csv()` — one-liner extract to a CSV file.
|
|
95
|
+
- `update_csv()` — incremental updates that upsert on `(commodity, date)`,
|
|
96
|
+
appending new observations and overwriting values the World Bank later
|
|
97
|
+
revises.
|
|
98
|
+
- `new_observations()` — file-free incremental helper: given an already-extracted
|
|
99
|
+
long DataFrame (or long-CSV path), returns only the rows you are missing
|
|
100
|
+
(newer dates and never-seen commodities), with an `include_revisions` toggle.
|
|
101
|
+
It is the shared building block behind `update_csv()`.
|
|
102
|
+
- `examples/incremental.py` — runnable, inline-commented walkthrough of the
|
|
103
|
+
incremental extraction scenarios.
|
|
104
|
+
- On-disk caching of the downloaded workbooks (24 h TTL) plus in-process
|
|
105
|
+
memoisation.
|
|
106
|
+
- Command-line interface (`worldbank-commodities` / `python -m
|
|
107
|
+
worldbank_commodities`) with `--list`, `--freq`, `--commodity`, `--start`,
|
|
108
|
+
`--end`, `--wide`, `--out`, `--update` and `--no-cache`.
|
|
109
|
+
- `src/` package layout, `py.typed` marker, and a network-mocked pytest suite
|
|
110
|
+
(38 tests, 96% coverage).
|
|
111
|
+
- Tooling: uv project config, strict ruff lint/format, mypy `--strict`,
|
|
112
|
+
deptry, interrogate (docstring coverage), codespell, pre-commit hooks, and a
|
|
113
|
+
GitHub Actions CI workflow.
|
|
114
|
+
|
|
115
|
+
### Fixed
|
|
116
|
+
|
|
117
|
+
- `update_csv` now detects and applies World Bank **revisions** to
|
|
118
|
+
already-stored months instead of only appending strictly-newer rows.
|
|
119
|
+
- `get_prices(wide=True)` uses `pivot` so a duplicate `(date, commodity)` key
|
|
120
|
+
raises loudly instead of being silently averaged.
|
|
121
|
+
- `discover_urls` selects workbook links deterministically (prefers the
|
|
122
|
+
`Historical` workbook) rather than relying on set iteration order.
|
|
123
|
+
- `update_csv` validates that the target file is in the long format and raises
|
|
124
|
+
a clear error for wide CSVs.
|
|
125
|
+
|
|
126
|
+
[Unreleased]: https://github.com/hmorao95/worldbank-commodities/compare/v0.5.0...HEAD
|
|
127
|
+
[0.5.0]: https://github.com/hmorao95/worldbank-commodities/compare/v0.4.1...v0.5.0
|
|
128
|
+
[0.4.1]: https://github.com/hmorao95/worldbank-commodities/compare/v0.4.0...v0.4.1
|
|
129
|
+
[0.4.0]: https://github.com/hmorao95/worldbank-commodities/compare/v0.3.0...v0.4.0
|
|
130
|
+
[0.3.0]: https://github.com/hmorao95/worldbank-commodities/compare/v0.2.1...v0.3.0
|
|
131
|
+
[0.2.1]: https://github.com/hmorao95/worldbank-commodities/compare/v0.2.0...v0.2.1
|
|
132
|
+
[0.2.0]: https://github.com/hmorao95/worldbank-commodities/compare/v0.1.0...v0.2.0
|
|
133
|
+
[0.1.0]: https://github.com/hmorao95/worldbank-commodities/releases/tag/v0.1.0
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
cff-version: 1.2.0
|
|
2
|
+
message: "If you use this software, please cite it using these metadata."
|
|
3
|
+
title: "worldbank-commodities"
|
|
4
|
+
abstract: >-
|
|
5
|
+
A small Python wrapper to extract World Bank "Pink Sheet" (Commodity Markets)
|
|
6
|
+
commodity price data — crude oil, natural gas, coal, metals, fertilizers and
|
|
7
|
+
agricultural products — as tidy pandas DataFrames.
|
|
8
|
+
type: software
|
|
9
|
+
authors:
|
|
10
|
+
- family-names: "Morão"
|
|
11
|
+
given-names: "Hugo"
|
|
12
|
+
email: "hfmorao@gmail.com"
|
|
13
|
+
version: "0.5.0"
|
|
14
|
+
date-released: "2026-08-01"
|
|
15
|
+
license: MIT
|
|
16
|
+
repository-code: "https://github.com/hmorao95/worldbank-commodities"
|
|
17
|
+
url: "https://github.com/hmorao95/worldbank-commodities"
|
|
18
|
+
keywords:
|
|
19
|
+
- world-bank
|
|
20
|
+
- commodities
|
|
21
|
+
- pink-sheet
|
|
22
|
+
- prices
|
|
23
|
+
- energy
|
|
24
|
+
- oil
|
|
25
|
+
- python
|
|
26
|
+
references:
|
|
27
|
+
- type: data
|
|
28
|
+
title: "World Bank Commodity Price Data (The Pink Sheet)"
|
|
29
|
+
authors:
|
|
30
|
+
- name: "The World Bank"
|
|
31
|
+
url: "https://www.worldbank.org/en/research/commodity-markets"
|
|
32
|
+
notes: "Underlying commodity price data, licensed CC BY 4.0."
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Hugo Morão
|
|
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.
|