Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend fhir.resources for a particular implementation guide #109

Open
yvesonline opened this issue Aug 12, 2022 · 3 comments
Open

Extend fhir.resources for a particular implementation guide #109

yvesonline opened this issue Aug 12, 2022 · 3 comments

Comments

@yvesonline
Copy link

  • fhir.resources version: 6.4.0
  • Python version: 3.8.0
  • Operating System: Ubuntu (4.15.0-176-generic)

Description

We need to work with some FHIR data according to MIO DiGA V1.0.0 and I was wondering how to extend fhir.resources to make it possible to do so. For example the Patient resource of MIO DiGA is extended by a couple of attributes, so I was wondering where to start to get to a from mio.diga.patient import Patient. I'd inherit from fhir.resources.patient.Patient and then add the new attributes. I assume this is the way to go? Is there any documentation available regarding implementing custom FHIR resources?

What I Did

So far nothing.

@bwalsh
Copy link

bwalsh commented Feb 5, 2023

@yvesonline Hello. I was wondering if you resolved this and what approach you took?

@yvesonline
Copy link
Author

Yes @bwalsh we resolved this by directly using the Patient object, there wasn't a lot of added value in creating a dedicated MIO DiGA Patient class.

So we do something like this:

from datetime import datetime, timezone
from fhir.resources.patient import Patient

data = {
    'id': '...',
    'name': [
        {
            'text': '...',
            'use': 'official',
            'family': '...',
            'family__ext': {
                'extension': [
                    {
                        'url': 'http://hl7.org/fhir/StructureDefinition/humanname-own-name',
                        'valueString': '...',
                    },
                ],
            },
            'given': ['...'],
        },
    ],
    'identifier': [...],
    'meta': {
        'versionId': 1,
        'lastUpdated': datetime.now(tz=timezone.utc),
        'profile': [
            'https://fhir.kbv.de/StructureDefinition/KBV_PR_MIO_DIGA_Patient|1.0.0'
        ],
    },
    'telecom': [...],
    'communication': [...],
}

p = Patient(**data)

@bobvanderlinden
Copy link

I needed to define resources as part of Aidbox that weren't defined fhir.resources. It took some time to figure out, but eventually I came up with the following function:

def define_fhir_resource(
    fhirtypes,
    fhirtypesvalidators,
    cls: typing.Type[DomainResource],
) -> typing.Type[DomainResource]:
    resource_name = cls.__name__
    resource_type_name = f"{resource_name}Type"
    resource_validator_name = f"{resource_name.lower()}_validator"

    resource_type = type(
        resource_type_name,
        (fhirtypes.AbstractType,),
        {"__resource_type__": resource_name},
    )

    setattr(fhirtypes, resource_type_name, resource_type)
    fhirtypesvalidators.MODEL_CLASSES[resource_name] = (cls, None)

    def resource_validator(value):
        return fhirtypesvalidators.fhir_model_validator(resource_name, value)

    setattr(fhirtypesvalidators, resource_validator_name, resource_validator)

To use this to create a User resource:

from fhir.resources.R4B import fhirtypes
from fhir.resources.R4B import fhirtypesvalidators
from fhir.resources.R4B.domainresource import DomainResource
from pydantic import Field

class User(DomainResource):
    resource_type = Field("User", const=True)
    userName: str = Field(None, element_property=True)
    password: str = Field(None, element_property=True)

    @classmethod
    def elements_sequence(cls):
        return [
            "id",
            "meta",
            "implicitRules",
            "language",
            "text",
            "contained",
            "extension",
            "modifierExtension",
            "userName",
            "password",
        ]

define_fhir_resource(
    fhirtypes=fhirtypes, fhirtypesvalidators=fhirtypesvalidators, cls=User
)

This was needed because fhir.resources would try to look up UserType in its fhirtypes and user_validator in fhirtypesvalidators. The above isn't pretty, but I couldn't find a better solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants