Skip to main content

FHIR Slicing utilities build on top of Pydantic

Project description

🔪 FHIR Slicing utilities for Pydantic

PyPI version License: MIT Python 3.10+

A Python library that simplifies working with nested elements in FHIR resources using Pydantic models and smart slicing.

🚀 Installation

pip install fhir-slicing

🤔 The Challenge

Working with FHIR resources in Python can be challenging due to their complex structure and extensibility. FHIR resources often contain:

  • Nested elements with cardinality 0..* or 1..*
  • Extension arrays with unknown elements

This leads to verbose and error-prone code when accessing nested data:

# Traditional way to access birth place
birth_place = next(
    (e.valueAddress.city
     for e in patient.extension
     if e.url == "http://hl7.org/fhir/StructureDefinition/patient-birthPlace"),
    None
)
# Traditional way to access systolic blood pressure
bp_reading = observation.component[0].valueQuantity.value  # Fragile! Assumes systolic is first
# or by code but not very readable
systolic = next(
    (c.valueQuantity.value
     for c in observation.component
     if c.code.coding[0].code == "8480-6"),
    None
)

✨ Solution: Smart Slicing

This library introduces a more intuitive way to access nested FHIR data using named slices, inspired by FHIR's slicing mechanism.

Known slices are defined as annotated fields in Pydantic models, which provide:

  • ✅ Validation of slice cardinality
  • 🛡️ Type safety for slice elements
  • 📖 Improved readability

Example: Patient with birthPlace extension

# Access known extensions by name, while preserving access to unknown ones
patient.extension.birthPlace.valueAddress.city
patient.extension[0]  # Still works for accessing any extension

Example: Blood Pressure Observation with systolic and diastolic components

# Access components naturally
bp = BloodPressureObservation.model_validate(data)
systolic = bp.component.systolic.valueQuantity.value
diastolic = bp.component.diastolic.valueQuantity.value

❓ How

Setting up your models for slicing is as simple as subclassing ElementArray and defining a discriminator method.

[!NOTE] Interested in how it works? Check out this blog post for more details. Example: Patient with birthPlace extension

from pydantic_fhir_slicing import Slice, ElementArray
from my_fhir_types import Address, BaseModel

class AddressExtension(BaseModel):
    url: str
    valueAddress: Address

class PatientExtensions(ElementArray):
    birthPlace: AddressExtension = Slice(1, 1)

    def discriminator(self, item) -> str:
        url = item.get("url", None)
        match url:
            case "http://hl7.org/fhir/StructureDefinition/patient-birthPlace":
                return "birthPlace"
            case _:
                return "@default"

class Patient(BaseModel):
    extension: PatientExtensions

Example: Blood Pressure Observation with systolic and diastolic components

from pydantic_fhir_slicing import ElementArray
from my_fhir_types import CodeableConcept, Quantity, BaseModel

class QuantityComponent(BaseModel):
    code: CodeableConcept
    valueQuantity: Quantity

class BPComponents(ElementArray):
    systolic: QuantityComponent = Slice(1, 1)
    diastolic: QuantityComponent = Slice(1, 1)

    def discriminator(self, item: Component) -> str:
        try:
            code = item["code"]["coding"][0]["code"]
            match code:
                case "8480-6":
                    return "systolic"
                case "8462-4":
                    return "diastolic"
                case _:
                    return "@default"
        except (KeyError, IndexError):
            return "@default"

class BloodPressureObservation(BaseModel):
    code: CodeableConcept
    component: BPComponents

👥 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

📜 License

MIT License

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fhir_slicing-0.1.4.tar.gz (15.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fhir_slicing-0.1.4-py3-none-any.whl (9.3 kB view details)

Uploaded Python 3

File details

Details for the file fhir_slicing-0.1.4.tar.gz.

File metadata

  • Download URL: fhir_slicing-0.1.4.tar.gz
  • Upload date:
  • Size: 15.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.6.3

File hashes

Hashes for fhir_slicing-0.1.4.tar.gz
Algorithm Hash digest
SHA256 c0b6c56baa2dfc2594cdc884755e8c931a4a1e29fd41c9dea2616483fade818f
MD5 d4a1ff4c52dd55eadaa3714ffa89a1ce
BLAKE2b-256 0e22a6298e07a2f51a926a438613d84c0ea1838505764809b92bdc0c3fa7f255

See more details on using hashes here.

File details

Details for the file fhir_slicing-0.1.4-py3-none-any.whl.

File metadata

File hashes

Hashes for fhir_slicing-0.1.4-py3-none-any.whl
Algorithm Hash digest
SHA256 21f11dc2f3041426adceccdcf8673f08b576c01df0f7fdfbc3a3db04cacc5592
MD5 cfb4fbb4ac3ab9c8d58b43e9ec638cb3
BLAKE2b-256 71cccbcf42de4d820a945a8ba1beb14c8411e13b71871da25630630292dda03c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page