Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions assets/api/writer-generator/python/profile_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,18 @@
import copy
from typing import Any, Iterable, Mapping, MutableMapping, MutableSequence, Sequence, TypeVar

from typing_extensions import TypeGuard

T = TypeVar("T")

# ---------------------------------------------------------------------------
# General utilities
# ---------------------------------------------------------------------------


def is_record(value: Any) -> bool:
def is_record(value: Any) -> TypeGuard[MutableMapping[str, Any]]:
"""True when ``value`` is a non-None mapping (dict-like, not a list)."""
return isinstance(value, Mapping)
return isinstance(value, MutableMapping)


def ensure_path(root: MutableMapping[str, Any], path: Sequence[str]) -> MutableMapping[str, Any]:
Expand Down
18 changes: 14 additions & 4 deletions examples/python-r4-us-core/demo.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,11 @@ async def main() -> None:
patients = await client.resources(Patient).fetch()
print(f"\nFound {len(patients)} patients:")
for pat in patients:
print(f" - {pat.name[0].family}, {pat.name[0].given[0]}")
name = pat.name
assert name is not None
given = name[0].given
assert given is not None
print(f" - {name[0].family}, {given[0]}")

# Search with filters
female_patients = await client.resources(Patient).search(gender="female").fetch()
Expand All @@ -57,16 +61,22 @@ async def main() -> None:
# Search and limit results
first_patient = await client.resources(Patient).first()
if first_patient:
print(f"\nFirst patient: {first_patient.name[0].family}")
first_patient_name = first_patient.name
assert first_patient_name is not None
print(f"\nFirst patient: {first_patient_name[0].family}")

# Fetch a single patient by ID
fetched_patient = await client.reference("Patient", created_patient.id).to_resource()
print(f"\nFetched patient by ID: {fetched_patient.name[0].family}")
fetched_patient_name = fetched_patient.name
assert fetched_patient_name is not None
print(f"\nFetched patient by ID: {fetched_patient_name[0].family}")

# Update a patient
created_patient.name = [HumanName(given=["Bob"], family="Updated")]
updated_patient = await client.update(created_patient)
print(f"\nUpdated patient family name to: {updated_patient.name[0].family}")
updated_patient_name = updated_patient.name
assert updated_patient_name is not None
print(f"\nUpdated patient family name to: {updated_patient_name[0].family}")

# Cleanup
await client.delete(f"Patient/{created_patient.id}")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,13 @@ def get_code(self, mode: Literal["raw"] | None = None) -> CodeableConcept | Exte
return ext_obj
return cast('CodeableConcept | None', get_extension_value(ext, "valueCodeableConcept"))

def set_code(self, value: "Extension | Any") -> "NationalityExtension":
def set_code(self, value: "Extension | CodeableConcept") -> "NationalityExtension":
if is_extension(value):
if _get_key(value, "url") != "code":
raise ValueError(f"Expected extension url 'code', got {_get_key(value, 'url')!r}")
push_extension(self._resource, value)
else:
assert not isinstance(value, Extension)
push_extension(self._resource, Extension(url="code", valueCodeableConcept=value))
return self

Expand All @@ -92,12 +93,13 @@ def get_period(self, mode: Literal["raw"] | None = None) -> Period | Extension |
return ext_obj
return cast('Period | None', get_extension_value(ext, "valuePeriod"))

def set_period(self, value: "Extension | Any") -> "NationalityExtension":
def set_period(self, value: "Extension | Period") -> "NationalityExtension":
if is_extension(value):
if _get_key(value, "url") != "period":
raise ValueError(f"Expected extension url 'period', got {_get_key(value, 'url')!r}")
push_extension(self._resource, value)
else:
assert not isinstance(value, Extension)
push_extension(self._resource, Extension(url="period", valuePeriod=value))
return self

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,9 @@ def get_vscat(self, mode: Literal["raw"] | None = None) -> dict[str, Any] | Code
def set_vscat(self, value: dict[str, Any] | None = None) -> "ObservationBodyweightProfile":
match = self.__class__._vscat_slice_match
merged = apply_slice_match((value or {}), match)
merged = CodeableConcept(**merged)
element = CodeableConcept(**merged)
items = getattr(self._resource, "category", None) or []
set_array_slice(items, match, merged)
set_array_slice(items, match, element)
setattr(self._resource, "category", items)
return self

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,9 @@ def get_vscat(self, mode: Literal["raw"] | None = None) -> dict[str, Any] | Code
def set_vscat(self, value: dict[str, Any] | None = None) -> "ObservationVitalsignsProfile":
match = self.__class__._vscat_slice_match
merged = apply_slice_match((value or {}), match)
merged = CodeableConcept(**merged)
element = CodeableConcept(**merged)
items = getattr(self._resource, "category", None) or []
set_array_slice(items, match, merged)
set_array_slice(items, match, element)
setattr(self._resource, "category", items)
return self

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
from fhir_types.hl7_fhir_r4_core.base import Extension
from fhir_types.profile_helpers import (
_get_key, apply_slice_match, build_resource, ensure_slice_defaults, get_array_slice, get_extension_value, \
is_extension, matches_value, push_extension, set_array_slice, strip_match_keys, unwrap_slice_choice, validate_fixed_value, \
validate_required, validate_slice_cardinality, wrap_slice_choice
is_extension, is_record, matches_value, push_extension, set_array_slice, strip_match_keys, unwrap_slice_choice, \
validate_fixed_value, validate_required, validate_slice_cardinality, wrap_slice_choice
)


Expand Down Expand Up @@ -92,6 +92,7 @@ def set_omb_category(self, value: "Extension | dict[str, Any]") -> "UscoreEthnic
raise ValueError(f"Expected extension url 'ombCategory', got {_get_key(value, 'url')!r}")
push_extension(self._resource, value)
else:
assert is_record(value)
push_extension(self._resource, {"url": "ombCategory", **value})
return self

Expand All @@ -115,6 +116,7 @@ def set_detailed(self, value: "Extension | dict[str, Any]") -> "UscoreEthnicityE
raise ValueError(f"Expected extension url 'detailed', got {_get_key(value, 'url')!r}")
push_extension(self._resource, value)
else:
assert is_record(value)
push_extension(self._resource, {"url": "detailed", **value})
return self

Expand All @@ -138,6 +140,7 @@ def set_text(self, value: "Extension | dict[str, Any]") -> "UscoreEthnicityExten
raise ValueError(f"Expected extension url 'text', got {_get_key(value, 'url')!r}")
push_extension(self._resource, value)
else:
assert is_record(value)
push_extension(self._resource, {"url": "text", **value})
return self

Expand Down Expand Up @@ -181,28 +184,28 @@ def set_extension_omb_category(self, value: dict[str, Any] | None = None) -> "Us
match = self.__class__._omb_category_slice_match
wrapped = wrap_slice_choice((value or {}), "valueCoding")
merged = apply_slice_match(wrapped, match)
merged = Extension(**merged)
element = Extension(**merged)
items = getattr(self._resource, "extension", None) or []
set_array_slice(items, match, merged)
set_array_slice(items, match, element)
setattr(self._resource, "extension", items)
return self

def set_extension_detailed(self, value: dict[str, Any] | None = None) -> "UscoreEthnicityExtension":
match = self.__class__._detailed_slice_match
wrapped = wrap_slice_choice((value or {}), "valueCoding")
merged = apply_slice_match(wrapped, match)
merged = Extension(**merged)
element = Extension(**merged)
items = getattr(self._resource, "extension", None) or []
set_array_slice(items, match, merged)
set_array_slice(items, match, element)
setattr(self._resource, "extension", items)
return self

def set_extension_text(self, value: dict[str, Any] | None = None) -> "UscoreEthnicityExtension":
match = self.__class__._text_slice_match
merged = apply_slice_match((value or {}), match)
merged = Extension(**merged)
element = Extension(**merged)
items = getattr(self._resource, "extension", None) or []
set_array_slice(items, match, merged)
set_array_slice(items, match, element)
setattr(self._resource, "extension", items)
return self

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
from fhir_types.hl7_fhir_r4_core.base import Extension
from fhir_types.profile_helpers import (
_get_key, apply_slice_match, build_resource, ensure_slice_defaults, get_array_slice, get_extension_value, \
is_extension, matches_value, push_extension, set_array_slice, strip_match_keys, unwrap_slice_choice, validate_fixed_value, \
validate_required, validate_slice_cardinality, wrap_slice_choice
is_extension, is_record, matches_value, push_extension, set_array_slice, strip_match_keys, unwrap_slice_choice, \
validate_fixed_value, validate_required, validate_slice_cardinality, wrap_slice_choice
)


Expand Down Expand Up @@ -95,6 +95,7 @@ def set_omb_category(self, value: "Extension | dict[str, Any]") -> "UscoreRaceEx
raise ValueError(f"Expected extension url 'ombCategory', got {_get_key(value, 'url')!r}")
push_extension(self._resource, value)
else:
assert is_record(value)
push_extension(self._resource, {"url": "ombCategory", **value})
return self

Expand All @@ -118,6 +119,7 @@ def set_detailed(self, value: "Extension | dict[str, Any]") -> "UscoreRaceExtens
raise ValueError(f"Expected extension url 'detailed', got {_get_key(value, 'url')!r}")
push_extension(self._resource, value)
else:
assert is_record(value)
push_extension(self._resource, {"url": "detailed", **value})
return self

Expand All @@ -141,6 +143,7 @@ def set_text(self, value: "Extension | dict[str, Any]") -> "UscoreRaceExtension"
raise ValueError(f"Expected extension url 'text', got {_get_key(value, 'url')!r}")
push_extension(self._resource, value)
else:
assert is_record(value)
push_extension(self._resource, {"url": "text", **value})
return self

Expand Down Expand Up @@ -184,28 +187,28 @@ def set_extension_omb_category(self, value: dict[str, Any] | None = None) -> "Us
match = self.__class__._omb_category_slice_match
wrapped = wrap_slice_choice((value or {}), "valueCoding")
merged = apply_slice_match(wrapped, match)
merged = Extension(**merged)
element = Extension(**merged)
items = getattr(self._resource, "extension", None) or []
set_array_slice(items, match, merged)
set_array_slice(items, match, element)
setattr(self._resource, "extension", items)
return self

def set_extension_detailed(self, value: dict[str, Any] | None = None) -> "UscoreRaceExtension":
match = self.__class__._detailed_slice_match
wrapped = wrap_slice_choice((value or {}), "valueCoding")
merged = apply_slice_match(wrapped, match)
merged = Extension(**merged)
element = Extension(**merged)
items = getattr(self._resource, "extension", None) or []
set_array_slice(items, match, merged)
set_array_slice(items, match, element)
setattr(self._resource, "extension", items)
return self

def set_extension_text(self, value: dict[str, Any] | None = None) -> "UscoreRaceExtension":
match = self.__class__._text_slice_match
merged = apply_slice_match((value or {}), match)
merged = Extension(**merged)
element = Extension(**merged)
items = getattr(self._resource, "extension", None) or []
set_array_slice(items, match, merged)
set_array_slice(items, match, element)
setattr(self._resource, "extension", items)
return self

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
from fhir_types.hl7_fhir_r4_core.base import Extension
from fhir_types.profile_helpers import (
_get_key, apply_slice_match, build_resource, ensure_slice_defaults, get_array_slice, get_extension_value, \
is_extension, matches_value, push_extension, set_array_slice, strip_match_keys, unwrap_slice_choice, validate_fixed_value, \
validate_required, validate_slice_cardinality, wrap_slice_choice
is_extension, is_record, matches_value, push_extension, set_array_slice, strip_match_keys, unwrap_slice_choice, \
validate_fixed_value, validate_required, validate_slice_cardinality, wrap_slice_choice
)


Expand Down Expand Up @@ -88,6 +88,7 @@ def set_tribal_affiliation(self, value: "Extension | dict[str, Any]") -> "Uscore
raise ValueError(f"Expected extension url 'tribalAffiliation', got {_get_key(value, 'url')!r}")
push_extension(self._resource, value)
else:
assert is_record(value)
push_extension(self._resource, {"url": "tribalAffiliation", **value})
return self

Expand All @@ -111,6 +112,7 @@ def set_is_enrolled(self, value: "Extension | dict[str, Any]") -> "UscoreTribalA
raise ValueError(f"Expected extension url 'isEnrolled', got {_get_key(value, 'url')!r}")
push_extension(self._resource, value)
else:
assert is_record(value)
push_extension(self._resource, {"url": "isEnrolled", **value})
return self

Expand Down Expand Up @@ -142,18 +144,18 @@ def set_extension_tribal_affiliation(self, value: dict[str, Any] | None = None)
match = self.__class__._tribal_affiliation_slice_match
wrapped = wrap_slice_choice((value or {}), "valueCodeableConcept")
merged = apply_slice_match(wrapped, match)
merged = Extension(**merged)
element = Extension(**merged)
items = getattr(self._resource, "extension", None) or []
set_array_slice(items, match, merged)
set_array_slice(items, match, element)
setattr(self._resource, "extension", items)
return self

def set_extension_is_enrolled(self, value: dict[str, Any] | None = None) -> "UscoreTribalAffiliationExtension":
match = self.__class__._is_enrolled_slice_match
merged = apply_slice_match((value or {}), match)
merged = Extension(**merged)
element = Extension(**merged)
items = getattr(self._resource, "extension", None) or []
set_array_slice(items, match, merged)
set_array_slice(items, match, element)
setattr(self._resource, "extension", items)
return self

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -354,29 +354,29 @@ def get_diastolic(self, mode: Literal["raw"] | None = None) -> dict[str, Any] |
def set_vscat(self, value: dict[str, Any] | None = None) -> "UscoreBloodPressureProfile":
match = self.__class__._vscat_slice_match
merged = apply_slice_match((value or {}), match)
merged = CodeableConcept(**merged)
element = CodeableConcept(**merged)
items = getattr(self._resource, "category", None) or []
set_array_slice(items, match, merged)
set_array_slice(items, match, element)
setattr(self._resource, "category", items)
return self

def set_systolic(self, value: dict[str, Any] | None = None) -> "UscoreBloodPressureProfile":
match = self.__class__._systolic_slice_match
wrapped = wrap_slice_choice((value or {}), "valueQuantity")
merged = apply_slice_match(wrapped, match)
merged = ObservationComponent(**merged)
element = ObservationComponent(**merged)
items = getattr(self._resource, "component", None) or []
set_array_slice(items, match, merged)
set_array_slice(items, match, element)
setattr(self._resource, "component", items)
return self

def set_diastolic(self, value: dict[str, Any] | None = None) -> "UscoreBloodPressureProfile":
match = self.__class__._diastolic_slice_match
wrapped = wrap_slice_choice((value or {}), "valueQuantity")
merged = apply_slice_match(wrapped, match)
merged = ObservationComponent(**merged)
element = ObservationComponent(**merged)
items = getattr(self._resource, "component", None) or []
set_array_slice(items, match, merged)
set_array_slice(items, match, element)
setattr(self._resource, "component", items)
return self

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,9 +204,9 @@ def get_vscat(self, mode: Literal["raw"] | None = None) -> dict[str, Any] | Code
def set_vscat(self, value: dict[str, Any] | None = None) -> "UscoreBodyWeightProfile":
match = self.__class__._vscat_slice_match
merged = apply_slice_match((value or {}), match)
merged = CodeableConcept(**merged)
element = CodeableConcept(**merged)
items = getattr(self._resource, "category", None) or []
set_array_slice(items, match, merged)
set_array_slice(items, match, element)
setattr(self._resource, "category", items)
return self

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -314,9 +314,9 @@ def get_vscat(self, mode: Literal["raw"] | None = None) -> dict[str, Any] | Code
def set_vscat(self, value: dict[str, Any] | None = None) -> "UscoreVitalSignsProfile":
match = self.__class__._vscat_slice_match
merged = apply_slice_match((value or {}), match)
merged = CodeableConcept(**merged)
element = CodeableConcept(**merged)
items = getattr(self._resource, "category", None) or []
set_array_slice(items, match, merged)
set_array_slice(items, match, element)
setattr(self._resource, "category", items)
return self

Expand Down
Loading
Loading