Documentation Index
Fetch the complete documentation index at: https://docs.omophub.com/llms.txt
Use this file to discover all available pages before exploring further.
Resolve a Single FHIR Coding
Translate a FHIR Coding (system URI + code) to an OMOP standard concept and CDM target table:
result = client.fhir.resolve(
system="http://snomed.info/sct",
code="44054006",
resource_type="Condition",
)
res = result["resolution"]
print(res["standard_concept"]["concept_name"]) # "Type 2 diabetes mellitus"
print(res["target_table"]) # "condition_occurrence"
print(res["mapping_type"]) # "direct"
Resolve a Non-Standard Code (Maps to Traversal)
ICD-10-CM and other classification codes are automatically mapped to their standard equivalents:
result = client.fhir.resolve(
system="http://hl7.org/fhir/sid/icd-10-cm",
code="E11.9",
)
res = result["resolution"]
print(res["source_concept"]["vocabulary_id"]) # "ICD10CM"
print(res["standard_concept"]["vocabulary_id"]) # "SNOMED"
print(res["mapping_type"]) # "mapped"
print(res["relationship_id"]) # "Maps to"
print(res["target_table"]) # "condition_occurrence"
Text-Only Resolution (Semantic Search Fallback)
When no structured code is available, pass the display text for semantic search:
result = client.fhir.resolve(
display="Blood Sugar",
resource_type="Observation",
)
res = result["resolution"]
print(res["standard_concept"]["concept_name"]) # "Glucose [Mass/volume] in Blood"
print(res["mapping_type"]) # "semantic_match"
print(res["similarity_score"]) # 0.91
print(res["target_table"]) # "measurement"
Skip URI Resolution with vocabulary_id
If you already know the OMOP vocabulary, bypass the URI lookup:
result = client.fhir.resolve(
vocabulary_id="ICD10CM",
code="E11.9",
)
Include Phoebe Recommendations
Get related concepts for phenotype development alongside the resolution:
result = client.fhir.resolve(
system="http://snomed.info/sct",
code="44054006",
include_recommendations=True,
recommendations_limit=5,
)
for rec in result["resolution"]["recommendations"]:
print(f" {rec['concept_name']} ({rec['domain_id']}) via {rec['relationship_id']}")
# "Hyperglycemia (Condition) via Has finding"
# "Diabetic retinopathy (Condition) via Associated finding"
Include Mapping Quality Signal
Assess whether a resolution needs manual review:
result = client.fhir.resolve(
system="http://snomed.info/sct",
code="44054006",
include_quality=True,
)
print(result["resolution"]["mapping_quality"]) # "high", "medium", "low", or "manual_review"
Batch Resolution
Resolve up to 100 codings in a single call. Failed items are reported inline:
result = client.fhir.resolve_batch([
{"system": "http://snomed.info/sct", "code": "44054006"},
{"system": "http://loinc.org", "code": "2339-0"},
{"system": "http://www.nlm.nih.gov/research/umls/rxnorm", "code": "197696"},
])
print(result["summary"]) # {"total": 3, "resolved": 3, "failed": 0}
for item in result["results"]:
if "resolution" in item:
res = item["resolution"]
print(f"{res['source_concept']['concept_code']} -> {res['standard_concept']['concept_name']} -> {res['target_table']}")
else:
print(f"Failed: {item['error']['code']} - {item['error']['message']}")
Apply shared options to the entire batch:
result = client.fhir.resolve_batch(
[{"system": "http://snomed.info/sct", "code": "44054006"}],
resource_type="Condition",
include_quality=True,
)
CodeableConcept Resolution
Resolve a FHIR CodeableConcept with multiple codings. The resolver picks the best match per OHDSI vocabulary preference (SNOMED > RxNorm > LOINC > CVX > ICD-10):
result = client.fhir.resolve_codeable_concept(
coding=[
{"system": "http://snomed.info/sct", "code": "44054006"},
{"system": "http://hl7.org/fhir/sid/icd-10-cm", "code": "E11.9"},
],
resource_type="Condition",
)
best = result["best_match"]["resolution"]
print(best["source_concept"]["vocabulary_id"]) # "SNOMED" (preferred)
print(best["target_table"]) # "condition_occurrence"
# Other resolved codings ranked by preference
for alt in result["alternatives"]:
print(f" Alt: {alt['resolution']['source_concept']['vocabulary_id']}")
# Codings that failed to resolve
for fail in result["unresolved"]:
print(f" Failed: {fail['error']['code']}")
Falls back to the text field via semantic search when no coding resolves:
result = client.fhir.resolve_codeable_concept(
coding=[{"system": "http://loinc.org", "code": "99999-9"}],
text="Blood Sugar",
resource_type="Observation",
)
# best_match resolved via semantic search; failed coding in unresolved
Async Usage
All three methods are available on the async client:
async with omophub.AsyncOMOPHub(api_key="oh_xxx") as client:
result = await client.fhir.resolve(
system="http://snomed.info/sct",
code="44054006",
)
batch = await client.fhir.resolve_batch([
{"system": "http://loinc.org", "code": "2339-0"},
])
cc = await client.fhir.resolve_codeable_concept(
coding=[{"system": "http://snomed.info/sct", "code": "44054006"}],
)
Type Interoperability
All resolver methods accept any Coding-like input via duck typing. You can pass a plain dict, an omophub.types.fhir.Coding TypedDict, or any object exposing .system / .code attributes - including fhir.resources.Coding and fhirpy coding instances. fhir.resources is never a required dependency.
# 1. Plain dict (no extra install)
client.fhir.resolve(
coding={"system": "http://snomed.info/sct", "code": "44054006"},
)
# 2. omophub's lightweight Coding TypedDict
from omophub.types.fhir import Coding, CodeableConcept
coding: Coding = {"system": "http://snomed.info/sct", "code": "44054006"}
client.fhir.resolve(coding=coding)
cc: CodeableConcept = {
"coding": [
{"system": "http://snomed.info/sct", "code": "44054006"},
{"system": "http://hl7.org/fhir/sid/icd-10-cm", "code": "E11.9"},
],
"text": "Type 2 diabetes mellitus",
}
client.fhir.resolve_codeable_concept(cc)
# 3. fhir.resources objects via duck typing (optional install)
# pip install omophub[fhir-resources]
from fhir.resources.R4B.coding import Coding as FhirCoding
fhir_coding = FhirCoding(system="http://snomed.info/sct", code="44054006")
client.fhir.resolve(coding=fhir_coding)
Mixed-shape inputs are fine inside a single batch call - dicts, TypedDicts, and fhir.resources objects can coexist:
from fhir.resources.R4B.coding import Coding as FhirCoding
result = client.fhir.resolve_batch([
{"system": "http://snomed.info/sct", "code": "44054006"},
FhirCoding(system="http://loinc.org", code="2339-0"),
])
Explicit system / code kwargs always win if you pass both coding= and explicit kwargs - handy for overriding a single field without rebuilding the object.
Connection Helpers
For users who want to point an external FHIR client library at OMOPHub’s FHIR Terminology Service directly, the SDK exposes two helpers: a URL builder and a pre-wired fhirpy client.
from omophub import OMOPHub, get_fhir_server_url, get_fhirpy_client
client = OMOPHub(api_key="oh_xxx")
# Property on the client - returns the R4 base URL
print(client.fhir_server_url)
# "https://fhir.omophub.com/fhir/r4"
# Helper for other FHIR versions
print(get_fhir_server_url("r5"))
# "https://fhir.omophub.com/fhir/r5"
If you want to call FHIR operations directly - outside the SDK’s Concept Resolver envelope - install fhirpy as an optional extra:
pip install omophub[fhirpy]
Then use the pre-configured client:
from omophub import get_fhirpy_client
fhir = get_fhirpy_client("oh_xxx")
# Example: fetch the CodeSystem discovery Bundle for SNOMED
bundle = fhir.resources("CodeSystem").search(
url="http://snomed.info/sct",
).fetch()
# Example: call $lookup directly via fhirpy
lookup = fhir.execute(
"CodeSystem/$lookup",
method="GET",
params={"system": "http://snomed.info/sct", "code": "44054006"},
)
get_async_fhirpy_client() is the async counterpart.
Use the Concept Resolver (client.fhir.resolve) when you want OMOP-enriched answers - standard concept ID, CDM target table, mapping quality. Use fhirpy against client.fhir_server_url when you need raw FHIR Parameters / Bundle responses for FHIR-native tooling.
Error Handling
The resolver raises standard SDK errors for API failures:
from omophub import APIError
try:
result = client.fhir.resolve(
system="http://www.ama-assn.org/go/cpt",
code="99213",
)
except APIError as e:
print(e.status_code) # 403
print(e.message) # "vocabulary_restricted"
| Error Code | HTTP | Cause |
|---|
unknown_system | 400 | FHIR code system URI not recognized (includes a typo suggestion when close) |
missing_input | 400 | Neither (system + code) / (vocabulary_id + code) / display provided |
concept_not_found | 404 | No concept found via lookup or semantic search |