nazrulworld / fhir.resources

FHIR Resources https://www.hl7.org/fhir/resourcelist.html
https://pypi.org/project/fhir.resources/
Other
372 stars 104 forks source link

Error creating resource object #54

Closed julsas closed 3 years ago

julsas commented 3 years ago

Description

Creation of resource objects fails for some data types when parsing and creating resource objects from json data. This is the case for decimal within e.g. Quantity and for datetime. Calling .dict() on the object does not return a valid python dict.

What I Did

with open('./Medication-example.json') as json_file:
    json_data = json.load(json_file)

med = Medication.parse_obj(json_data)
med = med.dict()
print(med)

{'id': 'demo-medication-3', 'code': {'coding': [{'code': '116602009', 'display': 'Prednisone (substance)', 'system': 'http://snomed.info/sct'}, {'code': 'H02AB07', 'display': 'prednisone', 'system': 'http://www.whocc.no/atc'}], 'text': 'Deltacortene tablet 25 mg'}, 'form': {'coding': [{'code': '10219000', 'display': 'Tablet', 'system': 'urn:oid:0.4.0.127.0.16.1.1.2.1'}]}, 'ingredient': [{'itemCodeableConcept': {'coding': [{'code': '116602009', 'display': 'Prednisone (substance)', 'system': 'http://snomed.info/sct'}]}, 'strength': {'denominator': {'code': '1', 'system': 'http://unitsofmeasure.org', 'unit': 'tablet', 'value': Decimal('1')}, 'numerator': {'code': 'mg', 'system': 'http://unitsofmeasure.org', 'value': Decimal('25')}}}], 'resourceType': 'Medication'}

med == dict
False

print(json.dumps(med, indent=4))
TypeError: Object of type 'Decimal' is not JSON serializable

---

with open('./Observation-example.json') as json_file:
    json_data = json.load(json_file)

obs = Observation(**json_data)
obs = obs.dict()
print(obs)

{'code': {'coding': [{'code': '718-7', 'display': 'Hemoglobin [Mass/volume] in Blood', 'system': 'http://loinc.org'}], 'text': 'Hemoglobin'}, 'effectiveDateTime': datetime.datetime(2021, 1, 18, 11, 5, 52, tzinfo=datetime.timezone(datetime.timedelta(0, 3600))), 'status': 'final', 'subject': {'reference': 'Patient/156ff0c4-5122-41ca-8bf5-32faf8d3f3a1'}, 'valueQuantity': {'code': 'g/dL', 'system': 'http://unitsofmeasure.org', 'unit': 'g/dL', 'value': Decimal('9.3')}, 'resourceType': 'Observation'}

print(json.dumps(obs, indent=4))
TypeError: Object of type 'datetime' is not JSON serializable
nazrulworld commented 3 years ago

It is always recommended that use the built-in method json. For example in your case

obs = Observation(**json_data)
print(obs.json(indent=2))

If you really want to use json.dumps (python built-in), then you have to do a little bit of extra

import json
from pydantic.json import pydantic_encoder
obs = Observation(**json_data)
obs = obs.dict()
print(json.dumps(obs,indent=2, default=pydantic_encoder))
julsas commented 3 years ago

Thanks for the clarification! I hadn't figured out that I needed the pydantic_encoder.