Skip to content

PY: make fhirpy the default python client (swap simple/fhirpy examples)#186

Merged
ryukzak merged 2 commits into
python-example-decouplefrom
python-fhirpy-default
Jun 18, 2026
Merged

PY: make fhirpy the default python client (swap simple/fhirpy examples)#186
ryukzak merged 2 commits into
python-example-decouplefrom
python-fhirpy-default

Conversation

@ryukzak

@ryukzak ryukzak commented Jun 18, 2026

Copy link
Copy Markdown
Collaborator

Make the fhirpy async client the default for the Python examples, and move the simple requests client to its own example. Stacked on #185 (python-example-decouple), so this PR shows only the client swap.

Changes

  • python-r4-us-core → fhirpy client (default). generate.ts now uses fhirpyClient: true (kept snake_case, since the profile tests depend on it). client.py/test_sdk.py use the fhirpy AsyncFHIRClient; because the models are snake_case with FHIR camelCase aliases, the client serializes with by_alias=True. The committed fhir_types/ is regenerated. Profile/offline tests are unchanged.
  • python-fhirpy → simple requests client. generate.ts uses fhirpyClient: false + snake_case; it now hosts the reusable Client class (basic auth + CRUD/search) reused from python-r4-us-core's old client.

Generator fix (the interesting bit)

fhirpy's AsyncFHIRClient methods are generic over TResource, bound to a ResourceProtocol with a settable resourceType. The camelCase models satisfied this with a real resourceType field; the snake_case models expose the discriminator as resource_type (alias resourceType) and only set resourceType at runtime via a __pydantic_init_subclass__ hook — invisible to mypy. So fhirpy calls failed type-checking.

Fix in the generated FhirpyBaseModel (assets/api/writer-generator/python/fhirpy_base_model.py): declare a TYPE_CHECKING-only instance annotation

if TYPE_CHECKING:
    resourceType: str = ""

— a settable instance attr (satisfies the protocol bound + class access), defaulted (so the pydantic mypy plugin treats it as optional, not a required ctor arg), and TYPE_CHECKING-only (zero runtime change; the hook still sets the real value). ClassVar was tried first but can't satisfy a settable protocol member.

Verification

  • python-r4-us-core: mypy --config-file mypy.ini . clean (42 files), 70 offline/profile tests pass, test_sdk.py (fhirpy) imports/type-checks, committed fhir_types matches a fresh generation.
  • python-fhirpy: mypy --strict . clean (154 files).
  • Project tsc + biome clean; python writer snapshot test green.
  • Live test_sdk.py CRUD (both examples) requires Aidbox → runs in CI.

Makefile and sdk-tests.yml need no change — the targets/jobs run mypy/pytest/diff-check on whatever each example generates.

Note on naming

python-fhirpy now hosts the simple requests client (the fhirpy client moved to python-r4-us-core), so the directory name is now misleading. I left the name as-is per the request; happy to rename it (e.g. python-simple-client) as a follow-up.

Comment thread examples/python-fhirpy/generate.ts Outdated
Comment thread examples/python-r4-us-core/generate.ts
Comment thread examples/python-r4-us-core/README.md Outdated
Comment thread examples/python-r4/generate.ts
Comment thread examples/python-r4-us-core/demo.py
Comment thread examples/README.md Outdated
@ryukzak

ryukzak commented Jun 18, 2026

Copy link
Copy Markdown
Collaborator Author

Plan for these comments:

@ryukzak ryukzak force-pushed the python-example-decouple branch from 50980ed to 9590468 Compare June 18, 2026 16:03
@ryukzak ryukzak force-pushed the python-fhirpy-default branch from 1969c6b to a98ec29 Compare June 18, 2026 16:05
ryukzak added 2 commits June 18, 2026 18:18
- python-r4-us-core: uses the default fhirpy client (no explicit option); the fhirpy
  AsyncFHIRClient demo is demo.py (renamed from client.py — it is a demo, not a Client class)
  and serializes via the generated serialize() helper
- python-r4 (renamed from python-fhirpy): the simple requests Client, generated with client: "none"
- Makefile/CI: rename the python-fhirpy targets/jobs/paths to python-r4
- READMEs: fix client descriptions, unwrap hard-wrapped paragraphs; add a Markdown no-wrap rule to CLAUDE.md
- No example uses the deprecated fhirpyClient flag anymore
@ryukzak ryukzak force-pushed the python-fhirpy-default branch from a98ec29 to 8fc0455 Compare June 18, 2026 16:19
@ryukzak

ryukzak commented Jun 18, 2026

Copy link
Copy Markdown
Collaborator Author

All comments addressed (force-pushed 8fc0455):

  • client API: the new client: "fhirpy" | "none" option landed in API: add python client option (fhirpy|none), default fhirpy; deprecate fhirpyClient #187; this PR now uses it — python-r4-us-core relies on the default (fhirpy, no explicit option), python-r4 sets client: "none". No example uses the deprecated fhirpyClient.
  • rename path: python-fhirpypython-r4 (it now hosts the simple requests client).
  • filename: the fhirpy client.pydemo.py (it is a runnable demo, not a Client class).
  • markdown: unwrapped the hard-wrapped paragraphs; added a no-wrap rule to CLAUDE.md.
  • default params: removed from generate.ts and the README notes.

Verified: python-r4-us-core mypy clean + 70 offline tests + fhir_types determinism; python-r4 mypy clean (154 files); also uses the generated serialize() helper in the fhirpy client.

@ryukzak ryukzak merged commit 2d27657 into python-example-decouple Jun 18, 2026
30 checks passed
@ryukzak ryukzak deleted the python-fhirpy-default branch June 18, 2026 19:50
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

Successfully merging this pull request may close these issues.

1 participant