Skip to main content

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"

fhirpy (optional extra)

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 CodeHTTPCause
unknown_system400FHIR code system URI not recognized (includes a typo suggestion when close)
missing_input400Neither (system + code) / (vocabulary_id + code) / display provided
concept_not_found404No concept found via lookup or semantic search
See the FHIR Resolver API Reference for full response schemas and field descriptions.