FHIR Chat · listing all elements using models · python

Stream: python

Topic: listing all elements using models


view this post on Zulip Eric Haas (Jan 16 2019 at 17:36):

using the model I can easily list all the objects props using...

for i in [type]().elementProperties():
print(i)

e.g.
(ignoring my r4 hack for _elements)

for i in p.elementProperties():
    print(i[0])

id
implicitRules
_implicitRules
language
_language
meta
contained
extension
modifierExtension
text
active
_active
address
birthDate
communication
contact
deceasedBoolean
_deceasedBoolean
deceasedDateTime
gender
_gender
generalPractitioner
identifier
link
managingOrganization
maritalStatus
multipleBirthBoolean
_multipleBirthBoolean
multipleBirthInteger
_multipleBirthInteger
name
photo
telecom

but I would like to know if there is a simple way to do something like...

for i in [type].[element].elementProperties():
print(i)

(Note this is desired but  does not work like this!!)
for i in p.name.elementProperties():
    print(i[0])

Coding
text

for j in p.name.Coding.elementProperties():
   print (j[0])

code
display
text

~~~~

view this post on Zulip Eric Haas (Jan 16 2019 at 17:39):

like using namedTuple or something?

view this post on Zulip Eric Haas (Jan 16 2019 at 17:46):

(deleted)

view this post on Zulip Eric Haas (Jan 17 2019 at 05:36):

What I'm looking for is a way to list the "snapshot of element" recursing through the elements until I get to the primitives. I've done this using the bracket notation but would like to know if there is an easier way.

view this post on Zulip Eric Haas (Jan 17 2019 at 08:00):

from fhirclient.models import patient as P

def get_eps(name,o,depth=0):
    print('--'*depth, name)
    print('--','id') if depth == 0 else False
    for i,j,k,l,m,n in o.elementProperties():
        if i in ['extension','modifierExtension','assigner','id'] :
            continue
        if i =='contained':
            print('--',i)
            continue
        try:
            get_eps(i,k(), depth+1) if k() else print('--'*(depth+1),j)
        except AttributeError:
            pass

p = P.Patient()
get_eps(p.resource_type,p)

view this post on Zulip Eric Haas (Jan 17 2019 at 08:01):

gives you

 Patient
-- id
-- implicitRules
-- language
-- meta
---- lastUpdated
---- profile
---- security
etc...
~~~

view this post on Zulip Eric Haas (Jan 20 2019 at 17:49):

here is a more flexible version that allows you to list all elements in dot notation or snake case.

from fhirr4models import observation as O   # my R4 model library which includes a fhir primitive hack

recursives = ['extension','modifierExtension','assigner']
root_ignore = ['contained','implicitRules','language','meta','extension','modifierExtension','text']
datatype_ignore = ['id','userSelected', 'version']
ignore_fhirprimitive = True
delimiter = '.'
list_notation ='[0]'

def get_eps(element,path, level = 0):
    print(path)

    for i,j,k,l,m,n in element.elementProperties():
        if level > 0 and (i in recursives):  # ignore recursive elements except for root level
            continue
        elif level == 0 and i in root_ignore:  # ignore these root elements
            continue
        elif level > 0 and i in datatype_ignore:  # ignore these datatype elements
            continue
        elif i.startswith('_') and ignore_fhirprimitive:  # ignore _elements
            continue

        try:
            get_eps(element=k(),path=f'{path}{delimiter}{i}{list_notation}' if l else f'{path}{delimiter}{i}',level = level +1)
        except AttributeError:
            pass

a = O.Observation()
get_eps(element=a,path=a.resource_type,level=0)

view this post on Zulip Eric Haas (Jan 20 2019 at 17:51):

will give you...

Observation
Observation.id
Observation.basedOn[0]
Observation.basedOn[0].display
Observation.basedOn[0].identifier
Observation.basedOn[0].identifier.period
Observation.basedOn[0].identifier.period.end
Observation.basedOn[0].identifier.period.start
Observation.basedOn[0].identifier.system
Observation.basedOn[0].identifier.type
Observation.basedOn[0].identifier.type.coding[0]
Observation.basedOn[0].identifier.type.coding[0].code
Observation.basedOn[0].identifier.type.coding[0].display
Observation.basedOn[0].identifier.type.coding[0].system
Observation.basedOn[0].identifier.type.text
Observation.basedOn[0].identifier.use
Observation.basedOn[0].identifier.value
Observation.basedOn[0].reference
....

view this post on Zulip Geoff Low (Jan 24 2019 at 13:51):

Cool, how do you work the extensions that are on the model (eg working group, etc) versus those that are potentially available (extension-definitions.json); the way I see it the defined elements (ie Observations.extensions = []) could be 'hard-coded' with the values - you'd need to load the extension definitions to get what the class attribute should be called and multiplicity, but then instantiate it as an extension.Extension instance?

view this post on Zulip Eric Haas (Jan 24 2019 at 16:00):

I omitted the extensions since they recurse reaching a recursion limit in the script but you certainly could add them in as you describe.


Last updated: Apr 12 2022 at 19:14 UTC