nazrulworld / fhir.resources Goto Github PK
View Code? Open in Web Editor NEWFHIR Resources https://www.hl7.org/fhir/resourcelist.html
Home Page: https://pypi.org/project/fhir.resources/
License: Other
FHIR Resources https://www.hl7.org/fhir/resourcelist.html
Home Page: https://pypi.org/project/fhir.resources/
License: Other
I need to implement the Contained Resources (https://www.hl7.org/fhir/references.html#contained) and to send the reference resources inside the referred resource. In my case, I need to send a Claim with all reference resources: Patient, Condition, etc.
Is this feature available in fhir.resources?
Thanks.
Hi @nazrulworld
Does this support the FHIR version converter (Hapi-fhir-converter)? e.g. dstu2 to r4, r3 to r4.
Like Grahame Grieve description there should support for fhir_comment. Other than we are facing some trouble like #37
https://www.hl7.org/fhir/extensibility.html#Special-Case
Certainly SMART doesn't impose any limits on how FHIR JSON works -- it sounds like there's some question about how FHIR treats extensions that are present in place of required elements. https://www.hl7.org/fhir/extensibility.html#Special-Case provides the official guidance to corroborate @Md Nazrul Islam's note above that "Maybe... when _intent value is provided then the intent field should be optional." -- indeed, required elements can be missing if extensions are provided.
@Md Nazrul Islam I tested with beta 6.x.x version and this doesn't pass validation:
"_intent": {
"extension": [
{
"url": "http://hl7.org/fhir/StructureDefinition/data-absent-reason",
"valueCode": "unknown"
}
]
},
Am I doing something wrong?
pydantic.error_wrappers.ValidationError: 1 validation error for MedicationRequest
intent
field required (type=value_error.missing)
@_Stephen Whitney|269724 said:
I see thanks @**Md Nazrul Islam**. It passes validation using open hapi fhir server as written at http://hapi.fhir.org/baseR4/Bundle/$validate
Ok, that is something a little bit long discussion need to be done. Maybe there should be when _intent
value is provided then the intent
field should be optional.
Running the following code:
from fhir.resources import construct_fhir_element
d = {'resourceType': 'Patient', 'contained':[{'resourceType': 'Patient'}]}
construct_fhir_element('Patient', d)
end up changing the value of d
to {'resourceType': 'Patient', 'contained': [{}]}
I would expect it to not change the given object. Moreover, because it doesn't delete resourceType
from the outter dictionary, I assume this behavior is not expected.
Is it on purpose?
Thanks,
Itay
I'm attempting to use FHIR (DSTU2) Bundles I already had in my tests against the current version of fhir.resources (all tests pass with version 5.1.1 of fhir.resources) and I'm getting lots of validation errors. This one is the first I've looked into in depth, but I'm hoping that by figuring out this one I'll have a better chance debugging the others on my own.
I have a JSON bundle (attached below, but renamed to .txt
so GitHub would let me upload it) I have tried to use to create a resource object. I continue to get the error value is not a valid list (type=type_error.list)
, but that doesn't make any sense since the value for the coding
is a Python list
.
See iPython screenshot below. The output from [7]
is the most informative, yet super confusing since the value is truly a list
. I've triple-checked the FHIR spec (DSTU2) and everything seems to conform to it, and nothing that I can see in the pydantic model seems to be causing the problem. And creating a Coding
object from data["entry"][0]["resource"]['participant'][0]['type'][0]['coding'][0]
causes no problems either.
I've built a diagnostic report resource but when I print json the resourceType is the last key. I was expecting the resourceType to be the first key. How can I fix this? please
from fhir.resources.diagnosticreport import DiagnosticReport
from fhir.resources.identifier import Identifier
diagnosticreport = DiagnosticReport.construct()
diagnosticreport.status = 'final'
identifier = Identifier()
diagnosticreport.identifier = list()
identifier.value = '21-48608871'
diagnosticreport.identifier.append(identifier)
diagnosticreport.issued = '2021-03-05T11:45:33+11:00'
print(diagnosticreport.json())
{"identifier": [{"value": "21-48608871"}], "issued": "2021-03-05T11:45:33+11:00", "status": "final", "resourceType": "DiagnosticReport"}
Hi all,
This is a really amazing library. I'm a physician, and I'm starting to learn about FHIR and how to use it and this library has been a great starting place.
I'm having a hard time finding documentation on the 'server' attribute that is found in many objects. For example if I create a new patient:
data = {'name':{'given':['Bob'], 'family':'Smith'}}
new_p = Patient(**data)
There is now a new_p.server
attribute. I would like to know if I set the server attribute am I able to then just call new_p.create()
to create an instance on the server? Or if I want to find patients on a server do I just set the search parameters in a Patient
object and then call .search()
.
For context, I've been learning how to post and search for FHIR objects on a locally running HAPI FHIR server with this docker image.
Any help is much appreciated.
EDIT
I now realize that I was using an old version of the library. I would like to know if similar functionality is available in the current version that from the master branch on this repository ('6.0.0b11'
).
Hey,
When would the new version be released with the changes in the change log?
Thanks
In 8fe3dbc, when Black was used on the code and unified the import statements, the import of extension
was moved from the bottom of the file to the top. Any code that uses backboneelement.BackboneElement
(in my case an OperationOutcome) now triggers a cyclical import as can be seen in the attached screenshot. Briefly:
backboneelement
imports extension
extension
imports annotation
annotation
imports fhirreference
fhirreference
imports bundle
bundle
attempts to import backboneelement
, which technically succeeds, but since the first import of backboneelement
hasn't completed, the BackboneElement
class isn't available and the import in bundle
fails.Expected behavior is for an import of operationoutcome.OperationOutcome
to succeed.
Text version of the attached image:
from fhir.resources.DSTU2.operationoutcome import OperationOutcome
File "/home/app/.local/share/virtualenvs/ehr-TNUJx0lF/lib/python3.6/site-packages/fhir/resources/DSTU2/operationoutcome.py", line 8, in <module>
from . import backboneelement, codeableconcept, domainresource
File "/home/app/.local/share/virtualenvs/ehr-TNUJx0lF/lib/python3.6/site-packages/fhir/resources/DSTU2/backboneelement.py", line 8, in <module>
from . import element, extension
File "/home/app/.local/share/virtualenvs/ehr-TNUJx0lF/lib/python3.6/site-packages/fhir/resources/DSTU2/extension.py", line 8, in <module>
from . import (address, annotation, attachment, codeableconcept, coding,
File "/home/app/.local/share/virtualenvs/ehr-TNUJx0lF/lib/python3.6/site-packages/fhir/resources/DSTU2/annotation.py", line 8, in <module>
from . import element, fhirdate, fhirreference
File "/home/app/.local/share/virtualenvs/ehr-TNUJx0lF/lib/python3.6/site-packages/fhir/resources/DSTU2/fhirreference.py", line 116, in <module>
from . import bundle
File "/home/app/.local/share/virtualenvs/ehr-TNUJx0lF/lib/python3.6/site-packages/fhir/resources/DSTU2/bundle.py", line 64, in <module>
class BundleEntry(backboneelement.BackboneElement):
AttributeError: module 'fhir.resources.DSTU2.backboneelement' has no attribute 'BackboneElement'
Is there any option to create an empty Resource Object and set the Parameter via setters ?
In the old version this worked as shown below:
diagnostic_report = DiagnosticReport()
diagnostic_report.id = "foobar"
diagnostic_report.status = "registered"
Disclaimer I am getting started with FHIR.
My high level goal is to implement some basic FHIR resources on a flask API server.
Expose some FHIR search capabilities. Run some basic queries on a backend store, populate FHIR resource objects, return these resources in FHIR-compliant JSON structure response.
>>> from fhir.resources.fhirelementfactory import FHIRElementFactory
>>> json_dict = {"resourceType": "Organization", "id": "foo", "active": True, "name": "acme", "address": [{"country": "us"}]}
>>> org = FHIRElementFactory.instantiate('Organization', json_dict)
>>> org.address[0].country == "Swizterland"
False
>>> org.address[0].country == "us"
True
>>> org.as_json()['active'] is True
True
>>> repr(org)
'<fhir.resources.organization.Organization object at 0x02DF5250>'
>>> org.as_json()
{'id': 'foo', 'active': True, 'address': [{'country': 'us'}], 'name': 'acme', 'resourceType': 'Organization'}
All of this is fine but that JSON is not a true FHIR resource response as I understand it to be. For example it is missing things like resourcetype
Is my understanding of the above correct? Is there a better way? Am I getting too old for programming and need to check myself into a retirement community?
Tried to redeploy an AWS Lambda function to localstack from a Jenkins container. Deploy works the first time, but subsequent deploys throw the error below after updating the Python lambda function code.
The error seems to be thrown when importing CapabilityStatement resource from custom Validator module.
From util.validator.Validator:
from fhir.resources.capabilitystatement import (
CapabilityStatement, CapabilityStatementRestResource)
Result:
File "/tmp/localstack/lambda_script_l_79309ee6.py", line 29, in <module>
from util.validator import Validator
File "/tmp/localstack/zipfile.e257216d/util/validator.py", line 2, in <module>
from fhir.resources.capabilitystatement import (
File "/tmp/localstack/zipfile.9e07ed84/fhir/resources/capabilitystatement.py", line 18, in <module>
class CapabilityStatement(domainresource.DomainResource):
File "/tmp/localstack/zipfile.9e07ed84/fhir/resources/capabilitystatement.py", line 453, in CapabilityStatement
def validate_required_primitive_elements(
File "/tmp/localstack/zipfile.9e07ed84/pydantic/class_validators.py", line 126, in dec
f_cls = _prepare_validator(f, allow_reuse)
File "/tmp/localstack/zipfile.9e07ed84/pydantic/class_validators.py", line 144, in _prepare_validator
raise ConfigError(f'duplicate validator function "{ref}"; if this is intended, set allow_reuse=True')
pydantic.errors.ConfigError: duplicate validator function "fhir.resources.capabilitystatement.CapabilityStatement.validate_required_primitive_elements"; if this is intended, set allow_reuse=True
Greetings, I am investigating this library to use in a ETL step for a data integration and looking to create FHIR data structures. I've never used pydantic before so please forgive my ignorance :) Could I get some help with why this is failing?
I am trying to create an encounter:
from fhir.resources.encounter import Encounter
e: Encounter = Encounter(**{"class": 'inpatient', "status": "planned"})
Results in a confusing error. Especially since it is talking about "jsondecode" error.
Traceback (most recent call last):
File "test.py", line 62, in <module>
fetchsome(cur, handleRow, some=100)
File "test.py", line 39, in fetchsome
rowFunc(row)
File "test.py", line 52, in handleRow
e: Encounter = Encounter(**{"class": 'inpatient', "status": "planned"})
File "...\lib\site-packages\fhir.resources-6.0.0b7.dev0-py3.7.egg\fhir\resources\fhirabstractmodel.py", line 126, in __init__
BaseModel.__init__(__pydantic_self__, **data)
File "pydantic\main.py", line 362, in pydantic.main.BaseModel.__init__
pydantic.error_wrappers.ValidationError: 1 validation error for Encounter
class -> __root__
expected value at line 1 column 1: line 1 column 1 (char 0) (type=value_error.jsondecode; msg=expected value at line 1 column 1; doc=; pos=0; lineno=1; colno=1)
In addition to above Example 5 doesn't seem to work either:
from fhir.resources.organization import Organization
org = Organization.construct()
results in
Traceback (most recent call last):
File "test.py", line 17, in <module>
org = Organization.construct()
File "...\lib\site-packages\fhir.resources-6.0.0b7.dev0-py3.7.egg\fhir\resources\fhirabstractmodel.py", line 386, in construct
m, "__dict__", {**deepcopy(cls.__field_defaults__), **values}
AttributeError: type object 'Organization' has no attribute '__field_defaults__'
I am creating a FHIR object using the models and a spreadsheet as a source
When there is repeating element and their is no data in the source, my code creates an empty list.
This empty list is preserved unlike when the element is None. I think when an element is evaluated to these Falsy types listed below I think it should behave the same ... namely the element value should be None
. Note that in FHIR "when present, elements cannot be empty - they SHALL have a value attribute, child elements, or extensions".
cs = construct_fhir_element('CapabilityStatement',dict(
id = meta.id,
url = f'{canon}CapabilityStatement/{meta.id}',
version = meta.version,
# more elements
instantiates = [i for i in meta.instantiates.split(',') if i], #<<<< this evaluates to '[]' instead of None
))
Note that I can code around this but I think this should be the default behavior of the classes as a convienence.
FastAPI supports using pydantic models to define JSON response bodies for REST API endpoints; making FHIR resources compatible with this support would take the usability of the library to a higher level.
I'm new to the library so I don't know more about how it uses pydantic other than what is stated in the README; in any case, however pydantic is currently used, it doesn't seem to be compatible on first look. The only requirement for compatibility with FastAPI is that the response model class is derived from pydantic's BaseModel
.
A super basic example using the Practitioner
resource from release 5.1.1, with FastAPI 0.62.0 and pydantic 1.7.3, is as follows:
from fastapi import APIRouter
from fhir.resources.practitioner import Practitioner
router = APIRouter()
@router.get(
"/practitioner",
response_model=Practitioner,
)
def get_practitioner(
) -> Any:
return Practitioner()
This gives a couple of runtime errors on endpoint setup:
RuntimeError: no validator found for <class 'fhir.resources.practitioner.Practitioner'>, see `arbitrary_types_allowed` in Config
Invalid args for response field! Hint: check that <class 'fhir.resources.practitioner.Practitioner'> is a valid pydantic field type
This makes some sense, as the Practitioner
resource (and most other resources, it would seem) derive from FHIRAbstractBase
, and not pydantic's BaseModel
.
Is FastAPI support something that's been considered already? Am I missing anything obvious regarding the use of pydantic?
I am creating a FHIR object using the models and a spreadsheet as a source
When there is repeating element and their is no data in the source, my code creates an empty list.
This empty list is preserved unlike when the element is None. I think when an element is evaluated to these Falsy types listed below I think it should behave the same ... namely the element value should be None
. Note that in FHIR "when present, elements cannot be empty - they SHALL have a value attribute, child elements, or extensions".
cs = construct_fhir_element('CapabilityStatement',dict(
id = meta.id,
url = f'{canon}CapabilityStatement/{meta.id}',
version = meta.version,
# more elements
instantiates = [i for i in meta.instantiates.split(',') if i],
imports = [i for i in meta.imports.split(',') if i], #<<<< this evaluates to '[]' instead of None
))
print(cs.json(indent=2))
...
"kind": "requirements",
"instantiates": [
"foo"
],
"imports": [], <<<<<<<<<<<<< the empty list as value!
"fhirVersion": "4.0.1",
....
As a convenience, I would like to see these falsy values be treated like None instead of persisting.
when instantiate a FHIR Resource with a required valueset - Observation.status, I expected it to be validated based upon the fixed set of codes ( http://hl7.org/fhir/valueset-observation-status.html ). What is the status of code validataion? I think that it would possble to at least validate the required bindings where the codes are enumerated.
from fhir.resources import construct_fhir_element
obs = construct_fhir_element('Observation', {"status":"foo", "code": {}})
I expected the value "foo" to cause a pydantic validation error.
It seems that the validation success depends on when resource.id
is set - at least that's my interpretation for now. Is this expected behavior?
The following crashes with a validation error:
from fhir.resources.observation import Observation
o = Observation.construct()
o.id = "o123"
o.status = "final"
print(o.json())
pydantic.error_wrappers.ValidationError: 1 validation error for Observation
__root__ -> status
none is not an allowed value (type=type_error.none.not_allowed)
but switching o.id
and o.status
around works fine:
from fhir.resources.observation import Observation
o = Observation.construct()
o.status = "final"
o.id = "o123"
print(o.json())
{"id": "o123", "status": "final", "resourceType": "Observation"}
As far as I can see, there is no method __eq__
implemented. Am I missing something? Is it supposed to be added in the future?
Thanks
When creating a resource with construct_fhir_element
and specifying a date as a string, the date is not converted to Date
but rather stay as string. Yet, the regex pattern is verified.
I tried multiple resources and it happens for all of them.
from fhir.resources import construct_fhir_element
p = construct_fhir_element('Patient', {'birthDate': '2012'})
print(p.birthDate) # prints `"2012"`
print(type(p.birthDate)) # prints `str`
The same happen when using Patient.parse_obj
.
Edit:
The following Patient.parse_obj({'birthDate': '2012-01-01'}).birthDate
indeed returns datetime.date
.
If resource.id element has an underscore, validation fails
resource = {'resourceType': 'Patient', 'id': 'abc_1234'}
Patient(**resource)
pydantic.error_wrappers.ValidationError: 1 validation error for Patient
id
string does not match regex "^[A-Za-z0-9-.]+$" (type=value_error.str.regex; pattern=^[A-Za-z0-9-.]+$)
Hi I am a newbie to FHIR data formats. This might be a dumb questions as well, is there any easy way to convert bunch of XML's to FHIR format? any suggestions on blog/tutorials for reference?
Any help is appreciated!!
Describe what you were trying to get done.
Tell us what happened, what went wrong, and what you expected to happen.
Paste the command(s) you ran and the output.
If there was a crash, please include the traceback here.
I've been taking a look at the pydantic refactored code, and I think it's going to be a great thing for the project. As I've looked at how to adapt my code to the changes, one thing has come up that I can't quite find a good answer for.
In the project I'm working on, there are lots of instances where I need to be able to compare one Period with another. For example, I need to know which period is more recent than another. This gets really tricky because FHIR's dateTime values have such a wide range of acceptable granularity. For example, I might need to decide if a period with a starting year, month, and day is more recent than a period with an ending year and month (but no day).
The solution I came up with previously was to not depend on the Python datetime
objects offered by the previous (<=5.0.1) versions of fhir.resources
, but instead parse the FHIR start and end dateTime
values myself and slightly differently, with start dates filling any missing values for month, day, hour, minute, second, and microsecond with the lowest (earliest) value (e.g., month=1, hour=0, etc). Likewise, I parsed end dateTime
values by filling any missing values with the highest (latest) value possible (e.g., month=12, minute=59).
The above solution depended on using the origval
property of the fhir.resources.period.Period
object, which I used as input to the custom parsers I just described. And this is where the problem arises: The new pydantic models do not retain the original string extracted from the FHIR-formatted JSON.
I've tried to do some research into possible ways to address this, but due to my lack of familiarity with the ins and outs of pydantic, I've probably missed some viable solutions. Anyway, here are some ideas:
Alter the pydantic models for Date
, DateTime
, Instant
, and Time
to make the original string value available (the ones defined in fhir/resources/{DSTU2,STU3,}/fhirtypes.py
. I list this first because I think it will be the least labor-intensive, assuming there's a way to actually accomplish this with pydantic. From what I understand, these model types would need to use generic classes
validate
methods instead of the classes from the datetime
library. This is only a half-con though since I think the pydantic docs recommend doing it that way anyway.Create a custom class for Periods that allow for fuzzy data (according to the FHIR spec) while also providing operators that allow for comparison in a way that makes sense (I drew up a few examples of this but eventually decided they were confusing).
That's all I've got so far. I'm hoping that by discussing this we can find something that will be useful to many of the library's users.
Confusing error message "name 'self' is not defined" when using method "update_with_json(self, jsondict)", while providing an incorrect format for jsondict.
The cause of this confusing message I belive is a bug in FHIRAbstractBase._with_json_dict(cls, jsondict). The body of this classmethod refers to "self" which is not defined in this namespace.
(note: I have no experience on github, I hope this is the correct way to report small bugs)
STU3 code not included in pypy version.
I used 'pip install' to install this package expecting to be able to use the code to support STU3 and R4 projects. However I discovered that the STU3 code was missing.
would like to add native YAML support so that a Resource object can be created from YAML object or file and serialize as a YAML string.
e.g:
>>> from fhir.resources.organization import Organization
>>> from fhir.resources.address import Address
>>> yaml_str = '''
resourceType: Organization
id: f001
active: true
name: Acme Corporation
address:
- country: Swizterland
'''
>>> org = Organization.parse_raw(yaml_str)
>>> isinstance(org.address[0], Address)
>>> True
>>> org.address[0].country == "Swizterland"
True
>>> org.dict()['active'] is True
True
and
>>> from fhir.resources.patient import Patient
>>> import os
>>> import pathlib
>>> filename = pathlib.Path("foo/bar.yaml")
>>> pat = Patient.parse_file(filename)
>>> pat.resource_type == "Patient"
True
and
>>> pat.as_yaml()
'''
resourceType: Organization
id: f001
active: true
name: Acme Corporation
address:
- country: Swizterland
'''
See pyyaml.org
Im using python 3.8 and trying to upgrade from version 6.0.0b5 to 6.1.0.
The code is
from fhir.resources.codeableconcept import CodeableConcept
from fhir.resources.condition import Condition
Condition(subject={}, code=CodeableConcept()).code.coding
When using version 6.0.0b5 and running mypy --ignore-missing-imports a.py
I get:
Success: no issues found in 1 source file
Using version 6.1.0 and running the same function I get:
a.py:4: error: "CodeableConceptType" has no attribute "coding"
Found 1 error in 1 file (checked 1 source file)
Looking at the classes, we can see that the annotations are using FooType
, for example CodeableConceptType
and not CodeableConcept
which makes mypy not being able to parse the library.
If I understand correctly, the rational to use FooType
classes is otherwise we would have circle imports.
How can we make mypy parse this library?
Or, what changed between 6.0.0b5 to 6.1.0 that can affect it? Were type hints added to the library? If so, I think its wrong to do so :)
When installing the package, the "tests" folder is being installed which takes 10MB from the system. It might not sound a lot but when using AWS serverless applications, you have 250MB storage and 10MB can be critical.
The problem is in the project "setup.py" by using "find_packages" which finds the tests directory.
It needs to be filtered out.
Opened a ticket ๐
FHIR allows for (for example) Strings to have extensions.
An example of that can be found here: https://www.hl7.org/fhir/extensibility-examples.html#2.5.2.2.3
In the json representation this looks like this:
{
"name": [
{
"given": [
"Adam",
"A",
"Adam"
],
"_given": [
{
"extension": [
{
"url": "http://hl7.org/fhir/StructureDefinition/iso21090-EN-qualifier",
"valueCode": "BR"
}
]
},
{
"extension": [
{
"url": "http://hl7.org/fhir/StructureDefinition/iso21090-EN-qualifier",
"valueCode": "IN"
}
]
},
{
"extension": [
{
"url": "http://hl7.org/fhir/StructureDefinition/iso21090-EN-qualifier",
"valueCode": "CL"
}
]
}
]
}
]
}
What I get though, is a simple python string, so I've lost the extensions.
patient = fhir.resources.STU3.patient.Patient(**json.loads("[json here]"))
patient.name[0].given
['Adam', 'A', 'Adam']
Here's a full example:
import json
import fhir.resources.STU3.patient
patient_json = """
{
"resourceType": "Patient",
"name": [
{
"given": [
"Adam",
"A",
"Adam"
],
"_given": [
{
"extension": [
{
"url": "http://hl7.org/fhir/StructureDefinition/iso21090-EN-qualifier",
"valueCode": "BR"
}
]
},
{
"extension": [
{
"url": "http://hl7.org/fhir/StructureDefinition/iso21090-EN-qualifier",
"valueCode": "IN"
}
]
},
{
"extension": [
{
"url": "http://hl7.org/fhir/StructureDefinition/iso21090-EN-qualifier",
"valueCode": "CL"
}
]
}
]
}
]
}
"""
patient = fhir.resources.STU3.patient.Patient(**json.loads(patient_json))
print(patient.name[0].given)
# (Pdb) patient.name[0].given
# ['Adam', 'A', 'Adam']
I noticed that all the optional objects which has amount of 0...1
are defaulted to None
which is logical.
Why do we set the default value for fields with amount 0...*
to be None
as well and not []
?
I'm implementing FHIR, version DSTU2 works perfectly but I'd like to know if there is any way to parse the resources (MessageHeader, Patient, ...) to XML format?
According to the documentation "binary.as_json()" is the way to convert to Json format but I'm not sure if there is a function to convert to XML
Hey there! Thanks for all the great work on this package! Looking to start using this pretty heavily internally, so many niceties come out of the box with pydantic-based libraries like this.
One slight hiccup I'm seeing in the dev experience is the mismatch between the type annotation and the actual underlying type at runtime.
For example, the fhir.resources.patient.Patient
model has a field type of address: typing.List[fhirtypes.AddressType]
where AddressType
looked like a wrapper around plain dict
. Initially I thought this was a little weird, but maybe makes sense if we wanted to postpone validation until that specific field was used and unpacked into its corresponding pydantic type.
When I went to implement our address functionality, I used logic to the effect of address_pydantic = Address(**patient.address[0])
which threw the following error:
TypeError: ModelMetaclass object argument after ** must be a mapping, not Address
So at runtime, the real type of patient.address
is List[fhir.resources.address.Address]
rather than the dict
based type provided in the annotations.
This unfortunately poses an issue for typecheckers such as mypy. The typechecker expects the value to be an AbstractType
during runtime, so it won't allow the usage of pydantic fields (for example patient.address[0].state
) unless we put cast(
calls all over the place, opening ourselves up to type-related bugs that we were trying to avoid by using a pydantic-based lib.
Would you mind expanding on this design decision to have the AbstractType
annotations on each of the pydantic type's fields, instead of the actual pydantic type that is seen at runtime? Does anyone else use typecheckers in combination with this library, without needing to cast
everywhere? (Certainly open to using a different type checking system as well if this is just a limitation of mypy)
There very well could be information out there on this topic already, however I was not able to find it in the docs. Let me know if I missed it or if my library usage above does not align with what is expected!
I'm new to FHIR, but I'm confused why the address "line" is required to be a list? According to the official documentation it should be a string.
https://www.hl7.org/fhir/datatypes-definitions.html#Address.line
I'm trying to construct a basic resource with extension fields. In the example below I'm trying to add an extension to Patient resource.
result = fhir.resources.patient.Patient(**{
'id': str(self.id),
'_banana': {
'extension': [{
'url': 'https://tempuri.org',
'valueInteger': self.specialid,
}],
},
...
)
_banana
extra fields not permitted (type=value_error.extra).
I would like to run the test suite for DSTU (or at least review the test example files), but the json files that the tests use don't seem to be included in this repo.
We have yet many DSTU2 FHIR resources to be created, here the list.
Validating claim without focal
.
It's mandatory in Python: https://github.com/nazrulworld/fhir.resources/blob/5.1.1/fhir/resources/claim.py#L671
("focal", "focal", bool, "boolean", False, None, True)
(Where the last True
is for not_optional
or mandatory/required as far as I could see.)
(BTW, the same is true for Golang - https://github.com/samply/golang-fhir-models/blob/c26453f28c9f71b1e4e6870ecd633d38b665f005/fhir-models/fhir/claim.go#L116)
In the json schema this field is not required:
"Claim_Insurance": {
"properties": {
"focal": {
"description": "A flag to indicate that this Coverage is to be used for adjudication of this claim when set to true.",
"$ref": "#/definitions/boolean"
},
"_focal": {
"description": "Extensions for focal",
"$ref": "#/definitions/Element"
},
"coverage": {
"description": "Reference to the insurance card level information contained in the Coverage resource. The coverage issuing insurer will use these details to locate the patient\u0027s actual coverage within the insurer\u0027s information system.",
"$ref": "#/definitions/Reference"
}
},
"additionalProperties": false,
"required": [
"coverage"
]
},
with open("claim.json") as claim_file:
claim_json = json.load(claim_file)
claim = Claim(claim_json)
return claim
I use fhir.resources
as part of my work for a company that integrates with EHR systems using FHIR. The two biggest EHR systems I know of (Epic and Cerner) currently only support FHIR v1.0.2 (DSTU 2). My understanding is that there were so many issues with STU3 that hardly systems will ever support it and will instead migrate from DSTU 2 straight to R4. (I promise I'm not trying to sound dramatic here, that's literally what my company's Product team has told me these companies have said.)
Recent changes (specifically commit 4eb0790) remove support for DSTU 2, which effectively makes the latest version of the fhir.resources
library unusable for my team.
If I may ask, what was the reasoning behind the removal of support for DSTU 2? Is there something I could contribute to make it worth the effort to continue supporting that version of the FHIR spec?
Resolution of references within a Bundle fails unless an instance to a server is provided (and a couple of additional undocumented assumptions are met).
The problem is in fhir.resources.fhirresource.FHIRResource.resolved(). In case of a relative reference, the method attempts to build the fullUrl
based on the value of bundle.server.base_uri
. If no server instance is set, resolution fails.
The standard states
If the reference is not an absolute reference, convert it to an absolute URL:
if the reference has the format [type]/[id], and
if the fullUrl for the bundle entry containing the resource is a RESTful one (see the RESTful URL regex)
extract the [root] from the fullUrl, and append the reference (type/id) to it
then try to resolve within the bundle as for a RESTful URL reference.
If no resolution is possible, then the reference has no defined meaning within this specification
The important part is extract the [root] from the fullUrl, and append the reference (type/id) to it
. For example:
base_uri = '/'.join(bundle_entry.fullUrl.split('/')[:-2])
fullUrl = f'{base_uri}/{resource_type}/{resource_id}'
The bundle.server.base_uri
is not needed (and should not be expected to be present).
import requests
from fhir.resources.bundle import Bundle
from fhir.resources.patient import Patient
response = requests.get('https://www.hl7.org/fhir/bundle-example.json')
bundle = Bundle(response.json())
patient = bundle.entry[0].resource.subject.resolved(Patient)
results in
Not implemented: resolving absolute reference to resource Patient/347
I am supporting several FHIR projects and I need support for DSTU2 and well as STU3 and R4.
I looked at the code and discovered that code supporting STU3 was included, but not DSTU2.
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.
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
Describe what you were trying to get done.
I am trying to discover the simplest and most direct way to discover the type for an element:
ideally this :
1 from fhir.resources.observation import Observation
2
----> 3 Observation.resource_type
AttributeError: type object 'Observation' has no attribute 'resource_type'
obviously this isn't going to work on this instance but don't know the best way to do this on the
class
obs_obj = Observation.parse_file("Observation_wt.yml")
for i in obs_obj.element_properties():
try:
print(f'i.name={i.name}, itype = {i.type_.__resource_type__}')
except:
print(f'i.name={i.name}')
i.name=id
i.name=implicitRules
i.name=language
i.name=meta, itype = Meta
i.name=contained, itype = Resource
i.name=extension, itype = Extension
i.name=modifierExtension, itype = Extension
i.name=text, itype = Narrative
i.name=basedOn, itype = Reference
i.name=bodySite, itype = CodeableConcept
i.name=category, itype = CodeableConcept
i.name=code, itype = CodeableConcept
i.name=component, itype = ObservationComponent
i.name=dataAbsentReason, itype = CodeableConcept
i.name=derivedFrom, itype = Reference
i.name=device, itype = Reference
i.name=effectiveDateTime
i.name=effectiveInstant
i.name=effectivePeriod, itype = Period
i.name=effectiveTiming, itype = Timing
i.name=encounter, itype = Reference
i.name=focus, itype = Reference
i.name=hasMember, itype = Reference
i.name=identifier, itype = Identifier
i.name=interpretation, itype = CodeableConcept
i.name=issued
i.name=method, itype = CodeableConcept
i.name=note, itype = Annotation
i.name=partOf, itype = Reference
i.name=performer, itype = Reference
i.name=referenceRange, itype = ObservationReferenceRange
i.name=specimen, itype = Reference
i.name=status
i.name=subject, itype = Reference
i.name=valueBoolean
i.name=valueCodeableConcept, itype = CodeableConcept
i.name=valueDateTime
i.name=valueInteger
i.name=valuePeriod, itype = Period
i.name=valueQuantity, itype = Quantity
i.name=valueRange, itype = Range
i.name=valueRatio, itype = Ratio
i.name=valueSampledData, itype = SampledData
i.name=valueString
i.name=valueTime
```
Is there an easier way?
I want FHIRAbstractModel
to be able to validate enum values. I think it's already supported by the current version but I couldn't find how to do it.
class Patient(domainresource.DomainResource):
...
gender: fhirtypes.Code = Field(
None,
alias="gender",
title="male | female | other | unknown",
description=(
"Administrative Gender - the gender that the patient is considered to "
"have for administration and record keeping purposes."
),
# if property is element of this resource.
element_property=True,
# note: Enum values can be used in validation,
# but use in your own responsibilities, read official FHIR documentation.
enum_values=["male", "female", "other", "unknown"],
)
I don't quite understand what this means:
note: Enum values can be used in validation, but use in your own responsibilities, read official FHIR documentation.
because the pydantic model does not enforce the value of this field.
from fhir.resources import construct_fhir_element
resource = {"resourceType": "Patient", "gender": "toto"}
construct_fhir_element(resource["resourceType"], resource)
# everything went fine, but it should raise a validation error
Describe what you were trying to get done.
Tell us what happened, what went wrong, and what you expected to happen.
I have a record of ExplanationOfBenefit in json format.
When I pass it to fhir.resources.ExplanationOfBenefit it get the following error.
ValidationError: 2 validation errors for ExplanationOfBenefit __root__ -> created field required (type=value_error.missing) __root__ -> outcome field required (type=value_error.missing)
record = records[5945] from fhir.resources.explanationofbenefit import ExplanationOfBenefit Eob = ExplanationOfBenefit(**record)
How can I know what values are missing and is there a way to print the missing values
While writing tests I found a bug in Specimen
resource. It looks like his backbone elements are not defined correctly. I'm not sure what I am missing.
A result for example:
E pydantic.error_wrappers.ValidationError: 3 validation errors for Specimen
E collection
E (type=value_error)
E treatment -> 0
E (type=value_error)
E container -> 0
E (type=value_error)
You can run the tests in the following branch:
https://github.com/ItayGoren/fhir.resources/tree/bug-with-specimen
Thanks
I'm trying to construct a Patient
resource after fetching it via a FHIR call.
I fetched some data and tried to construct it using the Patient
model class.
The contact field for the resulting patient information was
"contact": [
{
"relationship": [{ /* a relationship object */}],
"name": { /* a name object */ },
"telecom": [{
"extension": [{
"valueUrl": "(123)123-1234",
"url": "http://hl7.org/fhir/StructureDefinition/iso21090-TEL-address"
}],
/* rest of the telecom object*/
}]
}],
contact -> 0 -> telecom -> 0 -> extension -> 0 -> valueUrl
invalid or missing URL scheme (type=value_error.url.scheme)
The url rfc defines that parenthesis are not valid so the sender seems to be at fault. Is there any way for me to continue to use the library to construct this Patient
resource and specifically ignore validating this field?
There's no issue as such. I'm trying to create a Django model using this project, for example, the patient resource.
Does this package support creation of a model?
I think it would be great if it where possible to map pydantic validation errors to proper fhir locations for `OperationOutcome' https://hl7.org/fhir/STU3/operationoutcome.html#loc
Do you have some thoughts/guidance on that. I might try to implement something like that.
The fhir.resources DateTime
object is not spec compliant. The spec (and the doc comments) both require a +zz:zz
or Z
timezone suffix, it is using datetime.isoformat()
which does not do this. Python isoformat()
violates ISO8601 https://stackoverflow.com/a/23705687/1480205
See DateTime.to_string
https://github.com/nazrulworld/fhir.resources/blob/main/fhir/resources/fhirtypes.py#L511
We are trying to interoperate with a partner and they are unable to consume the FHIR JSON we generate since the DateTimes are all wrong. We think a workaround will be to correctly pre-format the datetime
and use the str
instead of the actual datetime
object, it looks like to_string
will leave it alone in that case.
All DateTimes in FHIR objects are of the form 2021-05-07T21:41:57.120530
This is not compliant with the doc comment or the spec https://www.hl7.org/fhir/datatypes.html#dateTime
>>> from fhir.resources.annotation import Annotation
>>> import datetime
>>> a = Annotation(text="abc", time=datetime.datetime.utcnow())
>>> a.dict()
{'text': 'abc', 'time': datetime.datetime(2021, 5, 7, 22, 33, 55, 557605)}
>>> a.json()
'{"text": "abc", "time": "2021-05-07T22:33:55.557605"}'
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.