Skip to content

Commit

Permalink
parsing_lib: fix error on get() call for non-dictionaries
Browse files Browse the repository at this point in the history
.get("location", {}).get("country") raises AttributeError
when {"location": None} as None is not a dictionary.

Add deep_get() from export-data/transform.py to common_lib
for access to keys within nested dictionaries.
  • Loading branch information
abhidg committed Feb 24, 2022
1 parent 8088711 commit 4dbe512
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 5 deletions.
14 changes: 14 additions & 0 deletions ingestion/functions/common/common_lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
import functools
from enum import Enum
from pathlib import Path
from typing import Any
from functools import reduce
from typing import Dict

import google
import google.auth.transport.requests
Expand Down Expand Up @@ -179,6 +182,17 @@ def python_module(folder: Path, root: Path):
return None


def deep_get(dictionary: Dict[str, Any], keys: str, default=None) -> Any:
"""
Retrieve values from nested dictionaries
"""
return reduce(
lambda d, key: d.get(key, default) if isinstance(d, dict) else default,
keys.split("."),
dictionary,
)


def get_parser_module(parser):
parser_name = re.sub(r"-ingestor-\w+", r"", parser)
parser_name = re.sub(r"-", r".", parser_name)
Expand Down
9 changes: 4 additions & 5 deletions ingestion/functions/common/parsing_lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,12 +191,11 @@ def prepare_cases(cases: Generator[Dict, None, None], upload_id: str, excluded_c
"""
for case in cases:
case["caseReference"]["uploadIds"] = [upload_id]
if country := case.get("location", {}).get("country"):
if country := common_lib.deep_get(case, "location.country"):
case["location"]["country"] = iso3166_country_code(country)
if case.get("travelHistory") and case.get("travelHistory").get("travel"):
for travel in case["travelHistory"]["travel"]:
if travel_country := travel.get("location", {}).get("country"):
travel["location"]["country"] = iso3166_country_code(travel_country)
for travel in common_lib.deep_get(case, "travelHistory.travel", default=[]):
if travel_country := common_lib.deep_get(travel, "location.country"):
travel["location"]["country"] = iso3166_country_code(travel_country)
if (excluded_case_ids is None) or ("sourceEntryId" not in case["caseReference"]) or (not case["caseReference"]["sourceEntryId"] in excluded_case_ids):
yield remove_nested_none_and_empty(case)

Expand Down

0 comments on commit 4dbe512

Please sign in to comment.