Skip to content

Commit

Permalink
adapt to be able to have nested extensions of different lengths
Browse files Browse the repository at this point in the history
  • Loading branch information
pipliggins committed Aug 20, 2024
1 parent 43b8ef5 commit 3d99fe7
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 48 deletions.
51 changes: 25 additions & 26 deletions fhirflat/flat2fhir.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
get_fhirtype,
get_local_extension_type,
group_keys,
json_type_matching,
)


Expand Down Expand Up @@ -189,28 +190,6 @@ def set_datatypes(k, v_dict, klass) -> dict:
# datatype should be a primitive
return {"url": k, f"{value_type}": v_dict[k]}

# else:
# # more than one possible value type
# # if there's more than one, maybe re-arrange the dict using each value
# # type and try to call expand_concepts again?
# for v_type in value_type:
# data_type = prop[v_type]["type"]
# try:
# data_class = get_fhirtype(data_type)
# new_dict = v_dict[k]
# new_dict = expand_concepts(new_dict, data_class)
# # do some kind of check that the new_dict is the right type
# try:
# data_class(**new_dict)
# # return {f"{k}.value{data_type}": new_dict}
# return {k: {f"value{data_type}": new_dict}}
# # return {"url": k, f"{v_type}": new_dict}
# except ValidationError:
# continue
# except AttributeError:
# # is this the right error?
# continue

return {s.split(".", 1)[1]: v_dict[s] for s in v_dict}


Expand All @@ -220,9 +199,21 @@ def find_value_type(k: str, v_dict, klass):

if not value_type:
classes = find_data_class_options(klass, "extension")
short_extensions = [s for s in v_dict[k].keys() if s.count(".") == 0]
expanded_short_extensions = []
if short_extensions:
# these get skipped over in expand_concepts so have to be dealt with here
for se in short_extensions:
short_ext_dict = {se: v_dict[k][se]}
short_ext = find_data_class_options(classes, se)
expanded_short_extensions.append(
find_value_type(se, short_ext_dict, short_ext)
)
v_dict[k].pop(se)
return {
"url": k,
"extension": list(expand_concepts(v_dict[k], classes).values()),
"extension": list(expand_concepts(v_dict[k], classes).values())
+ expanded_short_extensions,
}

if len(value_type) == 1:
Expand All @@ -241,14 +232,22 @@ def find_value_type(k: str, v_dict, klass):
try:
data_class = get_fhirtype(data_type)
new_dict = v_dict[k]
new_dict = expand_concepts(new_dict, data_class)
new_dict = (
expand_concepts(new_dict, data_class)
if isinstance(new_dict, dict)
else new_dict
)
try:
data_class(**new_dict)
data_class.parse_obj(new_dict)
return {"url": k, f"{v_type}": new_dict}
except ValidationError:
continue
except AttributeError as e:
raise e
# should be a standard json type as a string
if isinstance(v_dict[k], json_type_matching(data_type)):
return {"url": k, f"{v_type}": v_dict[k]}
else:
raise e


def expand_concepts(data: dict[str, str], data_class: type[_DomainResource]) -> dict:
Expand Down
17 changes: 17 additions & 0 deletions fhirflat/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,3 +211,20 @@ def condense_codes(row: pd.Series, code_col: str) -> pd.Series:

row[code_col + ".code"] = codes
return row


def json_type_matching(t: str):
"""
Matches a JSON type to a Python type.
"""
tps = {
"string": str,
"integer": int,
"number": float,
"boolean": bool,
"array": list,
"object": dict,
"null": None,
}

return tps[t]
Binary file modified tests/data/immunization_flat.parquet
Binary file not shown.
63 changes: 41 additions & 22 deletions tests/test_immunization_resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,25 @@
"status": "completed",
"extension": [
{
"url": "timingPhase",
"valueCodeableConcept": {
"coding": [
{
"system": "http://snomed.info/sct",
"code": 278307001,
"display": "on admission",
}
]
},
"url": "timingPhaseDetail",
"extension": [
{
"url": "timingPhase",
"valueCodeableConcept": {
"coding": [
{
"system": "http://snomed.info/sct",
"code": 278307001,
"display": "on admission",
}
]
},
},
{
"url": "timingDetail",
"valueString": "ever",
},
],
},
],
"vaccineCode": {
Expand Down Expand Up @@ -104,8 +113,9 @@

IMMUNIZATION_FLAT = {
"resourceType": "Immunization",
"extension.timingPhase.code": "http://snomed.info/sct|278307001",
"extension.timingPhase.text": "on admission",
"extension.timingPhaseDetail.timingPhase.code": "http://snomed.info/sct|278307001",
"extension.timingPhaseDetail.timingPhase.text": "on admission",
"extension.timingPhaseDetail.timingDetail": "ever",
"occurrenceDateTime": datetime.date(2021, 9, 12),
"_occurrenceDateTime.relativeDay": 3.0,
"_occurrenceDateTime.approximateDate": "month 3",
Expand Down Expand Up @@ -133,16 +143,25 @@
"status": "completed",
"extension": [
{
"url": "timingPhase",
"valueCodeableConcept": {
"coding": [
{
"system": "http://snomed.info/sct",
"code": 278307001,
"display": "on admission",
}
]
},
"url": "timingPhaseDetail",
"extension": [
{
"url": "timingPhase",
"valueCodeableConcept": {
"coding": [
{
"system": "http://snomed.info/sct",
"code": 278307001,
"display": "on admission",
}
]
},
},
{
"url": "timingDetail",
"valueString": "ever",
},
],
},
],
"vaccineCode": {
Expand Down

0 comments on commit 3d99fe7

Please sign in to comment.