hdx-python-country 3.6.1__tar.gz → 3.6.3__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.6.1 → hdx_python_country-3.6.3}/.config/coveragerc +1 -1
  2. {hdx_python_country-3.6.1 → hdx_python_country-3.6.3}/CONTRIBUTING.md +4 -4
  3. {hdx_python_country-3.6.1 → hdx_python_country-3.6.3}/LICENSE +1 -1
  4. {hdx_python_country-3.6.1 → hdx_python_country-3.6.3}/PKG-INFO +1 -1
  5. {hdx_python_country-3.6.1 → hdx_python_country-3.6.3}/requirements.txt +5 -5
  6. {hdx_python_country-3.6.1 → hdx_python_country-3.6.3}/src/hdx/location/Countries & Territories Taxonomy MVP - C&T Taxonomy with HXL Tags.csv +1 -1
  7. {hdx_python_country-3.6.1 → hdx_python_country-3.6.3}/src/hdx/location/_version.py +2 -2
  8. {hdx_python_country-3.6.1 → hdx_python_country-3.6.3}/src/hdx/location/adminlevel.py +1 -1
  9. {hdx_python_country-3.6.1 → hdx_python_country-3.6.3}/src/hdx/location/currency.py +68 -14
  10. hdx_python_country-3.6.3/tests/fixtures/secondary_historic_rates.csv +13535 -0
  11. {hdx_python_country-3.6.1 → hdx_python_country-3.6.3}/tests/hdx/location/Countries_UZB_Deleted.csv +1 -1
  12. {hdx_python_country-3.6.1 → hdx_python_country-3.6.3}/tests/hdx/location/test_adminlevel.py +4 -0
  13. {hdx_python_country-3.6.1 → hdx_python_country-3.6.3}/tests/hdx/location/test_currency.py +246 -9
  14. hdx_python_country-3.6.1/tests/fixtures/secondary_historic_rates.csv +0 -745
  15. {hdx_python_country-3.6.1 → hdx_python_country-3.6.3}/.config/black.toml +0 -0
  16. {hdx_python_country-3.6.1 → hdx_python_country-3.6.3}/.config/pre-commit-config.yaml +0 -0
  17. {hdx_python_country-3.6.1 → hdx_python_country-3.6.3}/.config/pytest.ini +0 -0
  18. {hdx_python_country-3.6.1 → hdx_python_country-3.6.3}/.config/ruff.toml +0 -0
  19. {hdx_python_country-3.6.1 → hdx_python_country-3.6.3}/.github/workflows/publish.yaml +0 -0
  20. {hdx_python_country-3.6.1 → hdx_python_country-3.6.3}/.github/workflows/run-python-tests.yaml +0 -0
  21. {hdx_python_country-3.6.1 → hdx_python_country-3.6.3}/.gitignore +0 -0
  22. {hdx_python_country-3.6.1 → hdx_python_country-3.6.3}/README.md +0 -0
  23. {hdx_python_country-3.6.1 → hdx_python_country-3.6.3}/documentation/.readthedocs.yaml +0 -0
  24. {hdx_python_country-3.6.1 → hdx_python_country-3.6.3}/documentation/main.md +0 -0
  25. {hdx_python_country-3.6.1 → hdx_python_country-3.6.3}/documentation/pydoc-markdown.yaml +0 -0
  26. {hdx_python_country-3.6.1 → hdx_python_country-3.6.3}/pyproject.toml +0 -0
  27. {hdx_python_country-3.6.1 → hdx_python_country-3.6.3}/src/hdx/location/__init__.py +0 -0
  28. {hdx_python_country-3.6.1 → hdx_python_country-3.6.3}/src/hdx/location/country.py +0 -0
  29. {hdx_python_country-3.6.1 → hdx_python_country-3.6.3}/src/hdx/location/names.py +0 -0
  30. {hdx_python_country-3.6.1 → hdx_python_country-3.6.3}/src/hdx/location/phonetics.py +0 -0
  31. {hdx_python_country-3.6.1 → hdx_python_country-3.6.3}/tests/fixtures/adminlevel.yaml +0 -0
  32. {hdx_python_country-3.6.1 → hdx_python_country-3.6.3}/tests/fixtures/global_pcode_lengths.csv +0 -0
  33. {hdx_python_country-3.6.1 → hdx_python_country-3.6.3}/tests/fixtures/global_pcodes_adm_1_2.csv +0 -0
  34. {hdx_python_country-3.6.1 → hdx_python_country-3.6.3}/tests/fixtures/secondary_rates.json +0 -0
  35. {hdx_python_country-3.6.1 → hdx_python_country-3.6.3}/tests/hdx/location/__init__.py +0 -0
  36. {hdx_python_country-3.6.1 → hdx_python_country-3.6.3}/tests/hdx/location/test_country.py +0 -0
@@ -14,4 +14,4 @@ exclude_also =
14
14
  if 0:
15
15
  if __name__ == .__main__.:
16
16
  if TYPE_CHECKING:
17
- @(abc\.)?abstractmethod
17
+ @(abc\.)?abstractmethod
@@ -20,7 +20,7 @@ you make a git commit:
20
20
 
21
21
  pre-commit install
22
22
 
23
- The configuration file for this project is in a
23
+ The configuration file for this project is in a
24
24
  non-start location. Thus, you will need to edit your
25
25
  `.git/hooks/pre-commit` file to reflect this. Change
26
26
  the line that begins with `ARGS` to:
@@ -29,7 +29,7 @@ the line that begins with `ARGS` to:
29
29
 
30
30
  With pre-commit, all code is formatted according to
31
31
  [black]("https://github.com/psf/black") and
32
- [ruff]("https://github.com/charliermarsh/ruff") guidelines.
32
+ [ruff]("https://github.com/charliermarsh/ruff") guidelines.
33
33
 
34
34
  To check if your changes pass pre-commit without committing, run:
35
35
 
@@ -46,8 +46,8 @@ Follow the example set out already in ``api.rst`` as you write the documentation
46
46
  ## Packages
47
47
 
48
48
  [pip-tools](https://github.com/jazzband/pip-tools) is used for
49
- package management. If you’ve introduced a new package to the
50
- source code (i.e.anywhere in `src/`), please add it to the
49
+ package management. If you’ve introduced a new package to the
50
+ source code (i.e.anywhere in `src/`), please add it to the
51
51
  `project.dependencies` section of
52
52
  `pyproject.toml` with any known version constraints.
53
53
 
@@ -23,4 +23,4 @@ SOFTWARE.
23
23
  Regular expressions from countrycode
24
24
  (https://github.com/vincentarelbundock/countrycode) incorporated and relicensed
25
25
  under The MIT License (MIT) with the kind permission of Vincent Arel-Bundock,
26
- Nils Enevoldsen, and CJ Yetman.
26
+ Nils Enevoldsen, and CJ Yetman.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: hdx-python-country
3
- Version: 3.6.1
3
+ Version: 3.6.3
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-email: Michael Rans <rans@email.com>
@@ -17,7 +17,7 @@ cfgv==3.4.0
17
17
  # via pre-commit
18
18
  chardet==5.2.0
19
19
  # via frictionless
20
- charset-normalizer==3.3.1
20
+ charset-normalizer==3.3.2
21
21
  # via requests
22
22
  click==8.1.7
23
23
  # via typer
@@ -29,7 +29,7 @@ distlib==0.3.7
29
29
  # via virtualenv
30
30
  et-xmlfile==1.1.0
31
31
  # via openpyxl
32
- filelock==3.13.0
32
+ filelock==3.13.1
33
33
  # via virtualenv
34
34
  frictionless==5.16.0
35
35
  # via hdx-python-utilities
@@ -37,7 +37,7 @@ hdx-python-utilities==3.6.2
37
37
  # via hdx-python-country (pyproject.toml)
38
38
  humanize==4.8.0
39
39
  # via frictionless
40
- identify==2.5.30
40
+ identify==2.5.31
41
41
  # via pre-commit
42
42
  idna==3.4
43
43
  # via requests
@@ -130,7 +130,7 @@ rfc3986==2.0.0
130
130
  # via frictionless
131
131
  rich==13.6.0
132
132
  # via typer
133
- ruamel-yaml==0.18.2
133
+ ruamel-yaml==0.18.5
134
134
  # via hdx-python-utilities
135
135
  ruamel-yaml-clib==0.2.8
136
136
  # via ruamel-yaml
@@ -173,7 +173,7 @@ validators==0.22.0
173
173
  # via frictionless
174
174
  virtualenv==20.24.6
175
175
  # via pre-commit
176
- wheel==0.41.2
176
+ wheel==0.41.3
177
177
  # via libhxl
178
178
  xlrd==2.0.1
179
179
  # via hdx-python-utilities
@@ -255,4 +255,4 @@ ID,HRinfo ID,RW ID,m49 numerical code,FTS API ID,Appears in UNTERM list,Appears
255
255
  255,346,178,580,166,,,N,N,MP,MNP,,,Northern Mariana Islands,,Northern Mariana Islands (the),,,,,Northern Mariana Islands (The United States of America),Northern Mariana Islands,,,,,,,0,25.56053736,152.1251419,9,Oceania,57,Micronesia,,,mariana,High,USD,1986-01-01,255 - Northern Mariana Islands
256
256
  256,,,680,,,,N,N,,,,,Sark,,,,,,,,Sark,,,,,,,,,,150,Europe,154,Northern Europe,830,Channel Islands,sark,,GBP,1974-01-01,256 - Sark
257
257
  265,425,246,850,245,,,N,N,VI,VIR,,,United States Virgin Islands,,Virgin Islands (U.S.),,"Virgin Islands, U.S.","Virgin Islands, U.S.",,,United States Virgin Islands,,,,,,,0,17.39137826,-64.67699419,19,Americas,419,Latin America and the Caribbean,29,Caribbean,^(?=.*\bu\.?\s?s).*virgin|^(?=.*states).*virgin,High,USD,1974-01-01,265 - United States Virgin Islands
258
- 266,,,,,,,N,N,,,XK,XKX,Kosovo,,,,,,,,Kosovo,,,,,,,,,,150,Europe,39,Southern Europe,,,kosovo,,EUR,1974-01-01,266 - Kosovo
258
+ 266,,,,,,,N,N,,,XK,XKX,Kosovo,,,,,,,,Kosovo,,,,,,,,,,150,Europe,39,Southern Europe,,,kosovo,,EUR,1974-01-01,266 - Kosovo
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '3.6.1'
16
- __version_tuple__ = version_tuple = (3, 6, 1)
15
+ __version__ = version = '3.6.3'
16
+ __version_tuple__ = version_tuple = (3, 6, 3)
@@ -38,7 +38,7 @@ class AdminLevel:
38
38
  admin_level_overrides (Dict): Countries at other admin levels.
39
39
  """
40
40
 
41
- pcode_regex = re.compile(r"^([a-zA-Z]{2,3})(\d*)$")
41
+ pcode_regex = re.compile(r"^([a-zA-Z]{2,3})(\d+)$")
42
42
  _admin_url_default = "https://data.humdata.org/dataset/cb963915-d7d1-4ffa-90dc-31277e24406f/resource/f65bc260-4d8b-416f-ac07-f2433b4d5142/download/global_pcodes_adm_1_2.csv"
43
43
  _admin_url = _admin_url_default
44
44
  _formats_url_default = "https://data.humdata.org/dataset/cb963915-d7d1-4ffa-90dc-31277e24406f/resource/f1161807-dab4-4331-b7b0-4e5dac56e0e4/download/global_pcode_lengths.csv"
@@ -42,6 +42,7 @@ class Currency:
42
42
  _retriever = None
43
43
  _log_level = logging.DEBUG
44
44
  _fixed_now = None
45
+ _threshold = 1.3
45
46
 
46
47
  @classmethod
47
48
  def _get_int_timestamp(cls, date: datetime) -> int:
@@ -173,13 +174,17 @@ class Currency:
173
174
  return None
174
175
 
175
176
  @classmethod
176
- def _get_adjclose(cls, indicators: Dict) -> Optional[float]:
177
+ def _get_adjclose(
178
+ cls, indicators: Dict, currency: str, timestamp: int
179
+ ) -> Optional[float]:
177
180
  """
178
181
  Get the adjusted close fx rate from the indicators dictionary returned
179
182
  from the Yahoo API.
180
183
 
181
184
  Args:
182
185
  indicators (Dict): Indicators dictionary from Yahoo API
186
+ currency (str): Currency
187
+ timestamp (int): Timestamp to use for fx conversion
183
188
 
184
189
  Returns:
185
190
  Optional[float]: Adjusted close fx rate or None
@@ -187,23 +192,72 @@ class Currency:
187
192
  adjclose = indicators["adjclose"][0].get("adjclose")
188
193
  if adjclose is None:
189
194
  return None
195
+
196
+ def beyond_threshold(x, y):
197
+ if max(x, y) / min(x, y) > cls._threshold:
198
+ return True
199
+ return False
200
+
201
+ def within_threshold(x, y):
202
+ if max(x, y) / min(x, y) > cls._threshold:
203
+ return False
204
+ return True
205
+
206
+ # Compare adjclose to other variables returned by Yahoo API
190
207
  adjclose = adjclose[0]
191
- # compare with high and low to reveal errors from Yahoo feed
192
208
  quote = indicators["quote"][0]
209
+ open = quote.get("open")
210
+ fraction_ok = True
211
+ if open:
212
+ open = open[0]
213
+ if beyond_threshold(adjclose, open):
214
+ fraction_ok = False
193
215
  high = quote.get("high")
194
- low = quote.get("low")
195
- if high and low:
216
+ if high:
196
217
  high = high[0]
218
+ if beyond_threshold(adjclose, high):
219
+ fraction_ok = False
220
+ low = quote.get("low")
221
+ if low:
197
222
  low = low[0]
198
- if adjclose > high:
199
- diff = adjclose / high
200
- if diff > 1.1:
201
- adjclose = low + (high - low) / 2
202
- elif adjclose < low:
203
- diff = low / adjclose
204
- if diff > 1.1:
205
- adjclose = low + (high - low) / 2
206
- return adjclose
223
+ if beyond_threshold(adjclose, low):
224
+ fraction_ok = False
225
+ if fraction_ok:
226
+ # if no discrepancies, adjclose is ok
227
+ return adjclose
228
+
229
+ if cls._no_historic:
230
+ secondary_fx_rate = None
231
+ else:
232
+ secondary_fx_rate = cls._get_secondary_historic_rate(
233
+ currency, timestamp
234
+ )
235
+ if not secondary_fx_rate:
236
+ # compare with high and low to reveal errors from Yahoo feed
237
+ if high and low:
238
+ if within_threshold(low, high):
239
+ return low + (high - low) / 2
240
+ return None
241
+
242
+ # compare with secondary historic rate
243
+ if within_threshold(adjclose, secondary_fx_rate):
244
+ return adjclose
245
+ # if adjclose is wacky, find another value to return that is ok
246
+ if high and low:
247
+ if within_threshold(high, secondary_fx_rate) and within_threshold(
248
+ low, secondary_fx_rate
249
+ ):
250
+ return low + (high - low) / 2
251
+ if open:
252
+ if within_threshold(open, secondary_fx_rate):
253
+ return open
254
+ if high:
255
+ if within_threshold(high, secondary_fx_rate):
256
+ return high
257
+ if low:
258
+ if within_threshold(low, secondary_fx_rate):
259
+ return low
260
+ return secondary_fx_rate
207
261
 
208
262
  @classmethod
209
263
  def _get_primary_rate(
@@ -234,7 +288,7 @@ class Currency:
234
288
  if not data:
235
289
  return None
236
290
  if get_close:
237
- return cls._get_adjclose(data["indicators"])
291
+ return cls._get_adjclose(data["indicators"], currency, timestamp)
238
292
  return data["meta"]["regularMarketPrice"]
239
293
 
240
294
  @classmethod