Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow specifying desired countries for AdminLevel #28

Merged
merged 2 commits into from
Oct 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion documentation/main.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,10 +131,13 @@ Method *setup_from_libhxl_dataset* takes a libhxl Dataset object, while
*setup_from_url* takes a URL which defaults to the global p-codes dataset on
HDX.

These methods also have optional parameter *countryiso3s* which is a tuple or
list of country ISO3 codes to be read or None if all countries are desired.

Examples of usage:

adminlevel = AdminLevel(config)
adminlevel.setup_from_admin_info(admin_info)
adminlevel.setup_from_admin_info(admin_info, countryiso3s=("YEM",))
adminlevel.get_pcode("YEM", "YEM030", logname="test") # returns ("YE30", True)
adminlevel.get_pcode("YEM", "Al Dhale"e / الضالع") # returns ("YE30", False)
adminlevel.get_pcode("YEM", "Al Dhale"e / الضالع", fuzzy_match=False) # returns (None, True)
Expand Down
43 changes: 35 additions & 8 deletions src/hdx/location/adminlevel.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,20 +97,31 @@ def get_libhxl_dataset(cls, admin_url: str = _admin_url) -> hxl.Dataset:
)
raise

def setup_from_admin_info(self, admin_info: ListTuple[Dict]) -> None:
def setup_from_admin_info(
self,
admin_info: ListTuple[Dict],
countryiso3s: Optional[ListTuple[str]] = None,
) -> None:
"""
Setup p-codes from admin_info which is a list with values of the form:
::
{"iso3": "AFG", "pcode": "AF01", "name": "Kabul"}
Args:
admin_info (ListTuple[Dict]): p-code dictionary
countryiso3s (Optional[ListTuple[str]]): Countries to read. Defaults to None (all).

Returns:
None
"""
if countryiso3s:
countryiso3s = [
countryiso3.upper() for countryiso3 in countryiso3s
]
for row in admin_info:
countryiso3 = row["iso3"]
pcode = row.get("pcode")
countryiso3 = row["iso3"].upper()
if countryiso3s and countryiso3 not in countryiso3s:
continue
pcode = row.get("pcode").upper()
self.pcodes.append(pcode)
self.pcode_lengths[countryiso3] = len(pcode)
adm_name = row["name"]
Expand All @@ -120,22 +131,33 @@ def setup_from_admin_info(self, admin_info: ListTuple[Dict]) -> None:
self.name_to_pcode[countryiso3] = name_to_pcode
self.pcode_to_iso3[pcode] = countryiso3

def setup_from_libhxl_dataset(self, libhxl_dataset: hxl.Dataset) -> None:
def setup_from_libhxl_dataset(
self,
libhxl_dataset: hxl.Dataset,
countryiso3s: Optional[ListTuple[str]] = None,
) -> None:
"""
Setup p-codes from a libhxl Dataset object.

Args:
libhxl_dataset (hxl.Dataset): Dataset object from libhxl library
countryiso3s (Optional[ListTuple[str]]): Countries to read. Defaults to None (all).

Returns:
None
"""
admin_info = libhxl_dataset.with_rows(
f"#geo+admin_level={self.admin_level}"
)
if countryiso3s:
countryiso3s = [
countryiso3.upper() for countryiso3 in countryiso3s
]
for row in admin_info:
countryiso3 = row.get("#country+code")
pcode = row.get("#adm+code")
countryiso3 = row.get("#country+code").upper()
if countryiso3s and countryiso3 not in countryiso3s:
continue
pcode = row.get("#adm+code").upper()
self.pcodes.append(pcode)
self.pcode_lengths[countryiso3] = len(pcode)
adm_name = row.get("#adm+name")
Expand All @@ -145,18 +167,23 @@ def setup_from_libhxl_dataset(self, libhxl_dataset: hxl.Dataset) -> None:
self.name_to_pcode[countryiso3] = name_to_pcode
self.pcode_to_iso3[pcode] = countryiso3

def setup_from_url(self, admin_url: str = _admin_url) -> None:
def setup_from_url(
self,
admin_url: str = _admin_url,
countryiso3s: Optional[ListTuple[str]] = None,
) -> None:
"""
Setup p-codes from a URL. Defaults to global p-codes dataset on HDX.

Args:
admin_url (str): URL from which to load data. Defaults to global p-codes dataset.
countryiso3s (Optional[ListTuple[str]]): Countries to read. Defaults to None (all).

Returns:
None
"""
admin_info = self.get_libhxl_dataset(admin_url)
self.setup_from_libhxl_dataset(admin_info)
self.setup_from_libhxl_dataset(admin_info, countryiso3s)

def get_pcode_list(self) -> List[str]:
"""Get list of all pcodes
Expand Down
8 changes: 8 additions & 0 deletions tests/hdx/location/test_adminlevel.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ def url(self):
return "https://raw.githubusercontent.com/OCHA-DAP/hdx-python-country/admin_dataset/tests/fixtures/global_pcodes_adm_1_2.csv"

def test_adminlevel(self, config):
adminone = AdminLevel(config)
adminone.setup_from_admin_info(
config["admin_info"], countryiso3s=("yem",)
)
assert len(adminone.get_pcode_list()) == 22
adminone = AdminLevel(config)
adminone.setup_from_admin_info(config["admin_info"])
assert adminone.get_admin_level("YEM") == 1
Expand Down Expand Up @@ -150,6 +155,9 @@ def test_adminlevel_with_url(self, config, url):
assert AdminLevel._admin_url == AdminLevel._admin_url_default
AdminLevel.set_default_admin_url(url)
assert AdminLevel._admin_url == url
adminone.setup_from_url(countryiso3s=("YEM",))
assert len(adminone.get_pcode_list()) == 22
adminone = AdminLevel(config)
adminone.setup_from_url()
assert adminone.get_admin_level("YEM") == 1
assert len(adminone.get_pcode_list()) == 2553
Expand Down
2 changes: 1 addition & 1 deletion tests/hdx/location/test_currency.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ def test_get_current_value_in_usd(self, retrievers, secondary_rates_url):
Currency._secondary_rates = None
rate2gbp = Currency.get_current_rate("gbp")
assert rate2gbp != 1
assert abs(rate1gbp - rate2gbp) / rate1gbp < 0.007
assert abs(rate1gbp - rate2gbp) / rate1gbp < 0.008
Currency.setup(
retriever=retrievers[1],
primary_rates_url="fail",
Expand Down