hdx-python-country 3.8.3__tar.gz → 3.8.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.
Files changed (50) hide show
  1. {hdx_python_country-3.8.3 → hdx_python_country-3.8.5}/PKG-INFO +1 -2
  2. {hdx_python_country-3.8.3 → hdx_python_country-3.8.5}/requirements.txt +9 -11
  3. {hdx_python_country-3.8.3 → hdx_python_country-3.8.5}/src/hdx/location/_version.py +2 -2
  4. {hdx_python_country-3.8.3 → hdx_python_country-3.8.5}/src/hdx/location/country.py +42 -22
  5. hdx_python_country-3.8.5/tests/hdx/location/__init__.py +0 -0
  6. {hdx_python_country-3.8.3 → hdx_python_country-3.8.5}/tests/hdx/location/test_country.py +37 -1
  7. hdx_python_country-3.8.3/tests/hdx/location/__init__.py +0 -8
  8. {hdx_python_country-3.8.3 → hdx_python_country-3.8.5}/.config/coveragerc +0 -0
  9. {hdx_python_country-3.8.3 → hdx_python_country-3.8.5}/.config/pre-commit-config.yaml +0 -0
  10. {hdx_python_country-3.8.3 → hdx_python_country-3.8.5}/.config/pytest.ini +0 -0
  11. {hdx_python_country-3.8.3 → hdx_python_country-3.8.5}/.config/ruff.toml +0 -0
  12. {hdx_python_country-3.8.3 → hdx_python_country-3.8.5}/.github/workflows/publish.yaml +0 -0
  13. {hdx_python_country-3.8.3 → hdx_python_country-3.8.5}/.github/workflows/run-python-tests.yaml +0 -0
  14. {hdx_python_country-3.8.3 → hdx_python_country-3.8.5}/.gitignore +0 -0
  15. {hdx_python_country-3.8.3 → hdx_python_country-3.8.5}/CONTRIBUTING.md +0 -0
  16. {hdx_python_country-3.8.3 → hdx_python_country-3.8.5}/LICENSE +0 -0
  17. {hdx_python_country-3.8.3 → hdx_python_country-3.8.5}/README.md +0 -0
  18. {hdx_python_country-3.8.3 → hdx_python_country-3.8.5}/documentation/.readthedocs.yaml +0 -0
  19. {hdx_python_country-3.8.3 → hdx_python_country-3.8.5}/documentation/main.md +0 -0
  20. {hdx_python_country-3.8.3 → hdx_python_country-3.8.5}/documentation/pydoc-markdown.yaml +0 -0
  21. {hdx_python_country-3.8.3 → hdx_python_country-3.8.5}/pyproject.toml +0 -0
  22. {hdx_python_country-3.8.3 → hdx_python_country-3.8.5}/src/hdx/location/Countries & Territories Taxonomy MVP - C&T Taxonomy with HXL Tags.csv +0 -0
  23. {hdx_python_country-3.8.3 → hdx_python_country-3.8.5}/src/hdx/location/__init__.py +0 -0
  24. {hdx_python_country-3.8.3 → hdx_python_country-3.8.5}/src/hdx/location/adminlevel.py +0 -0
  25. {hdx_python_country-3.8.3 → hdx_python_country-3.8.5}/src/hdx/location/currency.py +0 -0
  26. {hdx_python_country-3.8.3 → hdx_python_country-3.8.5}/src/hdx/location/phonetics.py +0 -0
  27. {hdx_python_country-3.8.3 → hdx_python_country-3.8.5}/src/hdx/location/wfp_api.py +0 -0
  28. {hdx_python_country-3.8.3 → hdx_python_country-3.8.5}/src/hdx/location/wfp_exchangerates.py +0 -0
  29. {hdx_python_country-3.8.3 → hdx_python_country-3.8.5}/tests/fixtures/adminlevel.yaml +0 -0
  30. {hdx_python_country-3.8.3 → hdx_python_country-3.8.5}/tests/fixtures/adminlevelparent.yaml +0 -0
  31. {hdx_python_country-3.8.3 → hdx_python_country-3.8.5}/tests/fixtures/download-global-pcode-lengths.csv +0 -0
  32. {hdx_python_country-3.8.3 → hdx_python_country-3.8.5}/tests/fixtures/download-global-pcodes-adm-1-2.csv +0 -0
  33. {hdx_python_country-3.8.3 → hdx_python_country-3.8.5}/tests/fixtures/secondary_historic_rates.csv +0 -0
  34. {hdx_python_country-3.8.3 → hdx_python_country-3.8.5}/tests/fixtures/secondary_rates.json +0 -0
  35. {hdx_python_country-3.8.3 → hdx_python_country-3.8.5}/tests/fixtures/wfp/Currency_List_1.json +0 -0
  36. {hdx_python_country-3.8.3 → hdx_python_country-3.8.5}/tests/fixtures/wfp/Currency_List_2.json +0 -0
  37. {hdx_python_country-3.8.3 → hdx_python_country-3.8.5}/tests/fixtures/wfp/Currency_UsdIndirectQuotation_1.json +0 -0
  38. {hdx_python_country-3.8.3 → hdx_python_country-3.8.5}/tests/fixtures/wfp/Currency_UsdIndirectQuotation_10.json +0 -0
  39. {hdx_python_country-3.8.3 → hdx_python_country-3.8.5}/tests/fixtures/wfp/Currency_UsdIndirectQuotation_2.json +0 -0
  40. {hdx_python_country-3.8.3 → hdx_python_country-3.8.5}/tests/fixtures/wfp/Currency_UsdIndirectQuotation_3.json +0 -0
  41. {hdx_python_country-3.8.3 → hdx_python_country-3.8.5}/tests/fixtures/wfp/Currency_UsdIndirectQuotation_4.json +0 -0
  42. {hdx_python_country-3.8.3 → hdx_python_country-3.8.5}/tests/fixtures/wfp/Currency_UsdIndirectQuotation_5.json +0 -0
  43. {hdx_python_country-3.8.3 → hdx_python_country-3.8.5}/tests/fixtures/wfp/Currency_UsdIndirectQuotation_6.json +0 -0
  44. {hdx_python_country-3.8.3 → hdx_python_country-3.8.5}/tests/fixtures/wfp/Currency_UsdIndirectQuotation_7.json +0 -0
  45. {hdx_python_country-3.8.3 → hdx_python_country-3.8.5}/tests/fixtures/wfp/Currency_UsdIndirectQuotation_8.json +0 -0
  46. {hdx_python_country-3.8.3 → hdx_python_country-3.8.5}/tests/fixtures/wfp/Currency_UsdIndirectQuotation_9.json +0 -0
  47. {hdx_python_country-3.8.3 → hdx_python_country-3.8.5}/tests/hdx/location/Countries_UZB_Deleted.csv +0 -0
  48. {hdx_python_country-3.8.3 → hdx_python_country-3.8.5}/tests/hdx/location/test_adminlevel.py +0 -0
  49. {hdx_python_country-3.8.3 → hdx_python_country-3.8.5}/tests/hdx/location/test_currency.py +0 -0
  50. {hdx_python_country-3.8.3 → hdx_python_country-3.8.5}/tests/hdx/location/test_wfp_exchangerates.py +0 -0
@@ -1,11 +1,10 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: hdx-python-country
3
- Version: 3.8.3
3
+ Version: 3.8.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
  Author: Michael Rans
7
7
  License: MIT
8
- License-File: LICENSE
9
8
  Keywords: HDX,country,country code,currencies,currency,exchange rate,foreign exchange,fx,iso 3166,iso2,iso3,location,region
10
9
  Classifier: Development Status :: 5 - Production/Stable
11
10
  Classifier: Intended Audience :: Developers
@@ -18,7 +18,7 @@ charset-normalizer==3.4.0
18
18
  # via requests
19
19
  click==8.1.7
20
20
  # via typer
21
- coverage==7.6.4
21
+ coverage==7.6.7
22
22
  # via pytest-cov
23
23
  distlib==0.3.9
24
24
  # via virtualenv
@@ -32,7 +32,7 @@ hdx-python-utilities==3.7.4
32
32
  # via hdx-python-country (pyproject.toml)
33
33
  humanize==4.11.0
34
34
  # via frictionless
35
- identify==2.6.1
35
+ identify==2.6.2
36
36
  # via pre-commit
37
37
  idna==3.10
38
38
  # via requests
@@ -70,12 +70,10 @@ nodeenv==1.9.1
70
70
  # via pre-commit
71
71
  openpyxl==3.1.5
72
72
  # via hdx-python-utilities
73
- packaging==24.1
73
+ packaging==24.2
74
74
  # via pytest
75
75
  petl==1.7.15
76
76
  # via frictionless
77
- pip==24.3.1
78
- # via simpleeval
79
77
  platformdirs==4.3.6
80
78
  # via virtualenv
81
79
  pluggy==1.5.0
@@ -129,9 +127,9 @@ requests-file==2.1.0
129
127
  # via hdx-python-utilities
130
128
  rfc3986==2.0.0
131
129
  # via frictionless
132
- rich==13.9.3
130
+ rich==13.9.4
133
131
  # via typer
134
- rpds-py==0.20.0
132
+ rpds-py==0.21.0
135
133
  # via
136
134
  # jsonschema
137
135
  # referencing
@@ -141,7 +139,7 @@ ruamel-yaml-clib==0.2.12
141
139
  # via ruamel-yaml
142
140
  shellingham==1.5.4
143
141
  # via typer
144
- simpleeval==1.0.1
142
+ simpleeval==1.0.3
145
143
  # via frictionless
146
144
  six==1.16.0
147
145
  # via python-dateutil
@@ -157,7 +155,7 @@ tenacity==9.0.0
157
155
  # via hdx-python-country (pyproject.toml)
158
156
  text-unidecode==1.3
159
157
  # via python-slugify
160
- typer==0.12.5
158
+ typer==0.13.1
161
159
  # via frictionless
162
160
  typing-extensions==4.12.2
163
161
  # via
@@ -177,13 +175,13 @@ validators==0.34.0
177
175
  # via frictionless
178
176
  virtualenv==20.27.1
179
177
  # via pre-commit
180
- wheel==0.44.0
178
+ wheel==0.45.0
181
179
  # via libhxl
182
180
  xlrd==2.0.1
183
181
  # via hdx-python-utilities
184
182
  xlrd3==1.1.0
185
183
  # via libhxl
186
- xlsx2csv==0.8.3
184
+ xlsx2csv==0.8.4
187
185
  # via hdx-python-utilities
188
186
  xlsxwriter==3.2.0
189
187
  # via tableschema-to-template
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '3.8.3'
16
- __version_tuple__ = version_tuple = (3, 8, 3)
15
+ __version__ = version = '3.8.5'
16
+ __version_tuple__ = version_tuple = (3, 8, 5)
@@ -2,6 +2,7 @@
2
2
 
3
3
  import copy
4
4
  import logging
5
+ import os.path
5
6
  import re
6
7
  from string import punctuation
7
8
  from typing import Dict, List, Optional, Tuple, Union
@@ -73,6 +74,11 @@ class Country:
73
74
  _countriesdata = None
74
75
  _ochaurl_default = "https://docs.google.com/spreadsheets/d/1NjSI2LaS3SqbgYc0HdD8oIb7lofGtiHgoKKATCpwVdY/export?format=csv&gid=1088874596"
75
76
  _ochaurl = _ochaurl_default
77
+ _ochapath_default = script_dir_plus_file(
78
+ "Countries & Territories Taxonomy MVP - C&T Taxonomy with HXL Tags.csv",
79
+ CountryError,
80
+ )
81
+ _ochapath = _ochapath_default
76
82
  _country_name_overrides = {}
77
83
  _country_name_mappings = {}
78
84
 
@@ -206,7 +212,7 @@ class Country:
206
212
  @classmethod
207
213
  def countriesdata(
208
214
  cls,
209
- use_live: bool = _use_live,
215
+ use_live: bool = None,
210
216
  country_name_overrides: Dict = None,
211
217
  country_name_mappings: Dict = None,
212
218
  ) -> List[Dict[str, Dict]]:
@@ -221,6 +227,8 @@ class Country:
221
227
  Returns:
222
228
  List[Dict[str,Dict]]: Countries dictionaries
223
229
  """
230
+ if use_live is None:
231
+ use_live = cls._use_live
224
232
  if cls._countriesdata is None:
225
233
  countries = None
226
234
  if country_name_overrides is not None:
@@ -238,10 +246,7 @@ class Country:
238
246
  )
239
247
  if countries is None:
240
248
  countries = hxl.data(
241
- script_dir_plus_file(
242
- "Countries & Territories Taxonomy MVP - C&T Taxonomy with HXL Tags.csv",
243
- Country,
244
- ),
249
+ cls._ochapath,
245
250
  InputOptions(allow_local=True, encoding="utf-8"),
246
251
  )
247
252
  cls.set_countriesdata(countries)
@@ -264,7 +269,7 @@ class Country:
264
269
  cls._use_live = use_live
265
270
 
266
271
  @classmethod
267
- def set_ocha_url(cls, url: Optional[str] = None) -> None:
272
+ def set_ocha_url(cls, url: str = None) -> None:
268
273
  """
269
274
  Set OCHA url from which to retrieve countries data
270
275
 
@@ -278,6 +283,21 @@ class Country:
278
283
  url = cls._ochaurl_default
279
284
  cls._ochaurl = url
280
285
 
286
+ @classmethod
287
+ def set_ocha_path(cls, path: Optional[str] = None) -> None:
288
+ """
289
+ Set local path from which to retrieve OCHA countries data
290
+
291
+ Args:
292
+ path (Optional[str]): Local path from which to retrieve countries data. Defaults to None.
293
+
294
+ Returns:
295
+ None
296
+ """
297
+ if not path or (path and not os.path.exists(path)):
298
+ path = cls._ochapath_default
299
+ cls._ochapath = path
300
+
281
301
  @classmethod
282
302
  def set_country_name_overrides(cls, country_name_overrides: Dict) -> None:
283
303
  """
@@ -308,7 +328,7 @@ class Country:
308
328
  def get_country_info_from_iso3(
309
329
  cls,
310
330
  iso3: str,
311
- use_live: bool = _use_live,
331
+ use_live: bool = None,
312
332
  exception: Optional[ExceptionUpperBound] = None,
313
333
  ) -> Optional[Dict[str, str]]:
314
334
  """Get country information from ISO3 code
@@ -334,7 +354,7 @@ class Country:
334
354
  def get_country_name_from_iso3(
335
355
  cls,
336
356
  iso3: str,
337
- use_live: bool = _use_live,
357
+ use_live: bool = None,
338
358
  exception: Optional[ExceptionUpperBound] = None,
339
359
  formal: bool = False,
340
360
  ) -> Optional[str]:
@@ -371,7 +391,7 @@ class Country:
371
391
  def get_currency_from_iso3(
372
392
  cls,
373
393
  iso3: str,
374
- use_live: bool = _use_live,
394
+ use_live: bool = None,
375
395
  exception: Optional[ExceptionUpperBound] = None,
376
396
  ) -> Optional[int]:
377
397
  """Get currency code from ISO3 code
@@ -397,7 +417,7 @@ class Country:
397
417
  def get_iso2_from_iso3(
398
418
  cls,
399
419
  iso3: str,
400
- use_live: bool = _use_live,
420
+ use_live: bool = None,
401
421
  exception: Optional[ExceptionUpperBound] = None,
402
422
  ) -> Optional[str]:
403
423
  """Get ISO2 from ISO3 code
@@ -423,7 +443,7 @@ class Country:
423
443
  def get_iso3_from_iso2(
424
444
  cls,
425
445
  iso2: str,
426
- use_live: bool = _use_live,
446
+ use_live: bool = None,
427
447
  exception: Optional[ExceptionUpperBound] = None,
428
448
  ) -> Optional[str]:
429
449
  """Get ISO3 from ISO2 code
@@ -449,7 +469,7 @@ class Country:
449
469
  def get_country_info_from_iso2(
450
470
  cls,
451
471
  iso2: str,
452
- use_live: bool = _use_live,
472
+ use_live: bool = None,
453
473
  exception: Optional[ExceptionUpperBound] = None,
454
474
  ) -> Optional[Dict[str, str]]:
455
475
  """Get country name from ISO2 code
@@ -475,7 +495,7 @@ class Country:
475
495
  def get_country_name_from_iso2(
476
496
  cls,
477
497
  iso2: str,
478
- use_live: bool = _use_live,
498
+ use_live: bool = None,
479
499
  exception: Optional[ExceptionUpperBound] = None,
480
500
  formal: bool = False,
481
501
  ) -> Optional[str]:
@@ -503,7 +523,7 @@ class Country:
503
523
  def get_currency_from_iso2(
504
524
  cls,
505
525
  iso2: str,
506
- use_live: bool = _use_live,
526
+ use_live: bool = None,
507
527
  exception: Optional[ExceptionUpperBound] = None,
508
528
  ) -> Optional[str]:
509
529
  """Get currency from ISO2 code
@@ -529,7 +549,7 @@ class Country:
529
549
  def get_m49_from_iso3(
530
550
  cls,
531
551
  iso3: str,
532
- use_live: bool = _use_live,
552
+ use_live: bool = None,
533
553
  exception: Optional[ExceptionUpperBound] = None,
534
554
  ) -> Optional[int]:
535
555
  """Get M49 from ISO3 code
@@ -555,7 +575,7 @@ class Country:
555
575
  def get_iso3_from_m49(
556
576
  cls,
557
577
  m49: int,
558
- use_live: bool = _use_live,
578
+ use_live: bool = None,
559
579
  exception: Optional[ExceptionUpperBound] = None,
560
580
  ) -> Optional[str]:
561
581
  """Get ISO3 from M49 code
@@ -581,7 +601,7 @@ class Country:
581
601
  def get_country_info_from_m49(
582
602
  cls,
583
603
  m49: int,
584
- use_live: bool = _use_live,
604
+ use_live: bool = None,
585
605
  exception: Optional[ExceptionUpperBound] = None,
586
606
  ) -> Optional[Dict[str, str]]:
587
607
  """Get country name from M49 code
@@ -605,7 +625,7 @@ class Country:
605
625
  def get_country_name_from_m49(
606
626
  cls,
607
627
  m49: int,
608
- use_live: bool = _use_live,
628
+ use_live: bool = None,
609
629
  exception: Optional[ExceptionUpperBound] = None,
610
630
  formal: bool = False,
611
631
  ) -> Optional[str]:
@@ -633,7 +653,7 @@ class Country:
633
653
  def get_currency_from_m49(
634
654
  cls,
635
655
  m49: int,
636
- use_live: bool = _use_live,
656
+ use_live: bool = None,
637
657
  exception: Optional[ExceptionUpperBound] = None,
638
658
  ) -> Optional[str]:
639
659
  """Get currency from M49 code
@@ -736,7 +756,7 @@ class Country:
736
756
  def get_iso3_country_code(
737
757
  cls,
738
758
  country: str,
739
- use_live: bool = _use_live,
759
+ use_live: bool = None,
740
760
  exception: Optional[ExceptionUpperBound] = None,
741
761
  ) -> Optional[str]:
742
762
  """Get ISO3 code for cls. Only exact matches or None are returned.
@@ -796,7 +816,7 @@ class Country:
796
816
  def get_iso3_country_code_fuzzy(
797
817
  cls,
798
818
  country: str,
799
- use_live: bool = _use_live,
819
+ use_live: bool = None,
800
820
  exception: Optional[ExceptionUpperBound] = None,
801
821
  min_chars: int = 5,
802
822
  ) -> Tuple[Optional[str], bool]:
@@ -886,7 +906,7 @@ class Country:
886
906
  def get_countries_in_region(
887
907
  cls,
888
908
  region: Union[int, str],
889
- use_live: bool = _use_live,
909
+ use_live: bool = None,
890
910
  exception: Optional[ExceptionUpperBound] = None,
891
911
  ) -> List[str]:
892
912
  """Get countries (ISO3 codes) in region
@@ -12,8 +12,19 @@ class LocationError(Exception):
12
12
  pass
13
13
 
14
14
 
15
- # Note that the Country class is set up in __init__.py
16
15
  class TestCountry:
16
+ @pytest.fixture(scope="function", autouse=True)
17
+ def setup(self):
18
+ # Clean up Country class before each test
19
+ Country._countriesdata = None
20
+ Country.set_use_live_default(False)
21
+ Country.set_ocha_url()
22
+ Country.set_ocha_path()
23
+ Country.countriesdata(
24
+ country_name_overrides={"PSE": "oPt"},
25
+ country_name_mappings={"Congo DR": "COD"},
26
+ )
27
+
17
28
  def test_get_country_name_from_iso3(self):
18
29
  assert Country.get_country_name_from_iso3("jpn") == "Japan"
19
30
  assert Country.get_country_name_from_iso3("awe") is None
@@ -696,8 +707,17 @@ class TestCountry:
696
707
  assert Country._use_live is True
697
708
  Country.set_use_live_default(False)
698
709
  assert Country._use_live is False
710
+ # We should now be able to load from local data without setting use_live=False
711
+ Country._countriesdata = None
712
+ Country.set_ocha_path(
713
+ script_dir_plus_file("Countries_UZB_Deleted.csv", TestCountry)
714
+ )
715
+ assert Country.get_iso3_country_code("UZBEKISTAN") is None
699
716
  Country.set_use_live_default(None)
700
717
  assert Country._use_live is True
718
+ Country._countriesdata = None
719
+ assert Country.get_iso3_country_code("UZBEKISTAN") == "UZB"
720
+ Country._countriesdata = None
701
721
 
702
722
  def test_ocha_feed_file_working(self):
703
723
  countries = hxl.data(
@@ -716,3 +736,19 @@ class TestCountry:
716
736
  Country.set_ocha_url("NOTEXIST")
717
737
  Country._countriesdata = None
718
738
  assert Country.get_iso3_from_iso2("AF") == "AFG"
739
+
740
+ def test_ocha_feed_local_file_working(self):
741
+ Country._countriesdata = None
742
+ Country.set_ocha_path(
743
+ script_dir_plus_file("Countries_UZB_Deleted.csv", TestCountry)
744
+ )
745
+ assert (
746
+ Country.get_iso3_country_code("UZBEKISTAN", use_live=False) is None
747
+ )
748
+
749
+ Country._countriesdata = None
750
+ Country.set_ocha_path()
751
+ assert (
752
+ Country.get_iso3_country_code("UZBEKISTAN", use_live=False)
753
+ == "UZB"
754
+ )
@@ -1,8 +0,0 @@
1
- from hdx.location.country import Country
2
-
3
- Country.set_use_live_default(False)
4
-
5
- Country.countriesdata(
6
- country_name_overrides={"PSE": "oPt"},
7
- country_name_mappings={"Congo DR": "COD"},
8
- )