hdx-python-country 3.7.8__tar.gz → 3.7.9__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 (36) hide show
  1. {hdx_python_country-3.7.8 → hdx_python_country-3.7.9}/PKG-INFO +2 -2
  2. {hdx_python_country-3.7.8 → hdx_python_country-3.7.9}/pyproject.toml +1 -1
  3. {hdx_python_country-3.7.8 → hdx_python_country-3.7.9}/requirements.txt +12 -14
  4. {hdx_python_country-3.7.8 → hdx_python_country-3.7.9}/src/hdx/location/_version.py +2 -2
  5. {hdx_python_country-3.7.8 → hdx_python_country-3.7.9}/src/hdx/location/adminlevel.py +32 -6
  6. {hdx_python_country-3.7.8 → hdx_python_country-3.7.9}/tests/hdx/location/test_adminlevel.py +53 -12
  7. {hdx_python_country-3.7.8 → hdx_python_country-3.7.9}/.config/coveragerc +0 -0
  8. {hdx_python_country-3.7.8 → hdx_python_country-3.7.9}/.config/pre-commit-config.yaml +0 -0
  9. {hdx_python_country-3.7.8 → hdx_python_country-3.7.9}/.config/pytest.ini +0 -0
  10. {hdx_python_country-3.7.8 → hdx_python_country-3.7.9}/.config/ruff.toml +0 -0
  11. {hdx_python_country-3.7.8 → hdx_python_country-3.7.9}/.github/workflows/publish.yaml +0 -0
  12. {hdx_python_country-3.7.8 → hdx_python_country-3.7.9}/.github/workflows/run-python-tests.yaml +0 -0
  13. {hdx_python_country-3.7.8 → hdx_python_country-3.7.9}/.gitignore +0 -0
  14. {hdx_python_country-3.7.8 → hdx_python_country-3.7.9}/CONTRIBUTING.md +0 -0
  15. {hdx_python_country-3.7.8 → hdx_python_country-3.7.9}/LICENSE +0 -0
  16. {hdx_python_country-3.7.8 → hdx_python_country-3.7.9}/README.md +0 -0
  17. {hdx_python_country-3.7.8 → hdx_python_country-3.7.9}/documentation/.readthedocs.yaml +0 -0
  18. {hdx_python_country-3.7.8 → hdx_python_country-3.7.9}/documentation/main.md +0 -0
  19. {hdx_python_country-3.7.8 → hdx_python_country-3.7.9}/documentation/pydoc-markdown.yaml +0 -0
  20. {hdx_python_country-3.7.8 → hdx_python_country-3.7.9}/src/hdx/location/Countries & Territories Taxonomy MVP - C&T Taxonomy with HXL Tags.csv +0 -0
  21. {hdx_python_country-3.7.8 → hdx_python_country-3.7.9}/src/hdx/location/__init__.py +0 -0
  22. {hdx_python_country-3.7.8 → hdx_python_country-3.7.9}/src/hdx/location/country.py +0 -0
  23. {hdx_python_country-3.7.8 → hdx_python_country-3.7.9}/src/hdx/location/currency.py +0 -0
  24. {hdx_python_country-3.7.8 → hdx_python_country-3.7.9}/src/hdx/location/phonetics.py +0 -0
  25. {hdx_python_country-3.7.8 → hdx_python_country-3.7.9}/src/hdx/location/wfp_exchangerates.py +0 -0
  26. {hdx_python_country-3.7.8 → hdx_python_country-3.7.9}/tests/fixtures/adminlevel.yaml +0 -0
  27. {hdx_python_country-3.7.8 → hdx_python_country-3.7.9}/tests/fixtures/adminlevelparent.yaml +0 -0
  28. /hdx_python_country-3.7.8/tests/fixtures/global_pcode_lengths.csv → /hdx_python_country-3.7.9/tests/fixtures/download-global-pcode-lengths.csv +0 -0
  29. /hdx_python_country-3.7.8/tests/fixtures/global_pcodes_adm_1_2.csv → /hdx_python_country-3.7.9/tests/fixtures/download-global-pcodes-adm-1-2.csv +0 -0
  30. {hdx_python_country-3.7.8 → hdx_python_country-3.7.9}/tests/fixtures/secondary_historic_rates.csv +0 -0
  31. {hdx_python_country-3.7.8 → hdx_python_country-3.7.9}/tests/fixtures/secondary_rates.json +0 -0
  32. {hdx_python_country-3.7.8 → hdx_python_country-3.7.9}/tests/hdx/location/Countries_UZB_Deleted.csv +0 -0
  33. {hdx_python_country-3.7.8 → hdx_python_country-3.7.9}/tests/hdx/location/__init__.py +0 -0
  34. {hdx_python_country-3.7.8 → hdx_python_country-3.7.9}/tests/hdx/location/test_country.py +0 -0
  35. {hdx_python_country-3.7.8 → hdx_python_country-3.7.9}/tests/hdx/location/test_currency.py +0 -0
  36. {hdx_python_country-3.7.8 → hdx_python_country-3.7.9}/tests/hdx/location/test_wfp_exchangerates.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: hdx-python-country
3
- Version: 3.7.8
3
+ Version: 3.7.9
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.7.3
28
+ Requires-Dist: hdx-python-utilities>=3.7.4
29
29
  Requires-Dist: libhxl>=5.2.1
30
30
  Requires-Dist: pyphonetics
31
31
  Provides-Extra: dev
@@ -34,7 +34,7 @@ classifiers = [
34
34
  requires-python = ">=3.8"
35
35
 
36
36
  dependencies = [
37
- "hdx-python-utilities>=3.7.3",
37
+ "hdx-python-utilities>=3.7.4",
38
38
  "libhxl>=5.2.1",
39
39
  "pyphonetics",
40
40
  ]
@@ -24,17 +24,17 @@ distlib==0.3.8
24
24
  # via virtualenv
25
25
  et-xmlfile==1.1.0
26
26
  # via openpyxl
27
- filelock==3.15.4
27
+ filelock==3.16.1
28
28
  # via virtualenv
29
- frictionless==5.17.1
29
+ frictionless==5.18.0
30
30
  # via hdx-python-utilities
31
- hdx-python-utilities==3.7.3
31
+ hdx-python-utilities==3.7.4
32
32
  # via hdx-python-country (pyproject.toml)
33
33
  humanize==4.10.0
34
34
  # via frictionless
35
- identify==2.6.0
35
+ identify==2.6.1
36
36
  # via pre-commit
37
- idna==3.8
37
+ idna==3.10
38
38
  # via requests
39
39
  ijson==3.3.0
40
40
  # via hdx-python-utilities
@@ -74,7 +74,7 @@ packaging==24.1
74
74
  # via pytest
75
75
  petl==1.7.15
76
76
  # via frictionless
77
- platformdirs==4.2.2
77
+ platformdirs==4.3.6
78
78
  # via virtualenv
79
79
  pluggy==1.5.0
80
80
  # via pytest
@@ -84,15 +84,15 @@ ply==3.11
84
84
  # libhxl
85
85
  pre-commit==3.8.0
86
86
  # via hdx-python-country (pyproject.toml)
87
- pydantic==2.9.0
87
+ pydantic==2.9.2
88
88
  # via frictionless
89
- pydantic-core==2.23.2
89
+ pydantic-core==2.23.4
90
90
  # via pydantic
91
91
  pygments==2.18.0
92
92
  # via rich
93
93
  pyphonetics==0.5.3
94
94
  # via hdx-python-country (pyproject.toml)
95
- pytest==8.3.2
95
+ pytest==8.3.3
96
96
  # via
97
97
  # hdx-python-country (pyproject.toml)
98
98
  # pytest-cov
@@ -127,7 +127,7 @@ requests-file==2.1.0
127
127
  # via hdx-python-utilities
128
128
  rfc3986==2.0.0
129
129
  # via frictionless
130
- rich==13.8.0
130
+ rich==13.9.1
131
131
  # via typer
132
132
  rpds-py==0.20.0
133
133
  # via
@@ -163,19 +163,17 @@ typing-extensions==4.12.2
163
163
  # pydantic
164
164
  # pydantic-core
165
165
  # typer
166
- tzdata==2024.1
167
- # via pydantic
168
166
  unidecode==1.3.8
169
167
  # via
170
168
  # libhxl
171
169
  # pyphonetics
172
- urllib3==2.2.2
170
+ urllib3==2.2.3
173
171
  # via
174
172
  # libhxl
175
173
  # requests
176
174
  validators==0.34.0
177
175
  # via frictionless
178
- virtualenv==20.26.3
176
+ virtualenv==20.26.6
179
177
  # via pre-commit
180
178
  wheel==0.44.0
181
179
  # via libhxl
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '3.7.8'
16
- __version_tuple__ = version_tuple = (3, 7, 8)
15
+ __version__ = version = '3.7.9'
16
+ __version_tuple__ = version_tuple = (3, 7, 9)
@@ -8,7 +8,9 @@ from hxl.input import HXLIOException
8
8
 
9
9
  from hdx.location.country import Country
10
10
  from hdx.location.phonetics import Phonetics
11
+ from hdx.utilities.base_downloader import DownloadError
11
12
  from hdx.utilities.dictandlist import dict_of_sets_add
13
+ from hdx.utilities.retriever import Retrieve
12
14
  from hdx.utilities.text import multiple_replace, normalise
13
15
  from hdx.utilities.typehint import ListTuple
14
16
 
@@ -30,10 +32,20 @@ class AdminLevel:
30
32
  admin_fuzzy_dont is a list of names for which fuzzy matching should not be
31
33
  tried
32
34
 
35
+ The admin_level_overrides parameter allows manually overriding the returned
36
+ admin level for given countries. It is a dictionary with iso3s as keys and
37
+ admin level numbers as values.
38
+
39
+ The retriever parameter accepts an object of type Retrieve (or inherited
40
+ classes). It is used to allow either that admin data from urls is saved
41
+ to files or to enable already saved files to be used instead of downloading
42
+ from urls.
43
+
33
44
  Args:
34
45
  admin_config (Dict): Configuration dictionary. Defaults to {}.
35
46
  admin_level (int): Admin level. Defaults to 1.
36
47
  admin_level_overrides (Dict): Countries at other admin levels.
48
+ retriever (Optional[Retrieve]): Retriever object to use for loading/saving files. Defaults to None.
37
49
  """
38
50
 
39
51
  pcode_regex = re.compile(r"^([a-zA-Z]{2,3})(\d+)$")
@@ -47,9 +59,11 @@ class AdminLevel:
47
59
  admin_config: Dict = {},
48
60
  admin_level: int = 1,
49
61
  admin_level_overrides: Dict = {},
62
+ retriever: Optional[Retrieve] = None,
50
63
  ) -> None:
51
64
  self.admin_level = admin_level
52
65
  self.admin_level_overrides = admin_level_overrides
66
+ self.retriever: Optional[Retrieve] = retriever
53
67
  self.countries_fuzzy_try = admin_config.get("countries_fuzzy_try")
54
68
  self.admin_name_mappings = admin_config.get("admin_name_mappings", {})
55
69
  self.admin_name_replacements = admin_config.get(
@@ -101,23 +115,35 @@ class AdminLevel:
101
115
  admin_url = cls._admin_url_default
102
116
  cls._admin_url = admin_url
103
117
 
104
- @classmethod
105
- def get_libhxl_dataset(cls, admin_url: str = _admin_url) -> hxl.Dataset:
118
+ def get_libhxl_dataset(self, url: str = _admin_url) -> hxl.Dataset:
106
119
  """
107
120
  Get libhxl Dataset object given a URL which defaults to global p-codes
108
121
  dataset on HDX.
109
122
 
110
123
  Args:
111
- admin_url (str): URL from which to load data. Defaults to global p-codes dataset.
124
+ admin_url (str): URL from which to load data.
112
125
 
113
126
  Returns:
114
127
  None
115
128
  """
129
+ if self.retriever:
130
+ try:
131
+ url_to_use = self.retriever.download_file(url)
132
+ except DownloadError:
133
+ logger.exception(
134
+ f"Setup of libhxl Dataset object with {url} failed!"
135
+ )
136
+ raise
137
+ else:
138
+ url_to_use = url
116
139
  try:
117
- return hxl.data(admin_url, InputOptions(encoding="utf-8"))
118
- except HXLIOException:
140
+ return hxl.data(
141
+ url_to_use,
142
+ InputOptions(InputOptions(allow_local=True, encoding="utf-8")),
143
+ )
144
+ except (FileNotFoundError, HXLIOException):
119
145
  logger.exception(
120
- f"Setup of libhxl Dataset object with {admin_url} failed!"
146
+ f"Setup of libhxl Dataset object with {url} failed!"
121
147
  )
122
148
  raise
123
149
 
@@ -3,28 +3,35 @@
3
3
  from os.path import join
4
4
 
5
5
  import pytest
6
- from hxl.input import HXLIOException
7
6
 
8
7
  from hdx.location.adminlevel import AdminLevel
8
+ from hdx.utilities.base_downloader import DownloadError
9
+ from hdx.utilities.downloader import Download
9
10
  from hdx.utilities.loader import load_yaml
11
+ from hdx.utilities.path import temp_dir
12
+ from hdx.utilities.retriever import Retrieve
10
13
 
11
14
 
12
15
  class TestAdminLevel:
16
+ @pytest.fixture(scope="class")
17
+ def fixtures_dir(self):
18
+ return join("tests", "fixtures")
19
+
13
20
  @pytest.fixture(scope="function")
14
- def config(self):
15
- return load_yaml(join("tests", "fixtures", "adminlevel.yaml"))
21
+ def config(self, fixtures_dir):
22
+ return load_yaml(join(fixtures_dir, "adminlevel.yaml"))
16
23
 
17
24
  @pytest.fixture(scope="function")
18
- def config_parent(self):
19
- return load_yaml(join("tests", "fixtures", "adminlevelparent.yaml"))
25
+ def config_parent(self, fixtures_dir):
26
+ return load_yaml(join(fixtures_dir, "adminlevelparent.yaml"))
20
27
 
21
28
  @pytest.fixture(scope="function")
22
- def url(self):
23
- return "https://raw.githubusercontent.com/OCHA-DAP/hdx-python-country/blank_adm_name/tests/fixtures/global_pcodes_adm_1_2.csv"
29
+ def url(self, fixtures_dir):
30
+ return join(fixtures_dir, "download-global-pcodes-adm-1-2.csv")
24
31
 
25
32
  @pytest.fixture(scope="function")
26
- def formats_url(self):
27
- return "https://raw.githubusercontent.com/OCHA-DAP/hdx-python-country/blank_adm_name/tests/fixtures/global_pcode_lengths.csv"
33
+ def formats_url(self, fixtures_dir):
34
+ return join(fixtures_dir, "download-global-pcode-lengths.csv")
28
35
 
29
36
  def test_adminlevel(self, config):
30
37
  adminone = AdminLevel(config)
@@ -367,16 +374,50 @@ class TestAdminLevel:
367
374
  "MWI", "Blantyre city", parent="MW3", logname="test"
368
375
  ) == (None, False)
369
376
 
370
- def test_adminlevel_with_url(self, config, url):
371
- adminone = AdminLevel(config)
372
- with pytest.raises(HXLIOException):
377
+ def test_adminlevel_with_url(self, config, url, fixtures_dir):
378
+ adminone = AdminLevel(config, admin_level_overrides={"YEM": 5})
379
+ assert adminone.get_admin_level("YEM") == 5
380
+ with pytest.raises(FileNotFoundError):
373
381
  adminone.setup_from_url("fake_url")
382
+ adminone = AdminLevel(config)
374
383
  AdminLevel.set_default_admin_url()
375
384
  assert AdminLevel._admin_url == AdminLevel._admin_url_default
376
385
  AdminLevel.set_default_admin_url(url)
377
386
  assert AdminLevel._admin_url == url
378
387
  adminone.setup_from_url(countryiso3s=("YEM",))
379
388
  assert len(adminone.get_pcode_list()) == 22
389
+
390
+ with temp_dir(
391
+ "TestAdminLevelRetriever",
392
+ delete_on_success=True,
393
+ delete_on_failure=False,
394
+ ) as tempdir:
395
+ with Download(user_agent="test") as downloader:
396
+ retriever = Retrieve(
397
+ downloader,
398
+ tempdir,
399
+ fixtures_dir,
400
+ tempdir,
401
+ save=False,
402
+ use_saved=False,
403
+ )
404
+ adminone = AdminLevel(config, retriever=retriever)
405
+ with pytest.raises(DownloadError):
406
+ adminone.setup_from_url("fake_url")
407
+ retriever = Retrieve(
408
+ downloader,
409
+ tempdir,
410
+ fixtures_dir,
411
+ tempdir,
412
+ save=False,
413
+ use_saved=True,
414
+ )
415
+ adminone = AdminLevel(config, retriever=retriever)
416
+ with pytest.raises(FileNotFoundError):
417
+ adminone.setup_from_url("fake_url")
418
+ adminone.setup_from_url(countryiso3s=("YEM",))
419
+ assert len(adminone.get_pcode_list()) == 22
420
+
380
421
  adminone = AdminLevel(config)
381
422
  adminone.setup_from_url()
382
423
  assert adminone.get_admin_level("YEM") == 1