hdx-python-country 3.7.0__tar.gz → 3.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.
- {hdx_python_country-3.7.0 → hdx_python_country-3.7.2}/.config/pre-commit-config.yaml +5 -4
- {hdx_python_country-3.7.0 → hdx_python_country-3.7.2}/.config/ruff.toml +0 -1
- {hdx_python_country-3.7.0 → hdx_python_country-3.7.2}/PKG-INFO +2 -2
- {hdx_python_country-3.7.0 → hdx_python_country-3.7.2}/documentation/.readthedocs.yaml +1 -0
- {hdx_python_country-3.7.0 → hdx_python_country-3.7.2}/documentation/main.md +13 -4
- {hdx_python_country-3.7.0 → hdx_python_country-3.7.2}/documentation/pydoc-markdown.yaml +3 -3
- {hdx_python_country-3.7.0 → hdx_python_country-3.7.2}/pyproject.toml +1 -1
- {hdx_python_country-3.7.0 → hdx_python_country-3.7.2}/requirements.txt +37 -35
- {hdx_python_country-3.7.0 → hdx_python_country-3.7.2}/src/hdx/location/_version.py +2 -2
- {hdx_python_country-3.7.0 → hdx_python_country-3.7.2}/src/hdx/location/adminlevel.py +116 -17
- hdx_python_country-3.7.2/tests/fixtures/adminlevelparent.yaml +25 -0
- {hdx_python_country-3.7.0 → hdx_python_country-3.7.2}/tests/hdx/location/test_adminlevel.py +144 -4
- {hdx_python_country-3.7.0 → hdx_python_country-3.7.2}/.config/coveragerc +0 -0
- {hdx_python_country-3.7.0 → hdx_python_country-3.7.2}/.config/pytest.ini +0 -0
- {hdx_python_country-3.7.0 → hdx_python_country-3.7.2}/.github/workflows/publish.yaml +0 -0
- {hdx_python_country-3.7.0 → hdx_python_country-3.7.2}/.github/workflows/run-python-tests.yaml +0 -0
- {hdx_python_country-3.7.0 → hdx_python_country-3.7.2}/.gitignore +0 -0
- {hdx_python_country-3.7.0 → hdx_python_country-3.7.2}/CONTRIBUTING.md +0 -0
- {hdx_python_country-3.7.0 → hdx_python_country-3.7.2}/LICENSE +0 -0
- {hdx_python_country-3.7.0 → hdx_python_country-3.7.2}/README.md +0 -0
- {hdx_python_country-3.7.0 → hdx_python_country-3.7.2}/src/hdx/location/Countries & Territories Taxonomy MVP - C&T Taxonomy with HXL Tags.csv +0 -0
- {hdx_python_country-3.7.0 → hdx_python_country-3.7.2}/src/hdx/location/__init__.py +0 -0
- {hdx_python_country-3.7.0 → hdx_python_country-3.7.2}/src/hdx/location/country.py +0 -0
- {hdx_python_country-3.7.0 → hdx_python_country-3.7.2}/src/hdx/location/currency.py +0 -0
- {hdx_python_country-3.7.0 → hdx_python_country-3.7.2}/src/hdx/location/names.py +0 -0
- {hdx_python_country-3.7.0 → hdx_python_country-3.7.2}/src/hdx/location/phonetics.py +0 -0
- {hdx_python_country-3.7.0 → hdx_python_country-3.7.2}/src/hdx/location/wfp_exchangerates.py +0 -0
- {hdx_python_country-3.7.0 → hdx_python_country-3.7.2}/tests/fixtures/adminlevel.yaml +0 -0
- {hdx_python_country-3.7.0 → hdx_python_country-3.7.2}/tests/fixtures/global_pcode_lengths.csv +0 -0
- {hdx_python_country-3.7.0 → hdx_python_country-3.7.2}/tests/fixtures/global_pcodes_adm_1_2.csv +0 -0
- {hdx_python_country-3.7.0 → hdx_python_country-3.7.2}/tests/fixtures/secondary_historic_rates.csv +0 -0
- {hdx_python_country-3.7.0 → hdx_python_country-3.7.2}/tests/fixtures/secondary_rates.json +0 -0
- {hdx_python_country-3.7.0 → hdx_python_country-3.7.2}/tests/hdx/location/Countries_UZB_Deleted.csv +0 -0
- {hdx_python_country-3.7.0 → hdx_python_country-3.7.2}/tests/hdx/location/__init__.py +0 -0
- {hdx_python_country-3.7.0 → hdx_python_country-3.7.2}/tests/hdx/location/test_country.py +0 -0
- {hdx_python_country-3.7.0 → hdx_python_country-3.7.2}/tests/hdx/location/test_currency.py +0 -0
- {hdx_python_country-3.7.0 → hdx_python_country-3.7.2}/tests/hdx/location/test_wfp_exchangerates.py +0 -0
|
@@ -8,7 +8,7 @@ repos:
|
|
|
8
8
|
- id: end-of-file-fixer
|
|
9
9
|
- id: check-ast
|
|
10
10
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
11
|
-
rev: v0.
|
|
11
|
+
rev: v0.4.4
|
|
12
12
|
hooks:
|
|
13
13
|
# Run the linter.
|
|
14
14
|
- id: ruff
|
|
@@ -16,10 +16,11 @@ repos:
|
|
|
16
16
|
# Run the formatter.
|
|
17
17
|
- id: ruff-format
|
|
18
18
|
args: [--config, .config/ruff.toml]
|
|
19
|
-
- repo: https://github.com/
|
|
20
|
-
rev:
|
|
19
|
+
- repo: https://github.com/astral-sh/uv-pre-commit
|
|
20
|
+
rev: 0.1.45
|
|
21
21
|
hooks:
|
|
22
|
+
# Run the pip compile
|
|
22
23
|
- id: pip-compile
|
|
23
24
|
name: pip-compile requirements.txt
|
|
24
25
|
files: pyproject.toml
|
|
25
|
-
args: [pyproject.toml, --resolver=backtracking, --all-extras, --upgrade, -q, -o, requirements.txt]
|
|
26
|
+
args: [ pyproject.toml, --resolver=backtracking, --all-extras, --upgrade, -q, -o, requirements.txt ]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: hdx-python-country
|
|
3
|
-
Version: 3.7.
|
|
3
|
+
Version: 3.7.2
|
|
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
|
Author: Michael Rans
|
|
@@ -25,7 +25,7 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
25
25
|
Classifier: Programming Language :: Python :: 3.12
|
|
26
26
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
27
27
|
Requires-Python: >=3.8
|
|
28
|
-
Requires-Dist: hdx-python-utilities>=3.6.
|
|
28
|
+
Requires-Dist: hdx-python-utilities>=3.6.8
|
|
29
29
|
Requires-Dist: libhxl>=5.2.1
|
|
30
30
|
Requires-Dist: pyphonetics
|
|
31
31
|
Provides-Extra: dev
|
|
@@ -113,10 +113,19 @@ The administration level mappings takes input configuration dictionary,
|
|
|
113
113
|
|
|
114
114
|
*admin_config* can have the following optional keys:
|
|
115
115
|
|
|
116
|
-
*countries_fuzzy_try* are countries (iso3 codes) for which to try fuzzy
|
|
117
|
-
|
|
118
|
-
*
|
|
119
|
-
|
|
116
|
+
*countries_fuzzy_try* are countries (iso3 codes) for which to try fuzzy
|
|
117
|
+
matching. Default is all countries.
|
|
118
|
+
*admin_name_mappings* is a dictionary of mappings from name to pcode. These can
|
|
119
|
+
be global or they can be restricted by country or parent (if the AdminLevel
|
|
120
|
+
object has been set up with parents). Keys take the form "MAPPING",
|
|
121
|
+
"AFG|MAPPING" or "AF01|MAPPING".
|
|
122
|
+
*admin_name_replacements* is a dictionary of textual replacements to try when
|
|
123
|
+
fuzzy matching. It maps from string to string replacement. The replacements can
|
|
124
|
+
be global or they can be restricted by country or parent (if the AdminLevel
|
|
125
|
+
object has been set up with parents). Keys take the form "STRING_TO_REPLACE",
|
|
126
|
+
"AFG|STRING_TO_REPLACE" or "AF01|STRING_TO_REPLACE".
|
|
127
|
+
*admin_fuzzy_dont* is a list of names for which fuzzy matching should not be
|
|
128
|
+
tried
|
|
120
129
|
|
|
121
130
|
Once an AdminLevel object is constructed, one of three setup methods must be
|
|
122
131
|
called: *setup_from_admin_info*, *setup_from_libhxl_dataset* or
|
|
@@ -9,7 +9,7 @@ renderer:
|
|
|
9
9
|
output_directory: docs
|
|
10
10
|
mkdocs_config:
|
|
11
11
|
site_name: HDX Python Country
|
|
12
|
-
theme:
|
|
12
|
+
theme: material
|
|
13
13
|
repo_url: "https://github.com/OCHA-DAP/hdx-python-country"
|
|
14
14
|
markdown:
|
|
15
15
|
source_linker:
|
|
@@ -24,9 +24,9 @@ renderer:
|
|
|
24
24
|
- title: Countries
|
|
25
25
|
contents:
|
|
26
26
|
- hdx.location.country.*
|
|
27
|
-
- title: Administration
|
|
27
|
+
- title: Administration Level
|
|
28
28
|
contents:
|
|
29
|
-
- hdx.location.
|
|
29
|
+
- hdx.location.adminlevel.*
|
|
30
30
|
- title: Currencies
|
|
31
31
|
contents:
|
|
32
32
|
- hdx.location.currency.*
|
|
@@ -1,16 +1,13 @@
|
|
|
1
|
-
#
|
|
2
|
-
#
|
|
3
|
-
|
|
4
|
-
#
|
|
5
|
-
# pip-compile --all-extras --output-file=requirements.txt pyproject.toml
|
|
6
|
-
#
|
|
7
|
-
annotated-types==0.6.0
|
|
1
|
+
# This file was autogenerated by uv via the following command:
|
|
2
|
+
# uv pip compile pyproject.toml --resolver=backtracking --all-extras -o requirements.txt
|
|
3
|
+
annotated-types==0.7.0
|
|
8
4
|
# via pydantic
|
|
9
5
|
attrs==23.2.0
|
|
10
6
|
# via
|
|
11
7
|
# frictionless
|
|
12
8
|
# jsonlines
|
|
13
9
|
# jsonschema
|
|
10
|
+
# referencing
|
|
14
11
|
certifi==2024.2.2
|
|
15
12
|
# via requests
|
|
16
13
|
cfgv==3.4.0
|
|
@@ -21,25 +18,23 @@ charset-normalizer==3.3.2
|
|
|
21
18
|
# via requests
|
|
22
19
|
click==8.1.7
|
|
23
20
|
# via typer
|
|
24
|
-
|
|
25
|
-
# via typer
|
|
26
|
-
coverage[toml]==7.4.4
|
|
21
|
+
coverage==7.5.1
|
|
27
22
|
# via pytest-cov
|
|
28
23
|
distlib==0.3.8
|
|
29
24
|
# via virtualenv
|
|
30
25
|
et-xmlfile==1.1.0
|
|
31
26
|
# via openpyxl
|
|
32
|
-
filelock==3.
|
|
27
|
+
filelock==3.14.0
|
|
33
28
|
# via virtualenv
|
|
34
|
-
frictionless==5.
|
|
29
|
+
frictionless==5.17.0
|
|
35
30
|
# via hdx-python-utilities
|
|
36
|
-
hdx-python-utilities==3.6.
|
|
31
|
+
hdx-python-utilities==3.6.8
|
|
37
32
|
# via hdx-python-country (pyproject.toml)
|
|
38
33
|
humanize==4.9.0
|
|
39
34
|
# via frictionless
|
|
40
|
-
identify==2.5.
|
|
35
|
+
identify==2.5.36
|
|
41
36
|
# via pre-commit
|
|
42
|
-
idna==3.
|
|
37
|
+
idna==3.7
|
|
43
38
|
# via requests
|
|
44
39
|
ijson==3.2.3
|
|
45
40
|
# via hdx-python-utilities
|
|
@@ -47,16 +42,18 @@ iniconfig==2.0.0
|
|
|
47
42
|
# via pytest
|
|
48
43
|
isodate==0.6.1
|
|
49
44
|
# via frictionless
|
|
50
|
-
jinja2==3.1.
|
|
45
|
+
jinja2==3.1.4
|
|
51
46
|
# via frictionless
|
|
52
47
|
jsonlines==4.0.0
|
|
53
48
|
# via hdx-python-utilities
|
|
54
49
|
jsonpath-ng==1.6.1
|
|
55
50
|
# via libhxl
|
|
56
|
-
jsonschema==4.
|
|
51
|
+
jsonschema==4.22.0
|
|
57
52
|
# via
|
|
58
53
|
# frictionless
|
|
59
54
|
# tableschema-to-template
|
|
55
|
+
jsonschema-specifications==2023.12.1
|
|
56
|
+
# via jsonschema
|
|
60
57
|
libhxl==5.2.1
|
|
61
58
|
# via hdx-python-country (pyproject.toml)
|
|
62
59
|
loguru==0.7.2
|
|
@@ -77,27 +74,25 @@ packaging==24.0
|
|
|
77
74
|
# via pytest
|
|
78
75
|
petl==1.7.15
|
|
79
76
|
# via frictionless
|
|
80
|
-
platformdirs==4.2.
|
|
77
|
+
platformdirs==4.2.2
|
|
81
78
|
# via virtualenv
|
|
82
|
-
pluggy==1.
|
|
79
|
+
pluggy==1.5.0
|
|
83
80
|
# via pytest
|
|
84
81
|
ply==3.11
|
|
85
82
|
# via
|
|
86
83
|
# jsonpath-ng
|
|
87
84
|
# libhxl
|
|
88
|
-
pre-commit==3.7.
|
|
85
|
+
pre-commit==3.7.1
|
|
89
86
|
# via hdx-python-country (pyproject.toml)
|
|
90
|
-
pydantic==2.
|
|
87
|
+
pydantic==2.7.1
|
|
91
88
|
# via frictionless
|
|
92
|
-
pydantic-core==2.
|
|
89
|
+
pydantic-core==2.18.2
|
|
93
90
|
# via pydantic
|
|
94
|
-
pygments==2.
|
|
91
|
+
pygments==2.18.0
|
|
95
92
|
# via rich
|
|
96
93
|
pyphonetics==0.5.3
|
|
97
94
|
# via hdx-python-country (pyproject.toml)
|
|
98
|
-
|
|
99
|
-
# via jsonschema
|
|
100
|
-
pytest==8.1.1
|
|
95
|
+
pytest==8.2.1
|
|
101
96
|
# via
|
|
102
97
|
# hdx-python-country (pyproject.toml)
|
|
103
98
|
# pytest-cov
|
|
@@ -119,21 +114,31 @@ pyyaml==6.0.1
|
|
|
119
114
|
# tableschema-to-template
|
|
120
115
|
ratelimit==2.2.1
|
|
121
116
|
# via hdx-python-utilities
|
|
122
|
-
|
|
117
|
+
referencing==0.35.1
|
|
118
|
+
# via
|
|
119
|
+
# jsonschema
|
|
120
|
+
# jsonschema-specifications
|
|
121
|
+
requests==2.32.2
|
|
123
122
|
# via
|
|
124
123
|
# frictionless
|
|
125
124
|
# libhxl
|
|
126
125
|
# requests-file
|
|
127
|
-
requests-file==2.
|
|
126
|
+
requests-file==2.1.0
|
|
128
127
|
# via hdx-python-utilities
|
|
129
128
|
rfc3986==2.0.0
|
|
130
129
|
# via frictionless
|
|
131
130
|
rich==13.7.1
|
|
132
131
|
# via typer
|
|
132
|
+
rpds-py==0.18.1
|
|
133
|
+
# via
|
|
134
|
+
# jsonschema
|
|
135
|
+
# referencing
|
|
133
136
|
ruamel-yaml==0.18.6
|
|
134
137
|
# via hdx-python-utilities
|
|
135
138
|
ruamel-yaml-clib==0.2.8
|
|
136
139
|
# via ruamel-yaml
|
|
140
|
+
setuptools==70.0.0
|
|
141
|
+
# via nodeenv
|
|
137
142
|
shellingham==1.5.4
|
|
138
143
|
# via typer
|
|
139
144
|
simpleeval==0.9.13
|
|
@@ -152,9 +157,9 @@ tabulate==0.9.0
|
|
|
152
157
|
# via frictionless
|
|
153
158
|
text-unidecode==1.3
|
|
154
159
|
# via python-slugify
|
|
155
|
-
typer
|
|
160
|
+
typer==0.12.3
|
|
156
161
|
# via frictionless
|
|
157
|
-
typing-extensions==4.
|
|
162
|
+
typing-extensions==4.11.0
|
|
158
163
|
# via
|
|
159
164
|
# frictionless
|
|
160
165
|
# pydantic
|
|
@@ -168,9 +173,9 @@ urllib3==2.2.1
|
|
|
168
173
|
# via
|
|
169
174
|
# libhxl
|
|
170
175
|
# requests
|
|
171
|
-
validators==0.
|
|
176
|
+
validators==0.28.1
|
|
172
177
|
# via frictionless
|
|
173
|
-
virtualenv==20.
|
|
178
|
+
virtualenv==20.26.2
|
|
174
179
|
# via pre-commit
|
|
175
180
|
wheel==0.43.0
|
|
176
181
|
# via libhxl
|
|
@@ -182,6 +187,3 @@ xlsxwriter==3.2.0
|
|
|
182
187
|
# via tableschema-to-template
|
|
183
188
|
xlwt==1.3.0
|
|
184
189
|
# via hdx-python-utilities
|
|
185
|
-
|
|
186
|
-
# The following packages are considered to be unsafe in a requirements file:
|
|
187
|
-
# setuptools
|
|
@@ -306,7 +306,7 @@ class AdminLevel:
|
|
|
306
306
|
"""Get admin level for country
|
|
307
307
|
|
|
308
308
|
Args:
|
|
309
|
-
countryiso3 (str):
|
|
309
|
+
countryiso3 (str): ISO3 country code
|
|
310
310
|
|
|
311
311
|
Returns:
|
|
312
312
|
int: Admin level
|
|
@@ -320,7 +320,7 @@ class AdminLevel:
|
|
|
320
320
|
"""Get pcode length for country
|
|
321
321
|
|
|
322
322
|
Args:
|
|
323
|
-
countryiso3 (str):
|
|
323
|
+
countryiso3 (str): ISO3 country code
|
|
324
324
|
|
|
325
325
|
Returns:
|
|
326
326
|
Optional[int]: Country's pcode length or None
|
|
@@ -517,6 +517,41 @@ class AdminLevel:
|
|
|
517
517
|
return pcode
|
|
518
518
|
return None
|
|
519
519
|
|
|
520
|
+
def get_admin_name_replacements(
|
|
521
|
+
self, countryiso3: str, parent: Optional[str]
|
|
522
|
+
) -> Dict[str, str]:
|
|
523
|
+
"""Get relevant admin name replacements from admin name replacements
|
|
524
|
+
which is a dictionary of mappings from string to string replacement.
|
|
525
|
+
These can be global or they can be restricted by
|
|
526
|
+
country or parent (if the AdminLevel object has been set up with
|
|
527
|
+
parents). Keys take the form "STRING_TO_REPLACE",
|
|
528
|
+
"AFG|STRING_TO_REPLACE" or "AF01|STRING_TO_REPLACE".
|
|
529
|
+
|
|
530
|
+
Args:
|
|
531
|
+
countryiso3 (str): ISO3 country code
|
|
532
|
+
parent (Optional[str]): Parent admin code
|
|
533
|
+
|
|
534
|
+
Returns:
|
|
535
|
+
Dict[str, str]: Relevant admin name replacements
|
|
536
|
+
"""
|
|
537
|
+
relevant_name_replacements = {}
|
|
538
|
+
for key, value in self.admin_name_replacements.items():
|
|
539
|
+
if "|" not in key:
|
|
540
|
+
if key not in relevant_name_replacements:
|
|
541
|
+
relevant_name_replacements[key] = value
|
|
542
|
+
continue
|
|
543
|
+
prefix, name = key.split("|")
|
|
544
|
+
if parent:
|
|
545
|
+
if prefix == parent:
|
|
546
|
+
if name not in relevant_name_replacements:
|
|
547
|
+
relevant_name_replacements[name] = value
|
|
548
|
+
continue
|
|
549
|
+
if prefix == countryiso3:
|
|
550
|
+
if name not in relevant_name_replacements:
|
|
551
|
+
relevant_name_replacements[name] = value
|
|
552
|
+
continue
|
|
553
|
+
return relevant_name_replacements
|
|
554
|
+
|
|
520
555
|
def fuzzy_pcode(
|
|
521
556
|
self,
|
|
522
557
|
countryiso3: str,
|
|
@@ -526,7 +561,7 @@ class AdminLevel:
|
|
|
526
561
|
"""Fuzzy match name to pcode
|
|
527
562
|
|
|
528
563
|
Args:
|
|
529
|
-
countryiso3 (str):
|
|
564
|
+
countryiso3 (str): ISO3 country code
|
|
530
565
|
name (str): Name to match
|
|
531
566
|
**kwargs:
|
|
532
567
|
parent (Optional[str]): Parent admin code
|
|
@@ -543,8 +578,17 @@ class AdminLevel:
|
|
|
543
578
|
if logname:
|
|
544
579
|
self.ignored.add((logname, countryiso3))
|
|
545
580
|
return None
|
|
546
|
-
if self.use_parent
|
|
547
|
-
parent = kwargs
|
|
581
|
+
if self.use_parent:
|
|
582
|
+
parent = kwargs.get("parent")
|
|
583
|
+
else:
|
|
584
|
+
parent = None
|
|
585
|
+
if parent is None:
|
|
586
|
+
name_to_pcode = self.name_to_pcode.get(countryiso3)
|
|
587
|
+
if not name_to_pcode:
|
|
588
|
+
if logname:
|
|
589
|
+
self.errors.add((logname, countryiso3))
|
|
590
|
+
return None
|
|
591
|
+
else:
|
|
548
592
|
name_parent_to_pcode = self.name_parent_to_pcode.get(countryiso3)
|
|
549
593
|
if not name_parent_to_pcode:
|
|
550
594
|
if logname:
|
|
@@ -555,15 +599,10 @@ class AdminLevel:
|
|
|
555
599
|
if logname:
|
|
556
600
|
self.errors.add((logname, countryiso3, parent))
|
|
557
601
|
return None
|
|
558
|
-
else:
|
|
559
|
-
name_to_pcode = self.name_to_pcode.get(countryiso3)
|
|
560
|
-
if not name_to_pcode:
|
|
561
|
-
if logname:
|
|
562
|
-
self.errors.add((logname, countryiso3))
|
|
563
|
-
return None
|
|
564
602
|
adm_name_lookup = clean_name(name)
|
|
565
603
|
adm_name_lookup2 = multiple_replace(
|
|
566
|
-
adm_name_lookup,
|
|
604
|
+
adm_name_lookup,
|
|
605
|
+
self.get_admin_name_replacements(countryiso3, parent),
|
|
567
606
|
)
|
|
568
607
|
pcode = name_to_pcode.get(
|
|
569
608
|
adm_name_lookup, name_to_pcode.get(adm_name_lookup2)
|
|
@@ -643,6 +682,33 @@ class AdminLevel:
|
|
|
643
682
|
)
|
|
644
683
|
return pcode
|
|
645
684
|
|
|
685
|
+
def get_name_mapped_pcode(
|
|
686
|
+
self, countryiso3: str, name: str, parent: Optional[str]
|
|
687
|
+
) -> Optional[str]:
|
|
688
|
+
"""Get pcode from admin name mappings which is a dictionary of mappings
|
|
689
|
+
from name to pcode. These can be global or they can be restricted by
|
|
690
|
+
country or parent (if the AdminLevel object has been set up with
|
|
691
|
+
parents). Keys take the form "MAPPING", "AFG|MAPPING" or
|
|
692
|
+
"AF01|MAPPING".
|
|
693
|
+
|
|
694
|
+
Args:
|
|
695
|
+
countryiso3 (str): ISO3 country code
|
|
696
|
+
name (str): Name to match
|
|
697
|
+
parent (Optional[str]): Parent admin code
|
|
698
|
+
|
|
699
|
+
Returns:
|
|
700
|
+
Optional[str]: P code match from admin name mappings or None if no match
|
|
701
|
+
"""
|
|
702
|
+
if parent:
|
|
703
|
+
pcode = self.admin_name_mappings.get(f"{parent}|{name}")
|
|
704
|
+
if pcode is None:
|
|
705
|
+
pcode = self.admin_name_mappings.get(f"{countryiso3}|{name}")
|
|
706
|
+
else:
|
|
707
|
+
pcode = self.admin_name_mappings.get(f"{countryiso3}|{name}")
|
|
708
|
+
if pcode is None:
|
|
709
|
+
pcode = self.admin_name_mappings.get(name)
|
|
710
|
+
return pcode
|
|
711
|
+
|
|
646
712
|
def get_pcode(
|
|
647
713
|
self,
|
|
648
714
|
countryiso3: str,
|
|
@@ -653,7 +719,7 @@ class AdminLevel:
|
|
|
653
719
|
"""Get pcode for a given name
|
|
654
720
|
|
|
655
721
|
Args:
|
|
656
|
-
countryiso3 (str):
|
|
722
|
+
countryiso3 (str): ISO3 country code
|
|
657
723
|
name (str): Name to match
|
|
658
724
|
fuzzy_match (bool): Whether to try fuzzy matching. Defaults to True.
|
|
659
725
|
**kwargs:
|
|
@@ -663,9 +729,17 @@ class AdminLevel:
|
|
|
663
729
|
Returns:
|
|
664
730
|
Tuple[Optional[str], bool]: (Matched P code or None if no match, True if exact match or False if not)
|
|
665
731
|
"""
|
|
666
|
-
|
|
732
|
+
if self.use_parent:
|
|
733
|
+
parent = kwargs.get("parent")
|
|
734
|
+
else:
|
|
735
|
+
parent = None
|
|
736
|
+
pcode = self.get_name_mapped_pcode(countryiso3, name, parent)
|
|
667
737
|
if pcode and self.pcode_to_iso3[pcode] == countryiso3:
|
|
668
|
-
|
|
738
|
+
if parent:
|
|
739
|
+
if self.pcode_to_parent[pcode] == parent:
|
|
740
|
+
return pcode, True
|
|
741
|
+
else:
|
|
742
|
+
return pcode, True
|
|
669
743
|
if self.looks_like_pcode(name):
|
|
670
744
|
pcode = name.upper()
|
|
671
745
|
if pcode in self.pcodes: # name is a p-code
|
|
@@ -677,8 +751,7 @@ class AdminLevel:
|
|
|
677
751
|
)
|
|
678
752
|
return pcode, True
|
|
679
753
|
else:
|
|
680
|
-
if
|
|
681
|
-
parent = kwargs["parent"]
|
|
754
|
+
if parent:
|
|
682
755
|
name_parent_to_pcode = self.name_parent_to_pcode.get(
|
|
683
756
|
countryiso3
|
|
684
757
|
)
|
|
@@ -743,3 +816,29 @@ class AdminLevel:
|
|
|
743
816
|
logger.error(line)
|
|
744
817
|
output.append(line)
|
|
745
818
|
return output
|
|
819
|
+
|
|
820
|
+
def output_admin_name_mappings(self) -> List[str]:
|
|
821
|
+
"""Output log of name mappings
|
|
822
|
+
|
|
823
|
+
Returns:
|
|
824
|
+
List[str]: List of mappings
|
|
825
|
+
"""
|
|
826
|
+
output = []
|
|
827
|
+
for name, pcode in self.admin_name_mappings.items():
|
|
828
|
+
line = f"{name}: {self.pcode_to_name[pcode]} ({pcode})"
|
|
829
|
+
logger.info(line)
|
|
830
|
+
output.append(line)
|
|
831
|
+
return output
|
|
832
|
+
|
|
833
|
+
def output_admin_name_replacements(self) -> List[str]:
|
|
834
|
+
"""Output log of name replacements
|
|
835
|
+
|
|
836
|
+
Returns:
|
|
837
|
+
List[str]: List of name replacements
|
|
838
|
+
"""
|
|
839
|
+
output = []
|
|
840
|
+
for name, replacement in self.admin_name_replacements.items():
|
|
841
|
+
line = f"{name}: {replacement}"
|
|
842
|
+
logger.info(line)
|
|
843
|
+
output.append(line)
|
|
844
|
+
return output
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
admin_info_with_parent:
|
|
2
|
+
- {pcode: AF0101, name: Kabul, iso3: AFG, parent: AF01}
|
|
3
|
+
- {pcode: AF0102, name: Paghman, iso3: AFG, parent: AF01}
|
|
4
|
+
- {pcode: AF0201, name: Kabul, iso3: AFG, parent: AF02} # testing purposes
|
|
5
|
+
- {pcode: AF0301, name: Charikar, iso3: AFG, parent: AF03}
|
|
6
|
+
- {pcode: AF0401, name: Maydan Shahr, iso3: AFG, parent: AF04}
|
|
7
|
+
- {pcode: AF0501, name: Pul-e-Alam, iso3: AFG, parent: AF05}
|
|
8
|
+
- {pcode: AF0501, name: Pul-e-Alam, iso3: AFG, parent: AF05}
|
|
9
|
+
- {pcode: CD2013, name: Mbanza-Ngungu, iso3: COD, parent: CD20}
|
|
10
|
+
- {pcode: CD3102, name: Kenge, iso3: COD, parent: CD31}
|
|
11
|
+
- {pcode: MW305, name: Blantyre, iso3: MWI, parent: MW3}
|
|
12
|
+
|
|
13
|
+
admin_name_mappings:
|
|
14
|
+
"MyMapping": "AF0301"
|
|
15
|
+
"AFG|MyMapping2": "AF0401"
|
|
16
|
+
"AF05|MyMapping3": "AF0501"
|
|
17
|
+
|
|
18
|
+
admin_name_replacements:
|
|
19
|
+
" city": ""
|
|
20
|
+
|
|
21
|
+
alt1_admin_name_replacements:
|
|
22
|
+
"COD| city": ""
|
|
23
|
+
|
|
24
|
+
alt2_admin_name_replacements:
|
|
25
|
+
"CD20| city": ""
|
|
@@ -14,6 +14,10 @@ class TestAdminLevel:
|
|
|
14
14
|
def config(self):
|
|
15
15
|
return load_yaml(join("tests", "fixtures", "adminlevel.yaml"))
|
|
16
16
|
|
|
17
|
+
@pytest.fixture(scope="function")
|
|
18
|
+
def config_parent(self):
|
|
19
|
+
return load_yaml(join("tests", "fixtures", "adminlevelparent.yaml"))
|
|
20
|
+
|
|
17
21
|
@pytest.fixture(scope="function")
|
|
18
22
|
def url(self):
|
|
19
23
|
return "https://raw.githubusercontent.com/OCHA-DAP/hdx-python-country/main/tests/fixtures/global_pcodes_adm_1_2.csv"
|
|
@@ -155,6 +159,25 @@ class TestAdminLevel:
|
|
|
155
159
|
"test - Could not find ABC in map names!",
|
|
156
160
|
"test - NER: Could not find ABCDEFGH in map names!",
|
|
157
161
|
]
|
|
162
|
+
output = adminone.output_admin_name_mappings()
|
|
163
|
+
assert len(output) == 62
|
|
164
|
+
assert output[0] == "Nord-Ouest: North West (HT09)"
|
|
165
|
+
assert output[31] == "Juba Dhexe: Middle Juba (SO27)"
|
|
166
|
+
assert output[61] == "CU Niamey: Niamey (NER008)"
|
|
167
|
+
|
|
168
|
+
output = adminone.output_admin_name_replacements()
|
|
169
|
+
assert output == [
|
|
170
|
+
" urban: ",
|
|
171
|
+
"sud: south",
|
|
172
|
+
"ouest: west",
|
|
173
|
+
"est: east",
|
|
174
|
+
"nord: north",
|
|
175
|
+
"': ",
|
|
176
|
+
"/: ",
|
|
177
|
+
".: ",
|
|
178
|
+
" region: ",
|
|
179
|
+
" oblast: ",
|
|
180
|
+
]
|
|
158
181
|
|
|
159
182
|
def test_adminlevel_fuzzy(self, config):
|
|
160
183
|
adminone = AdminLevel(config)
|
|
@@ -179,10 +202,10 @@ class TestAdminLevel:
|
|
|
179
202
|
"test - YEM: Matching (fuzzy) Al Dhale'e / الضالع to Ad Dali on map",
|
|
180
203
|
]
|
|
181
204
|
|
|
182
|
-
def test_adminlevel_parent(self,
|
|
183
|
-
admintwo = AdminLevel(
|
|
205
|
+
def test_adminlevel_parent(self, config_parent):
|
|
206
|
+
admintwo = AdminLevel(config_parent)
|
|
184
207
|
admintwo.countries_fuzzy_try = None
|
|
185
|
-
admintwo.setup_from_admin_info(
|
|
208
|
+
admintwo.setup_from_admin_info(config_parent["admin_info_with_parent"])
|
|
186
209
|
assert admintwo.use_parent is True
|
|
187
210
|
assert admintwo.pcode_to_parent["AF0101"] == "AF01"
|
|
188
211
|
assert admintwo.get_pcode("AFG", "AF0101", logname="test") == (
|
|
@@ -218,6 +241,123 @@ class TestAdminLevel:
|
|
|
218
241
|
"ABC", "Kabull", parent="AF02", logname="test"
|
|
219
242
|
) == (None, False)
|
|
220
243
|
|
|
244
|
+
output = admintwo.output_admin_name_mappings()
|
|
245
|
+
assert output == [
|
|
246
|
+
"MyMapping: Charikar (AF0301)",
|
|
247
|
+
"AFG|MyMapping2: Maydan Shahr (AF0401)",
|
|
248
|
+
"AF05|MyMapping3: Pul-e-Alam (AF0501)",
|
|
249
|
+
]
|
|
250
|
+
assert admintwo.get_pcode("AFG", "MyMapping", logname="test") == (
|
|
251
|
+
"AF0301",
|
|
252
|
+
True,
|
|
253
|
+
)
|
|
254
|
+
assert admintwo.get_pcode(
|
|
255
|
+
"AFG", "MyMapping", parent="AF03", logname="test"
|
|
256
|
+
) == ("AF0301", True)
|
|
257
|
+
assert admintwo.get_pcode(
|
|
258
|
+
"AFG", "MyMapping", parent="AF04", logname="test"
|
|
259
|
+
) == (None, False)
|
|
260
|
+
|
|
261
|
+
assert admintwo.get_pcode("AFG", "MyMapping2", logname="test") == (
|
|
262
|
+
"AF0401",
|
|
263
|
+
True,
|
|
264
|
+
)
|
|
265
|
+
assert admintwo.get_pcode(
|
|
266
|
+
"AFG", "MyMapping2", parent="AF04", logname="test"
|
|
267
|
+
) == ("AF0401", True)
|
|
268
|
+
assert admintwo.get_pcode(
|
|
269
|
+
"AFG", "MyMapping2", parent="AF05", logname="test"
|
|
270
|
+
) == (None, False)
|
|
271
|
+
|
|
272
|
+
assert admintwo.get_pcode("AFG", "MyMapping3", logname="test") == (
|
|
273
|
+
None,
|
|
274
|
+
False,
|
|
275
|
+
)
|
|
276
|
+
assert admintwo.get_pcode(
|
|
277
|
+
"AFG", "MyMapping3", parent="AF05", logname="test"
|
|
278
|
+
) == ("AF0501", True)
|
|
279
|
+
assert admintwo.get_pcode(
|
|
280
|
+
"AFG", "MyMapping3", parent="AF04", logname="test"
|
|
281
|
+
) == (None, False)
|
|
282
|
+
|
|
283
|
+
output = admintwo.output_admin_name_replacements()
|
|
284
|
+
assert output == [" city: "]
|
|
285
|
+
assert admintwo.get_pcode(
|
|
286
|
+
"COD", "Mbanza-Ngungu city", logname="test"
|
|
287
|
+
) == ("CD2013", False)
|
|
288
|
+
assert admintwo.get_pcode(
|
|
289
|
+
"COD", "Mbanza-Ngungu city", parent="CD20", logname="test"
|
|
290
|
+
) == ("CD2013", False)
|
|
291
|
+
assert admintwo.get_pcode(
|
|
292
|
+
"COD", "Mbanza-Ngungu city", parent="CD19", logname="test"
|
|
293
|
+
) == (None, False)
|
|
294
|
+
assert admintwo.get_pcode("COD", "Kenge city", logname="test") == (
|
|
295
|
+
"CD3102",
|
|
296
|
+
False,
|
|
297
|
+
)
|
|
298
|
+
assert admintwo.get_pcode("MWI", "Blantyre city", logname="test") == (
|
|
299
|
+
"MW305",
|
|
300
|
+
False,
|
|
301
|
+
)
|
|
302
|
+
|
|
303
|
+
admintwo.admin_name_replacements = config_parent[
|
|
304
|
+
"alt1_admin_name_replacements"
|
|
305
|
+
]
|
|
306
|
+
output = admintwo.output_admin_name_replacements()
|
|
307
|
+
assert output == ["COD| city: "]
|
|
308
|
+
assert admintwo.get_pcode(
|
|
309
|
+
"COD", "Mbanza-Ngungu city", logname="test"
|
|
310
|
+
) == ("CD2013", False)
|
|
311
|
+
assert admintwo.get_pcode(
|
|
312
|
+
"COD", "Mbanza-Ngungu city", parent="CD20", logname="test"
|
|
313
|
+
) == ("CD2013", False)
|
|
314
|
+
assert admintwo.get_pcode(
|
|
315
|
+
"COD", "Mbanza-Ngungu city", parent="CD19", logname="test"
|
|
316
|
+
) == (None, False)
|
|
317
|
+
assert admintwo.get_pcode("COD", "Kenge city", logname="test") == (
|
|
318
|
+
"CD3102",
|
|
319
|
+
False,
|
|
320
|
+
)
|
|
321
|
+
assert admintwo.get_pcode(
|
|
322
|
+
"COD", "Kenge city", parent="CD31", logname="test"
|
|
323
|
+
) == ("CD3102", False)
|
|
324
|
+
assert admintwo.get_pcode("MWI", "Blantyre city", logname="test") == (
|
|
325
|
+
None,
|
|
326
|
+
False,
|
|
327
|
+
)
|
|
328
|
+
assert admintwo.get_pcode(
|
|
329
|
+
"MWI", "Blantyre city", parent="MW3", logname="test"
|
|
330
|
+
) == (None, False)
|
|
331
|
+
|
|
332
|
+
admintwo.admin_name_replacements = config_parent[
|
|
333
|
+
"alt2_admin_name_replacements"
|
|
334
|
+
]
|
|
335
|
+
output = admintwo.output_admin_name_replacements()
|
|
336
|
+
assert output == ["CD20| city: "]
|
|
337
|
+
assert admintwo.get_pcode(
|
|
338
|
+
"COD", "Mbanza-Ngungu city", logname="test"
|
|
339
|
+
) == (None, False)
|
|
340
|
+
assert admintwo.get_pcode(
|
|
341
|
+
"COD", "Mbanza-Ngungu city", parent="CD20", logname="test"
|
|
342
|
+
) == ("CD2013", False)
|
|
343
|
+
assert admintwo.get_pcode(
|
|
344
|
+
"COD", "Mbanza-Ngungu city", parent="CD19", logname="test"
|
|
345
|
+
) == (None, False)
|
|
346
|
+
assert admintwo.get_pcode("COD", "Kenge city", logname="test") == (
|
|
347
|
+
None,
|
|
348
|
+
False,
|
|
349
|
+
)
|
|
350
|
+
assert admintwo.get_pcode(
|
|
351
|
+
"COD", "Kenge city", parent="CD31", logname="test"
|
|
352
|
+
) == (None, False)
|
|
353
|
+
assert admintwo.get_pcode("MWI", "Blantyre city", logname="test") == (
|
|
354
|
+
None,
|
|
355
|
+
False,
|
|
356
|
+
)
|
|
357
|
+
assert admintwo.get_pcode(
|
|
358
|
+
"MWI", "Blantyre city", parent="MW3", logname="test"
|
|
359
|
+
) == (None, False)
|
|
360
|
+
|
|
221
361
|
def test_adminlevel_with_url(self, config, url):
|
|
222
362
|
adminone = AdminLevel(config)
|
|
223
363
|
with pytest.raises(HXLIOException):
|
|
@@ -231,7 +371,7 @@ class TestAdminLevel:
|
|
|
231
371
|
adminone = AdminLevel(config)
|
|
232
372
|
adminone.setup_from_url()
|
|
233
373
|
assert adminone.get_admin_level("YEM") == 1
|
|
234
|
-
assert len(adminone.get_pcode_list()) ==
|
|
374
|
+
assert len(adminone.get_pcode_list()) == 2509
|
|
235
375
|
assert adminone.get_pcode_length("YEM") == 4
|
|
236
376
|
assert adminone.get_pcode("YEM", "YE30", logname="test") == (
|
|
237
377
|
"YE30",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{hdx_python_country-3.7.0 → hdx_python_country-3.7.2}/.github/workflows/run-python-tests.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{hdx_python_country-3.7.0 → hdx_python_country-3.7.2}/tests/fixtures/global_pcode_lengths.csv
RENAMED
|
File without changes
|
{hdx_python_country-3.7.0 → hdx_python_country-3.7.2}/tests/fixtures/global_pcodes_adm_1_2.csv
RENAMED
|
File without changes
|
{hdx_python_country-3.7.0 → hdx_python_country-3.7.2}/tests/fixtures/secondary_historic_rates.csv
RENAMED
|
File without changes
|
|
File without changes
|
{hdx_python_country-3.7.0 → hdx_python_country-3.7.2}/tests/hdx/location/Countries_UZB_Deleted.csv
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{hdx_python_country-3.7.0 → hdx_python_country-3.7.2}/tests/hdx/location/test_wfp_exchangerates.py
RENAMED
|
File without changes
|