Skip to content

v0.0.16

Choose a tag to compare

@ryukzak ryukzak released this 22 Jun 07:53
· 193 commits to main since this release

The big one: Python now supports profiles. The Python generator has mostly caught up with TypeScript this release — profile classes, generic Bundle[T], and nicer defaults (fhirpy + camelCase out of the box). Plus some lint tightening, a tidier examples layout, and a couple of package-resolution fixes.

Python profiles 🎉

generateProfile: true now spits out a typed wrapper class for each FHIR profile, just like the TypeScript side. You get create() / apply() / from_resource() constructors, to_resource() to unwrap, and a validate() that checks required fields, fixed values, slice cardinality, must-support, prohibited choices, enums, and reference targets. Fields, extensions, and slices all get typed get_X / set_X accessors (extensions can return flat values, a raw Extension, or a wrapped profile). A profile_helpers.py runtime ships with each profiles/ package. — @MikhailArtemyev in #167

# before — raw Pydantic, every fixed value by hand
obs = Observation(resource_type="Observation", status="final",
    code=CodeableConcept(coding=[Coding(code="85354-9", system="http://loinc.org")]),
    component=[ObservationComponent(...)], ...)

# after — the profile class fills fixed values, slices, and meta.profile for you
bp = UscoreBloodPressureProfile.create(status="final", subject=Reference(reference="Patient/123"))

👉 See it end-to-end in the US Core profiles example.

Other Python goodies

  • Generic Bundle[T]. Bundle, BundleEntry, BundleEntryResponse, and DomainResource are now generic — Bundle[Patient] narrows statically, and bare Bundle.from_json() still dispatches by resourceType at runtime. No more ResourceFamily union. — @MikhailArtemyev in #164

    bundle: Bundle[Patient] = Bundle[Patient].model_validate(response.json())   # typed
    bundle = Bundle.from_json('{"type":"collection","entry":[...]}')            # still polymorphic
  • Nicer defaults. Two config changes worth knowing about:

    • fhirpy is now the default client. The boolean fhirpyClient is deprecated (still works) — use client: "fhirpy" | "none" instead, or just omit it. — @ryukzak in #187
    • fieldFormat now defaults to camelCase, so models keep their FHIR spelling instead of converting to snake_case. Opt back in with .python({ fieldFormat: "snake_case" }). — @ryukzak in #189
    .python({ client: "none" })            // plain Pydantic, no fhirpy
    .python({ fieldFormat: "snake_case" }) // old snake_case behavior
  • Fixes. Extensions now serialize with proper FHIR aliases (valueCoding, not value_coding) and the profile generator honors fieldFormat end-to-end (#178), profile_helpers.py moved into the generated profiles/ package (#179), and the python-us-core example is mypy --strict clean (#180, #183). — @MikhailArtemyev, @ryukzak

Elsewhere

  • TypeSchema: stop recursing forever on packages with cyclic dependencies. — @ryukzak in #174
  • API: fix SQL-on-FHIR generation by adding the missing hl7.fhir.r5.core dependency. — @ryukzak in #175
  • Lint: turn on a batch of stricter Biome rules and fix everything they flagged. — @ryukzak in #182
  • Examples: consolidate the example dirs — typescript-r4-us-core, python-r4-us-core, CCDA moved to on-the-fly/ccda, and deduped TS profile tests. — @ryukzak in #184

Contributors

@MikhailArtemyev, @ryukzak

Full Changelog: v0.0.15...v0.0.16