SDK v1.7.0: FHIR Type Interop for Python & R
Python & R SDKs v1.7.0 add FHIR interop - pass fhir.resources Codings directly, return tibble batch output in R, and wire fhirpy or fhircrackr to OMOPHub's FHIR Terminology Service.
SDK v1.7.0 is out for both Python and R. Following the FHIR Resolver and FHIR Terminology Service launches, this release wires both SDKs into the broader FHIR ecosystem - so you can pass your existing FHIR objects into OMOPHub and point your existing FHIR libraries at the OMOPHub FHIR endpoint, without any glue code.
Pass FHIR Codings Directly (Python)
client.fhir.resolve now accepts a new coding= kwarg with duck-typed input - a plain dict, the new omophub.types.fhir.Coding TypedDict, or any object exposing .system / .code / .display attributes. That means fhir.resources.Coding, fhirpy codings, and your own FHIR types work directly:
# Python
from fhir.resources.coding import Coding
coding = Coding(
system="http://snomed.info/sct",
code="44054006",
display="Type 2 diabetes mellitus",
)
result = client.fhir.resolve(coding=coding, resource_type="Condition")
print(result["resolution"]["standard_concept"]["concept_name"])
resolve_batch accepts a mixed list of dicts and Coding-like objects; resolve_codeable_concept accepts either a list of codings (existing) or a full CodeableConcept-like object exposing .coding and .text (new). Two new lightweight types - Coding / CodeableConcept TypedDicts and CodingLike / CodeableConceptLike Protocols - live in omophub.types.fhir for static-typing-friendly call sites.
Tibble Batch Output (R)
FhirResource$resolve_batch() (and the standalone fhir_resolve_batch()) gained an as_tibble parameter. Set as_tibble = TRUE and the call returns a flat tibble::tibble - one row per input coding, columns for source concept, standard concept, target CDM table, mapping type, and resolution status - ready for dplyr / tidyr:
# R
library(dplyr)
result <- client$fhir$resolve_batch(
list(
list(system = "http://snomed.info/sct", code = "44054006"),
list(system = "http://loinc.org", code = "2339-0"),
list(system = "http://www.nlm.nih.gov/research/umls/rxnorm", code = "197696")
),
as_tibble = TRUE
)
result |>
filter(status == "resolved") |>
select(source_code, standard_concept_name, target_table)
# Batch summary stays attached:
attr(result, "summary") # list(total = 3, resolved = 3, failed = 0)
Default behavior is unchanged - as_tibble = FALSE still returns the legacy list shape.
Pipe-Friendly Standalone Wrappers (R)
Three new exported functions wrap the R6 FhirResource methods so they read naturally in |> pipelines:
# R
client |>
fhir_resolve_batch(codings, as_tibble = TRUE) |>
filter(status == "resolved")
fhir_resolve(), fhir_resolve_batch(), and fhir_resolve_codeable_concept() are all available. The R6 form (client$fhir$resolve(...)) still works - pick whichever reads better.
Configure External FHIR Clients
If you'd rather use a dedicated FHIR client library (fhirpy in Python, fhircrackr / httr2 in R) and just talk to OMOPHub's FHIR Terminology Service directly, the SDKs now hand you a pre-configured client:
# Python
from omophub.fhir_interop import get_fhirpy_client
# Returns a fhirpy client wired to https://fhir.omophub.com/fhir/r4
# with Authorization: Bearer YOUR_API_KEY already set.
fhir = get_fhirpy_client(api_key="oh_your_api_key", version="r4")
# Use it like any fhirpy client:
codesystems = fhir.resources("CodeSystem").fetch()
# R
# Returns the OMOPHub FHIR base URL for any version (r4, r4b, r5, r6).
url <- omophub_fhir_url(version = "r4") # "https://fhir.omophub.com/fhir/r4"
# Plug into httr2 / fhircrackr:
req <- httr2::request(url) |>
httr2::req_auth_bearer_token("oh_your_api_key") |>
httr2::req_url_path_append("metadata")
fhirpy is a lazy import in Python - never a required dependency. Install on demand with pip install omophub[fhirpy], or pip install omophub[fhir-resources] if you want the full HL7 type set.
Install or Upgrade
# Python
pip install --upgrade omophub
# R
install.packages("omophub")