Skip to content

Commit ba0cb9c

Browse files
author
alex-omophub
committed
Refactor examples to remove hardcoded API keys
- Updated example scripts. - Adjusted search and resolution methods in examples to reflect the new API response structures, ensuring consistency across examples. - Improved documentation and comments in example scripts for clarity and better user guidance.
1 parent e618f8d commit ba0cb9c

11 files changed

Lines changed: 257 additions & 98 deletions

File tree

examples/async_usage.py

Lines changed: 15 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,24 +11,23 @@ async def basic_async_usage() -> None:
1111
print("=== Basic Async Usage ===")
1212

1313
# Use async context manager
14-
async with omophub.AsyncOMOPHub(api_key="oh_your_api_key") as client:
14+
async with omophub.AsyncOMOPHub() as client:
1515
# Get a concept
1616
concept = await client.concepts.get(201826)
1717
print(f"Concept: {concept['concept_name']}")
1818

19-
# Search
20-
results = await client.search.basic("diabetes", page_size=5)
21-
concepts = results.get("concepts", [])
19+
# Search - returns a flat list of concept dicts
20+
concepts = await client.search.basic("diabetes", page_size=5)
2221
print(f"Found {len(concepts)} concepts")
2322

2423

2524
async def concurrent_requests() -> None:
2625
"""Demonstrate concurrent API requests."""
2726
print("\n=== Concurrent Requests ===")
2827

29-
async with omophub.AsyncOMOPHub(api_key="oh_your_api_key") as client:
28+
async with omophub.AsyncOMOPHub() as client:
3029
# Fetch multiple concepts concurrently
31-
concept_ids = [201826, 4329847, 1112807, 40483312, 37311061]
30+
concept_ids = [201826, 4329847, 1112807, 316866, 37311061]
3231

3332
tasks = [client.concepts.get(cid) for cid in concept_ids]
3433
concepts = await asyncio.gather(*tasks)
@@ -42,26 +41,20 @@ async def parallel_searches() -> None:
4241
"""Demonstrate parallel search operations."""
4342
print("\n=== Parallel Searches ===")
4443

45-
async with omophub.AsyncOMOPHub(api_key="oh_your_api_key") as client:
46-
# Run multiple searches in parallel
44+
async with omophub.AsyncOMOPHub() as client:
45+
# Run multiple searches in parallel. ``search.basic`` returns a
46+
# flat list of concept dicts for the current page; for the full
47+
# total count we iterate across pages via ``basic_iter``.
4748
search_terms = ["diabetes", "hypertension", "asthma", "depression"]
4849

49-
async def search_and_count(term: str) -> tuple[str, int]:
50-
results = await client.search.basic(term, page_size=1)
51-
# Get total from pagination metadata if available
52-
meta = results.get("meta", {}).get("pagination", {})
53-
total_items = meta.get("total_items")
54-
if total_items is not None:
55-
total = total_items
56-
else:
57-
concepts = results.get("concepts", [])
58-
total = len(concepts) if isinstance(concepts, list) else 0
59-
return term, total
60-
61-
tasks = [search_and_count(term) for term in search_terms]
50+
async def page_count(term: str) -> tuple[str, int]:
51+
concepts = await client.search.basic(term, page_size=50)
52+
return term, len(concepts)
53+
54+
tasks = [page_count(term) for term in search_terms]
6255
results = await asyncio.gather(*tasks)
6356

64-
print("Search results:")
57+
print("First-page hit counts:")
6558
for term, count in results:
6659
print(f" '{term}': {count} concepts")
6760

examples/basic_usage.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66

77
def main() -> None:
88
"""Demonstrate basic SDK usage."""
9-
# Initialize the client with your API key
10-
# You can also set OMOPHUB_API_KEY environment variable
11-
client = omophub.OMOPHub(api_key="oh_your_api_key")
9+
# Reads OMOPHUB_API_KEY from the environment. To pass it explicitly:
10+
# client = omophub.OMOPHub(api_key="oh_your_api_key")
11+
client = omophub.OMOPHub()
1212

1313
# Get a concept by ID
1414
concept = client.concepts.get(201826)
@@ -18,18 +18,18 @@ def main() -> None:
1818
print(f" Domain: {concept['domain_id']}")
1919
print()
2020

21-
# Search for concepts
21+
# Search for concepts - returns a list of concept dicts
2222
results = client.search.basic(
2323
"diabetes",
2424
vocabulary_ids=["SNOMED"],
2525
page_size=5,
2626
)
2727
print("Search results for 'diabetes':")
28-
for c in results.get("concepts", []):
28+
for c in results:
2929
print(f" {c['concept_id']}: {c['concept_name']}")
3030
print()
3131

32-
# List vocabularies
32+
# List vocabularies - returns a dict with a 'vocabularies' key
3333
vocabs = client.vocabularies.list(page_size=5)
3434
print("Available vocabularies:")
3535
for v in vocabs.get("vocabularies", []):

examples/error_handling.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ def handle_not_found() -> None:
1010
"""Handle concept not found errors."""
1111
print("=== Handling Not Found ===")
1212

13-
client = omophub.OMOPHub(api_key="oh_your_api_key")
13+
client = omophub.OMOPHub()
1414

1515
try:
1616
# Try to get a non-existent concept
@@ -40,7 +40,7 @@ def handle_rate_limit() -> None:
4040
"""Handle rate limit errors with retry."""
4141
print("\n=== Handling Rate Limits ===")
4242

43-
client = omophub.OMOPHub(api_key="oh_your_api_key")
43+
client = omophub.OMOPHub()
4444

4545
for i in range(5):
4646
try:
@@ -58,7 +58,7 @@ def handle_validation() -> None:
5858
"""Handle validation errors."""
5959
print("\n=== Handling Validation Errors ===")
6060

61-
client = omophub.OMOPHub(api_key="oh_your_api_key")
61+
client = omophub.OMOPHub()
6262

6363
try:
6464
# Try an invalid request
@@ -73,7 +73,7 @@ def comprehensive_error_handling() -> None:
7373
"""Demonstrate comprehensive error handling."""
7474
print("\n=== Comprehensive Error Handling ===")
7575

76-
client = omophub.OMOPHub(api_key="oh_your_api_key")
76+
client = omophub.OMOPHub()
7777

7878
try:
7979
concept = client.concepts.get(201826)

examples/fhir_interop.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131

3232
from __future__ import annotations
3333

34+
import os
3435
from types import SimpleNamespace
3536
from typing import TYPE_CHECKING
3637

@@ -39,7 +40,12 @@
3940
if TYPE_CHECKING:
4041
from omophub.types.fhir import Coding
4142

42-
API_KEY = "oh_your_api_key"
43+
# Read from the environment so the example runs out-of-the-box:
44+
# export OMOPHUB_API_KEY=oh_...
45+
# Scenario 8 (get_fhirpy_client) needs an explicit key string, so we
46+
# materialize it once here. All other scenarios use omophub.OMOPHub()
47+
# directly, which also picks up OMOPHUB_API_KEY.
48+
API_KEY = os.environ.get("OMOPHUB_API_KEY", "oh_your_api_key")
4349

4450

4551
# ---------------------------------------------------------------------------
@@ -51,7 +57,7 @@ def coding_kwarg_with_dict() -> None:
5157
"""Pass a plain dict via the new ``coding=`` kwarg."""
5258
print("=== 1. coding= kwarg with a plain dict ===")
5359

54-
client = omophub.OMOPHub(api_key=API_KEY)
60+
client = omophub.OMOPHub()
5561
try:
5662
result = client.fhir.resolve(
5763
coding={
@@ -76,7 +82,7 @@ def coding_kwarg_with_typed_dict() -> None:
7682
"""Use omophub's lightweight `Coding` TypedDict for IDE autocomplete."""
7783
print("\n=== 2. coding= kwarg with omophub.types.fhir.Coding ===")
7884

79-
client = omophub.OMOPHub(api_key=API_KEY)
85+
client = omophub.OMOPHub()
8086
try:
8187
coding: Coding = {
8288
"system": "http://loinc.org",
@@ -105,7 +111,7 @@ def coding_kwarg_with_duck_object() -> None:
105111
"""
106112
print("\n=== 3. coding= kwarg with a duck-typed object ===")
107113

108-
client = omophub.OMOPHub(api_key=API_KEY)
114+
client = omophub.OMOPHub()
109115
try:
110116
# SimpleNamespace stands in for any Coding-like class - fhir.resources,
111117
# fhirpy, or your own domain model.
@@ -143,7 +149,7 @@ def coding_kwarg_with_fhir_resources() -> None:
143149
print(" Skipped: pip install omophub[fhir-resources]")
144150
return
145151

146-
client = omophub.OMOPHub(api_key=API_KEY)
152+
client = omophub.OMOPHub()
147153
try:
148154
# Single Coding from fhir.resources
149155
snomed = FhirCoding(
@@ -191,7 +197,7 @@ def mixed_batch_inputs() -> None:
191197
"""A single `resolve_batch` accepts heterogeneous coding shapes."""
192198
print("\n=== 5. resolve_batch with mixed input shapes ===")
193199

194-
client = omophub.OMOPHub(api_key=API_KEY)
200+
client = omophub.OMOPHub()
195201
try:
196202
typed: Coding = {"system": "http://loinc.org", "code": "2339-0"}
197203
duck = SimpleNamespace(
@@ -232,7 +238,7 @@ def explicit_kwargs_override_coding() -> None:
232238
"""
233239
print("\n=== 6. Explicit kwargs override coding= fields ===")
234240

235-
client = omophub.OMOPHub(api_key=API_KEY)
241+
client = omophub.OMOPHub()
236242
try:
237243
base = SimpleNamespace(
238244
system="http://snomed.info/sct",
@@ -262,7 +268,7 @@ def connection_helper_urls() -> None:
262268

263269
from omophub import get_fhir_server_url
264270

265-
client = omophub.OMOPHub(api_key=API_KEY)
271+
client = omophub.OMOPHub()
266272
try:
267273
# Property on the client returns the R4 base URL
268274
print(f" client.fhir_server_url = {client.fhir_server_url}")

examples/fhir_resolver.py

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ def resolve_snomed() -> None:
2929
"""Resolve a SNOMED CT code directly to its OMOP concept."""
3030
print("=== 1. SNOMED Direct Resolution ===")
3131

32-
client = omophub.OMOPHub(api_key="oh_your_api_key")
32+
client = omophub.OMOPHub()
3333
try:
3434
result = client.fhir.resolve(
3535
system="http://snomed.info/sct",
@@ -57,7 +57,7 @@ def resolve_icd10_mapped() -> None:
5757
"""Resolve a non-standard ICD-10-CM code — automatically traverses Maps to."""
5858
print("\n=== 2. ICD-10-CM → SNOMED Mapping ===")
5959

60-
client = omophub.OMOPHub(api_key="oh_your_api_key")
60+
client = omophub.OMOPHub()
6161
try:
6262
result = client.fhir.resolve(
6363
system="http://hl7.org/fhir/sid/icd-10-cm",
@@ -89,7 +89,7 @@ def resolve_loinc() -> None:
8989
"""Resolve a LOINC lab code to the OMOP measurement table."""
9090
print("\n=== 3. LOINC → Measurement ===")
9191

92-
client = omophub.OMOPHub(api_key="oh_your_api_key")
92+
client = omophub.OMOPHub()
9393
try:
9494
result = client.fhir.resolve(
9595
system="http://loinc.org",
@@ -116,7 +116,7 @@ def resolve_rxnorm() -> None:
116116
"""Resolve an RxNorm drug code to the OMOP drug_exposure table."""
117117
print("\n=== 4. RxNorm → Drug Exposure ===")
118118

119-
client = omophub.OMOPHub(api_key="oh_your_api_key")
119+
client = omophub.OMOPHub()
120120
try:
121121
result = client.fhir.resolve(
122122
system="http://www.nlm.nih.gov/research/umls/rxnorm",
@@ -141,7 +141,7 @@ def resolve_text_only() -> None:
141141
"""Resolve using only display text — triggers BioLORD semantic search."""
142142
print("\n=== 5. Text-Only Semantic Fallback ===")
143143

144-
client = omophub.OMOPHub(api_key="oh_your_api_key")
144+
client = omophub.OMOPHub()
145145
try:
146146
# No system or code — just natural language text
147147
result = client.fhir.resolve(
@@ -168,7 +168,7 @@ def resolve_vocabulary_id_bypass() -> None:
168168
"""Use vocabulary_id directly when you already know the OMOP vocabulary."""
169169
print("\n=== 6. Vocabulary ID Bypass ===")
170170

171-
client = omophub.OMOPHub(api_key="oh_your_api_key")
171+
client = omophub.OMOPHub()
172172
try:
173173
# Skip URI resolution — go straight to the vocabulary
174174
result = client.fhir.resolve(
@@ -193,7 +193,7 @@ def resolve_with_recommendations() -> None:
193193
"""Get Phoebe-recommended related concepts alongside the resolution."""
194194
print("\n=== 7. With Phoebe Recommendations ===")
195195

196-
client = omophub.OMOPHub(api_key="oh_your_api_key")
196+
client = omophub.OMOPHub()
197197
try:
198198
result = client.fhir.resolve(
199199
system="http://snomed.info/sct",
@@ -225,7 +225,7 @@ def resolve_with_quality() -> None:
225225
"""Get a mapping quality signal to triage which resolutions need review."""
226226
print("\n=== 8. With Mapping Quality ===")
227227

228-
client = omophub.OMOPHub(api_key="oh_your_api_key")
228+
client = omophub.OMOPHub()
229229
try:
230230
# Direct SNOMED match → "high" quality
231231
result = client.fhir.resolve(
@@ -273,7 +273,7 @@ def resolve_batch() -> None:
273273
"""Resolve multiple codings in a single call with per-item error reporting."""
274274
print("\n=== 9. Batch Resolution ===")
275275

276-
client = omophub.OMOPHub(api_key="oh_your_api_key")
276+
client = omophub.OMOPHub()
277277
try:
278278
result = client.fhir.resolve_batch(
279279
[
@@ -324,7 +324,7 @@ def resolve_codeable_concept() -> None:
324324
"""Resolve a CodeableConcept with multiple codings — SNOMED wins by preference."""
325325
print("\n=== 10. CodeableConcept Resolution ===")
326326

327-
client = omophub.OMOPHub(api_key="oh_your_api_key")
327+
client = omophub.OMOPHub()
328328
try:
329329
result = client.fhir.resolve_codeable_concept(
330330
coding=[
@@ -382,7 +382,7 @@ def resolve_codeable_concept_text_fallback() -> None:
382382
"""When no structured coding resolves, fall back to the text field."""
383383
print("\n=== 11. CodeableConcept Text Fallback ===")
384384

385-
client = omophub.OMOPHub(api_key="oh_your_api_key")
385+
client = omophub.OMOPHub()
386386
try:
387387
result = client.fhir.resolve_codeable_concept(
388388
coding=[
@@ -420,7 +420,7 @@ async def async_resolve() -> None:
420420
"""Demonstrate async FHIR resolution with concurrent requests."""
421421
print("\n=== 12. Async FHIR Resolution ===")
422422

423-
async with omophub.AsyncOMOPHub(api_key="oh_your_api_key") as client:
423+
async with omophub.AsyncOMOPHub() as client:
424424
# Single resolve
425425
result = await client.fhir.resolve(
426426
system="http://snomed.info/sct",
@@ -463,7 +463,7 @@ def error_handling_examples() -> None:
463463
"""Demonstrate error responses from the FHIR resolver."""
464464
print("\n=== Error Handling Examples ===")
465465

466-
client = omophub.OMOPHub(api_key="oh_your_api_key")
466+
client = omophub.OMOPHub()
467467
try:
468468
# Unknown code system URI → 400 with suggestion
469469
print(" Typo in URI:")

examples/map_between_vocabularies.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ def get_mappings() -> None:
88
"""Get mappings for a concept to other vocabularies."""
99
print("=== Concept Mappings ===")
1010

11-
client = omophub.OMOPHub(api_key="oh_your_api_key")
11+
client = omophub.OMOPHub()
1212

1313
try:
1414
# Type 2 diabetes mellitus (SNOMED)
@@ -43,7 +43,7 @@ def map_concepts() -> None:
4343
"""Map multiple concepts to a target vocabulary."""
4444
print("\n=== Batch Concept Mapping ===")
4545

46-
client = omophub.OMOPHub(api_key="oh_your_api_key")
46+
client = omophub.OMOPHub()
4747

4848
try:
4949
# Map SNOMED concepts to ICD-10-CM
@@ -74,7 +74,7 @@ def lookup_by_code() -> None:
7474
"""Look up a concept by vocabulary code and find its standard mapping."""
7575
print("\n=== Code Lookup and Mapping ===")
7676

77-
client = omophub.OMOPHub(api_key="oh_your_api_key")
77+
client = omophub.OMOPHub()
7878

7979
try:
8080
# Look up ICD-10-CM code E11 (Type 2 diabetes)

examples/navigate_hierarchy.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33

44
import omophub
55

6-
client = omophub.OMOPHub(api_key="oh_your_api_key")
6+
# Reads OMOPHUB_API_KEY from the environment. To pass it explicitly:
7+
# client = omophub.OMOPHub(api_key="oh_your_api_key")
8+
client = omophub.OMOPHub()
79

810

911
def get_ancestors() -> None:

0 commit comments

Comments
 (0)