hdx-python-country 4.2.3__tar.gz → 4.2.5__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.
- {hdx_python_country-4.2.3 → hdx_python_country-4.2.5}/PKG-INFO +26 -12
- {hdx_python_country-4.2.3 → hdx_python_country-4.2.5}/README.md +24 -10
- {hdx_python_country-4.2.3 → hdx_python_country-4.2.5}/documentation/index.md +8 -8
- {hdx_python_country-4.2.3 → hdx_python_country-4.2.5}/pyproject.toml +5 -4
- {hdx_python_country-4.2.3 → hdx_python_country-4.2.5}/src/hdx/location/_version.py +2 -2
- {hdx_python_country-4.2.3 → hdx_python_country-4.2.5}/src/hdx/location/adminlevel.py +3 -8
- {hdx_python_country-4.2.3 → hdx_python_country-4.2.5}/tests/hdx/location/test_adminlevel.py +0 -26
- hdx_python_country-4.2.5/uv.lock +2671 -0
- hdx_python_country-4.2.3/uv.lock +0 -2063
- {hdx_python_country-4.2.3 → hdx_python_country-4.2.5}/.github/workflows/publish.yaml +0 -0
- {hdx_python_country-4.2.3 → hdx_python_country-4.2.5}/.github/workflows/run-python-tests.yaml +0 -0
- {hdx_python_country-4.2.3 → hdx_python_country-4.2.5}/.gitignore +0 -0
- {hdx_python_country-4.2.3 → hdx_python_country-4.2.5}/.pre-commit-config.yaml +0 -0
- {hdx_python_country-4.2.3 → hdx_python_country-4.2.5}/LICENSE +0 -0
- {hdx_python_country-4.2.3 → hdx_python_country-4.2.5}/documentation/.readthedocs.yaml +0 -0
- {hdx_python_country-4.2.3 → hdx_python_country-4.2.5}/documentation/mkdocs.yaml +0 -0
- {hdx_python_country-4.2.3 → hdx_python_country-4.2.5}/src/hdx/location/Countries & Territories Taxonomy MVP - C&T Taxonomy.csv +0 -0
- {hdx_python_country-4.2.3 → hdx_python_country-4.2.5}/src/hdx/location/__init__.py +0 -0
- {hdx_python_country-4.2.3 → hdx_python_country-4.2.5}/src/hdx/location/country.py +0 -0
- {hdx_python_country-4.2.3 → hdx_python_country-4.2.5}/src/hdx/location/currency.py +0 -0
- {hdx_python_country-4.2.3 → hdx_python_country-4.2.5}/src/hdx/location/int_timestamp.py +0 -0
- {hdx_python_country-4.2.3 → hdx_python_country-4.2.5}/src/hdx/location/wfp_api.py +0 -0
- {hdx_python_country-4.2.3 → hdx_python_country-4.2.5}/src/hdx/location/wfp_exchangerates.py +0 -0
- {hdx_python_country-4.2.3 → hdx_python_country-4.2.5}/tests/fixtures/adminlevel.yaml +0 -0
- {hdx_python_country-4.2.3 → hdx_python_country-4.2.5}/tests/fixtures/adminlevelparent.yaml +0 -0
- {hdx_python_country-4.2.3 → hdx_python_country-4.2.5}/tests/fixtures/fixtures-download-global-pcode-lengths.csv +0 -0
- {hdx_python_country-4.2.3 → hdx_python_country-4.2.5}/tests/fixtures/fixtures-download-global-pcodes-adm-1-2.csv +0 -0
- {hdx_python_country-4.2.3 → hdx_python_country-4.2.5}/tests/fixtures/secondary_historic_rates.csv +0 -0
- {hdx_python_country-4.2.3 → hdx_python_country-4.2.5}/tests/fixtures/secondary_rates.json +0 -0
- {hdx_python_country-4.2.3 → hdx_python_country-4.2.5}/tests/fixtures/wfp/Currency_List_1.json +0 -0
- {hdx_python_country-4.2.3 → hdx_python_country-4.2.5}/tests/fixtures/wfp/Currency_List_2.json +0 -0
- {hdx_python_country-4.2.3 → hdx_python_country-4.2.5}/tests/fixtures/wfp/Currency_UsdIndirectQuotation_1.json +0 -0
- {hdx_python_country-4.2.3 → hdx_python_country-4.2.5}/tests/fixtures/wfp/Currency_UsdIndirectQuotation_10.json +0 -0
- {hdx_python_country-4.2.3 → hdx_python_country-4.2.5}/tests/fixtures/wfp/Currency_UsdIndirectQuotation_2.json +0 -0
- {hdx_python_country-4.2.3 → hdx_python_country-4.2.5}/tests/fixtures/wfp/Currency_UsdIndirectQuotation_3.json +0 -0
- {hdx_python_country-4.2.3 → hdx_python_country-4.2.5}/tests/fixtures/wfp/Currency_UsdIndirectQuotation_4.json +0 -0
- {hdx_python_country-4.2.3 → hdx_python_country-4.2.5}/tests/fixtures/wfp/Currency_UsdIndirectQuotation_5.json +0 -0
- {hdx_python_country-4.2.3 → hdx_python_country-4.2.5}/tests/fixtures/wfp/Currency_UsdIndirectQuotation_6.json +0 -0
- {hdx_python_country-4.2.3 → hdx_python_country-4.2.5}/tests/fixtures/wfp/Currency_UsdIndirectQuotation_7.json +0 -0
- {hdx_python_country-4.2.3 → hdx_python_country-4.2.5}/tests/fixtures/wfp/Currency_UsdIndirectQuotation_8.json +0 -0
- {hdx_python_country-4.2.3 → hdx_python_country-4.2.5}/tests/fixtures/wfp/Currency_UsdIndirectQuotation_9.json +0 -0
- {hdx_python_country-4.2.3 → hdx_python_country-4.2.5}/tests/fixtures/wfp/Markets_List_AFG_1.json +0 -0
- {hdx_python_country-4.2.3 → hdx_python_country-4.2.5}/tests/fixtures/wfp/Markets_List_AFG_2.json +0 -0
- {hdx_python_country-4.2.3 → hdx_python_country-4.2.5}/tests/hdx/location/Countries_UZB_Deleted.csv +0 -0
- {hdx_python_country-4.2.3 → hdx_python_country-4.2.5}/tests/hdx/location/__init__.py +0 -0
- {hdx_python_country-4.2.3 → hdx_python_country-4.2.5}/tests/hdx/location/conftest.py +0 -0
- {hdx_python_country-4.2.3 → hdx_python_country-4.2.5}/tests/hdx/location/test_country.py +0 -0
- {hdx_python_country-4.2.3 → hdx_python_country-4.2.5}/tests/hdx/location/test_currency.py +0 -0
- {hdx_python_country-4.2.3 → hdx_python_country-4.2.5}/tests/hdx/location/test_wfp_exchangerates.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: hdx-python-country
|
|
3
|
-
Version: 4.2.
|
|
3
|
+
Version: 4.2.5
|
|
4
4
|
Summary: HDX Python country code and exchange rate (fx) utilities
|
|
5
5
|
Project-URL: Homepage, https://github.com/OCHA-DAP/hdx-python-country
|
|
6
6
|
Project-URL: Repository, https://github.com/OCHA-DAP/hdx-python-country
|
|
@@ -27,7 +27,7 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
27
27
|
Classifier: Programming Language :: Python :: 3.14
|
|
28
28
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
29
29
|
Requires-Python: >=3.10
|
|
30
|
-
Requires-Dist: hdx-python-utilities<5,>=4.2.
|
|
30
|
+
Requires-Dist: hdx-python-utilities<5,>=4.2.4
|
|
31
31
|
Requires-Dist: tenacity
|
|
32
32
|
Provides-Extra: docs
|
|
33
33
|
Requires-Dist: mkapi; extra == 'docs'
|
|
@@ -55,7 +55,7 @@ fuzzy matching for English look up that can handle abbreviations in country name
|
|
|
55
55
|
Dem. for Democratic and Rep. for Republic.
|
|
56
56
|
|
|
57
57
|
Mapping administration level names from a source to a given base set is also handled
|
|
58
|
-
including
|
|
58
|
+
including fuzzy name matching.
|
|
59
59
|
|
|
60
60
|
It also provides foreign exchange rates and conversion from amounts in local
|
|
61
61
|
currency to USD and vice-versa. The conversion relies on Yahoo Finance, falling
|
|
@@ -146,24 +146,38 @@ documentation at `documentation/index.md`.
|
|
|
146
146
|
## WFP DataBridges Client
|
|
147
147
|
|
|
148
148
|
The `WFPAPI` class (`hdx.location.wfp_api`) uses WFP's `data-bridges-client` library, which is
|
|
149
|
-
published on WFP's own package index rather than PyPI.
|
|
150
|
-
|
|
149
|
+
published on WFP's own package index rather than PyPI. That index hosts only
|
|
150
|
+
`data-bridges-client`, so install it from there first without dependencies, then install the
|
|
151
|
+
`wfp` extra from PyPI:
|
|
151
152
|
|
|
152
153
|
```shell
|
|
153
|
-
pip install "
|
|
154
|
-
--
|
|
155
|
-
|
|
154
|
+
pip install "data-bridges-client>=9,<10" --no-deps \
|
|
155
|
+
--index-url https://d2i4vvypvg40rv.cloudfront.net/pypi/
|
|
156
|
+
pip install "hdx-python-country[wfp]"
|
|
156
157
|
```
|
|
157
158
|
|
|
158
|
-
|
|
159
|
+
Avoid `--extra-index-url`: pip then picks the highest version from either index, so a package
|
|
160
|
+
published on PyPI under the name `data-bridges-client` would be installed instead.
|
|
161
|
+
|
|
162
|
+
If using `uv`, add the following to your project's `pyproject.toml` so that only
|
|
163
|
+
`data-bridges-client` is fetched from WFP's index. `data-bridges-client` must be a direct
|
|
164
|
+
dependency because `tool.uv.sources` does not apply to transitive dependencies; without it, uv
|
|
165
|
+
falls back to an old `hdx-python-country` that has no `wfp` extra:
|
|
159
166
|
|
|
160
167
|
```toml
|
|
161
|
-
[
|
|
162
|
-
|
|
168
|
+
[project]
|
|
169
|
+
dependencies = [
|
|
170
|
+
"hdx-python-country[wfp]",
|
|
171
|
+
"data-bridges-client>=9,<10",
|
|
172
|
+
]
|
|
163
173
|
|
|
164
174
|
[[tool.uv.index]]
|
|
165
175
|
name = "wfp"
|
|
166
176
|
url = "https://d2i4vvypvg40rv.cloudfront.net/pypi/"
|
|
177
|
+
explicit = true
|
|
178
|
+
|
|
179
|
+
[tool.uv.sources]
|
|
180
|
+
data-bridges-client = { index = "wfp" }
|
|
167
181
|
```
|
|
168
182
|
|
|
169
|
-
then run `uv sync
|
|
183
|
+
then run `uv sync`.
|
|
@@ -18,7 +18,7 @@ fuzzy matching for English look up that can handle abbreviations in country name
|
|
|
18
18
|
Dem. for Democratic and Rep. for Republic.
|
|
19
19
|
|
|
20
20
|
Mapping administration level names from a source to a given base set is also handled
|
|
21
|
-
including
|
|
21
|
+
including fuzzy name matching.
|
|
22
22
|
|
|
23
23
|
It also provides foreign exchange rates and conversion from amounts in local
|
|
24
24
|
currency to USD and vice-versa. The conversion relies on Yahoo Finance, falling
|
|
@@ -109,24 +109,38 @@ documentation at `documentation/index.md`.
|
|
|
109
109
|
## WFP DataBridges Client
|
|
110
110
|
|
|
111
111
|
The `WFPAPI` class (`hdx.location.wfp_api`) uses WFP's `data-bridges-client` library, which is
|
|
112
|
-
published on WFP's own package index rather than PyPI.
|
|
113
|
-
|
|
112
|
+
published on WFP's own package index rather than PyPI. That index hosts only
|
|
113
|
+
`data-bridges-client`, so install it from there first without dependencies, then install the
|
|
114
|
+
`wfp` extra from PyPI:
|
|
114
115
|
|
|
115
116
|
```shell
|
|
116
|
-
pip install "
|
|
117
|
-
--
|
|
118
|
-
|
|
117
|
+
pip install "data-bridges-client>=9,<10" --no-deps \
|
|
118
|
+
--index-url https://d2i4vvypvg40rv.cloudfront.net/pypi/
|
|
119
|
+
pip install "hdx-python-country[wfp]"
|
|
119
120
|
```
|
|
120
121
|
|
|
121
|
-
|
|
122
|
+
Avoid `--extra-index-url`: pip then picks the highest version from either index, so a package
|
|
123
|
+
published on PyPI under the name `data-bridges-client` would be installed instead.
|
|
124
|
+
|
|
125
|
+
If using `uv`, add the following to your project's `pyproject.toml` so that only
|
|
126
|
+
`data-bridges-client` is fetched from WFP's index. `data-bridges-client` must be a direct
|
|
127
|
+
dependency because `tool.uv.sources` does not apply to transitive dependencies; without it, uv
|
|
128
|
+
falls back to an old `hdx-python-country` that has no `wfp` extra:
|
|
122
129
|
|
|
123
130
|
```toml
|
|
124
|
-
[
|
|
125
|
-
|
|
131
|
+
[project]
|
|
132
|
+
dependencies = [
|
|
133
|
+
"hdx-python-country[wfp]",
|
|
134
|
+
"data-bridges-client>=9,<10",
|
|
135
|
+
]
|
|
126
136
|
|
|
127
137
|
[[tool.uv.index]]
|
|
128
138
|
name = "wfp"
|
|
129
139
|
url = "https://d2i4vvypvg40rv.cloudfront.net/pypi/"
|
|
140
|
+
explicit = true
|
|
141
|
+
|
|
142
|
+
[tool.uv.sources]
|
|
143
|
+
data-bridges-client = { index = "wfp" }
|
|
130
144
|
```
|
|
131
145
|
|
|
132
|
-
then run `uv sync
|
|
146
|
+
then run `uv sync`.
|
|
@@ -42,11 +42,13 @@ The code for the library is [here](https://github.com/OCHA-DAP/hdx-python-countr
|
|
|
42
42
|
The library has detailed API documentation which can be found in the menu at the top.
|
|
43
43
|
|
|
44
44
|
## Breaking Changes
|
|
45
|
+
From 4.2.4, the AdminLevel matcher parameter is removed and HDX Python Utilities
|
|
46
|
+
4.2.3 or later is required.
|
|
47
|
+
|
|
45
48
|
From 4.2.0, AdminLevel fuzzy matches using RapidFuzzMatcher (with its place_name_scorer)
|
|
46
|
-
from HDX Python Utilities rather than Phonetics by default.
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
parent is "" as well as when it is None.
|
|
49
|
+
from HDX Python Utilities rather than Phonetics by default. Names made of parts are
|
|
50
|
+
resolved from their parts and lists of names are not fuzzy matched (see Administration
|
|
51
|
+
Level). Fuzzy matching is now tried when parent is "" as well as when it is None.
|
|
50
52
|
|
|
51
53
|
From 4.1.1, HXL hashtags no longer used in AdminLevel class. The header names are used
|
|
52
54
|
instead. setup_from_iterable replaces setup_from_admin_info and
|
|
@@ -167,9 +169,8 @@ A Retrieve object can be passed in the *retriever* parameter that enables
|
|
|
167
169
|
saving data downloaded to a file or loading previously saved data depending
|
|
168
170
|
on how the Retrieve object is configured.
|
|
169
171
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
from HDX Python Utilities can be passed instead.
|
|
172
|
+
Fuzzy name matching uses RapidFuzzMatcher from HDX Python Utilities with its
|
|
173
|
+
place_name_scorer.
|
|
173
174
|
|
|
174
175
|
Before fuzzy matching, a name made of parts split by separators (",", ";", "/",
|
|
175
176
|
":", "&", newline, "and", "et") or a hyphen is resolved from its parts. A name
|
|
@@ -212,7 +213,6 @@ Examples of usage:
|
|
|
212
213
|
assert admintwo.get_pcode("AFG", "Kabul", parent="AF01") == ("AF0101", True)
|
|
213
214
|
adminlevel.get_pcode("KHM", "Kampot & Kep") # returns (None, False)
|
|
214
215
|
admintwo.get_pcode("VEN", "Falcón, Acosta", parent="VE11") # returns ("VE1101", False)
|
|
215
|
-
adminlevel = AdminLevel(config, matcher=Phonetics()) # use Phonetics
|
|
216
216
|
|
|
217
217
|
There is basic admin 1 p-code length conversion by default. A more advanced
|
|
218
218
|
p-code length conversion can be activated by calling *load_pcode_formats*
|
|
@@ -36,7 +36,7 @@ dynamic = ["version"]
|
|
|
36
36
|
requires-python = ">=3.10"
|
|
37
37
|
|
|
38
38
|
dependencies = [
|
|
39
|
-
"hdx-python-utilities>=4.2.
|
|
39
|
+
"hdx-python-utilities>=4.2.4,<5",
|
|
40
40
|
"tenacity",
|
|
41
41
|
]
|
|
42
42
|
|
|
@@ -82,12 +82,13 @@ allow-direct-references = true
|
|
|
82
82
|
# uv (Package Management)
|
|
83
83
|
# ----------------------------------------------------------------------------
|
|
84
84
|
|
|
85
|
-
[tool.uv]
|
|
86
|
-
index-strategy = "unsafe-best-match"
|
|
87
|
-
|
|
88
85
|
[[tool.uv.index]]
|
|
89
86
|
name = "wfp"
|
|
90
87
|
url = "https://d2i4vvypvg40rv.cloudfront.net/pypi/"
|
|
88
|
+
explicit = true
|
|
89
|
+
|
|
90
|
+
[tool.uv.sources]
|
|
91
|
+
data-bridges-client = { index = "wfp" }
|
|
91
92
|
|
|
92
93
|
# ----------------------------------------------------------------------------
|
|
93
94
|
# Ruff (Linting & Formatting)
|
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '4.2.
|
|
22
|
-
__version_tuple__ = version_tuple = (4, 2,
|
|
21
|
+
__version__ = version = '4.2.5'
|
|
22
|
+
__version_tuple__ = version_tuple = (4, 2, 5)
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -6,7 +6,6 @@ from typing import Any
|
|
|
6
6
|
|
|
7
7
|
from hdx.utilities.dictandlist import dict_of_sets_add
|
|
8
8
|
from hdx.utilities.matching import (
|
|
9
|
-
Phonetics,
|
|
10
9
|
RapidFuzzMatcher,
|
|
11
10
|
multiple_replace,
|
|
12
11
|
resolve_name_parts,
|
|
@@ -43,17 +42,14 @@ class AdminLevel:
|
|
|
43
42
|
to files or to enable already saved files to be used instead of downloading
|
|
44
43
|
from urls.
|
|
45
44
|
|
|
46
|
-
The
|
|
47
|
-
|
|
48
|
-
its place_name_scorer. hdx.utilities.matching.Phonetics can be passed
|
|
49
|
-
instead.
|
|
45
|
+
The fuzzy name matcher that fuzzy_pcode tries last is
|
|
46
|
+
hdx.utilities.matching.RapidFuzzMatcher with its place_name_scorer.
|
|
50
47
|
|
|
51
48
|
Args:
|
|
52
49
|
admin_config: Configuration dictionary. Defaults to {}.
|
|
53
50
|
admin_level: Admin level. Defaults to 1.
|
|
54
51
|
admin_level_overrides: Countries at other admin levels.
|
|
55
52
|
retriever: Retriever object to use for loading/saving files.
|
|
56
|
-
matcher: Fuzzy name matcher to use. Defaults to None (RapidFuzzMatcher).
|
|
57
53
|
"""
|
|
58
54
|
|
|
59
55
|
pcode_regex = re.compile(r"^([a-zA-Z]{2,3})(\d+)$")
|
|
@@ -69,7 +65,6 @@ class AdminLevel:
|
|
|
69
65
|
admin_level: int = 1,
|
|
70
66
|
admin_level_overrides: dict | None = None,
|
|
71
67
|
retriever: Retrieve | None = None,
|
|
72
|
-
matcher: Phonetics | RapidFuzzMatcher | None = None,
|
|
73
68
|
) -> None:
|
|
74
69
|
self._admin_level_overrides = admin_level_overrides or {}
|
|
75
70
|
self._retriever: Retrieve | None = retriever
|
|
@@ -81,7 +76,7 @@ class AdminLevel:
|
|
|
81
76
|
self._use_parent = False
|
|
82
77
|
self._zeroes = {}
|
|
83
78
|
self._parent_admins = []
|
|
84
|
-
self._matcher =
|
|
79
|
+
self._matcher = RapidFuzzMatcher(RapidFuzzMatcher.place_name_scorer)
|
|
85
80
|
self.init_matches_errors()
|
|
86
81
|
self.admin_level = admin_level
|
|
87
82
|
self.pcodes = []
|
|
@@ -205,32 +205,6 @@ class TestAdminLevel:
|
|
|
205
205
|
"test - YEM: Matching (fuzzy) Al_Dhale'a to Ad Dali on map",
|
|
206
206
|
]
|
|
207
207
|
|
|
208
|
-
def test_adminlevel_custom_matcher(self, config):
|
|
209
|
-
class AlwaysFirstMatcher:
|
|
210
|
-
def match(
|
|
211
|
-
self,
|
|
212
|
-
possible_names,
|
|
213
|
-
name,
|
|
214
|
-
alternative_name=None,
|
|
215
|
-
transform_possible_names=(),
|
|
216
|
-
threshold=None,
|
|
217
|
-
):
|
|
218
|
-
return 0
|
|
219
|
-
|
|
220
|
-
adminone = AdminLevel(config)
|
|
221
|
-
adminone.setup_from_iterable(config["admin_info"])
|
|
222
|
-
assert adminone.get_pcode("YEM", "Zzznotarealplace", logname="test") == (
|
|
223
|
-
None,
|
|
224
|
-
False,
|
|
225
|
-
)
|
|
226
|
-
|
|
227
|
-
adminone = AdminLevel(config, matcher=AlwaysFirstMatcher())
|
|
228
|
-
adminone.setup_from_iterable(config["admin_info"])
|
|
229
|
-
pcode, exact = adminone.get_pcode("YEM", "Zzznotarealplace", logname="test")
|
|
230
|
-
assert exact is False
|
|
231
|
-
assert pcode is not None
|
|
232
|
-
assert adminone.pcode_to_iso3[pcode] == "YEM"
|
|
233
|
-
|
|
234
208
|
def test_adminlevel_list_of_names(self):
|
|
235
209
|
def row(countryiso3, level, pcode, name, parent):
|
|
236
210
|
return {
|