Skip to content

Commit cc2d882

Browse files
authored
v1.7.1 prep (#18)
* v1.71. prep * Update search examples to reflect new API response structures - Adjusted the `basic_search`, `filtered_search`, and `bulk_lexical_search` functions to handle the updated response format from the `client.search` methods, ensuring that results are accessed correctly from the returned dictionaries. - Enhanced comments in the code to clarify the structure of the responses and improve overall documentation for better user understanding.
1 parent 78f3867 commit cc2d882

3 files changed

Lines changed: 1061 additions & 27 deletions

File tree

CHANGELOG.md

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,34 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [1.7.1] - 2026-05-20
9+
10+
Maintenance release. Dependency and lock-file updates only — there are no
11+
source code or public API changes. The published runtime dependencies
12+
(`httpx`, `typing_extensions`) are unchanged; the updates below affect the
13+
pinned development, testing, and optional-extra dependencies in `uv.lock`
14+
and are not shipped in the wheel/sdist.
15+
16+
### Security
17+
18+
- Updated pinned development and transitive dependencies in `uv.lock` to
19+
resolve reported advisories. None of these affect the published runtime
20+
dependencies:
21+
- `idna` 3.11 → 3.15 — fixes a bypass of the CVE-2024-3651 mitigation in
22+
`idna.encode()` (transitive via `httpx`/`anyio`).
23+
- `pytest` 9.0.2 → 9.0.3 — fixes vulnerable tmpdir handling (dev only).
24+
- `python-dotenv` 1.2.1 → 1.2.2 — fixes symlink following in `set_key`
25+
that allowed arbitrary file overwrite (dev only).
26+
- `pygments` 2.19.2 → 2.20.0 — fixes a ReDoS in GUID matching
27+
(transitive, dev only).
28+
29+
### Changed
30+
31+
- Bumped `aiohttp` and added `aiohappyeyeballs` in `uv.lock` (#17).
32+
- Locked the optional FHIR extras (`fhirpy`, `fhir-resources`) and their
33+
transitive dependencies in `uv.lock`. These were already declared in
34+
`pyproject.toml` but had never been captured in the lock file.
35+
836
## [1.7.0] - 2026-04-14
937

1038
### Added
@@ -216,7 +244,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
216244
- Full type hints and PEP 561 compliance
217245
- HTTP/2 support via httpx
218246

219-
[Unreleased]: https://github.com/omopHub/omophub-python/compare/v1.6.0...HEAD
247+
[Unreleased]: https://github.com/omopHub/omophub-python/compare/v1.7.1...HEAD
248+
[1.7.1]: https://github.com/omopHub/omophub-python/compare/v1.7.0...v1.7.1
249+
[1.7.0]: https://github.com/omopHub/omophub-python/compare/v1.6.0...v1.7.0
220250
[1.6.0]: https://github.com/omopHub/omophub-python/compare/v1.5.1...v1.6.0
221251
[1.5.1]: https://github.com/omopHub/omophub-python/compare/v1.5.0...v1.5.1
222252
[1.5.0]: https://github.com/omopHub/omophub-python/compare/v1.4.1...v1.5.0

examples/search_concepts.py

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@ def basic_search() -> None:
1616
"""Demonstrate basic concept search."""
1717
print("=== Basic Search ===")
1818

19-
# Simple text search - returns a flat list of concept dicts
20-
concepts = client.search.basic("heart attack")
19+
# ``search.basic`` returns a dict with a ``concepts`` list plus pagination
20+
# metadata - read the list from ``result["concepts"]``.
21+
result = client.search.basic("heart attack")
22+
concepts = result["concepts"]
2123
print(f"Found {len(concepts)} concepts for 'heart attack'")
2224

2325
for c in concepts[:3]:
@@ -28,14 +30,15 @@ def filtered_search() -> None:
2830
"""Demonstrate search with filters."""
2931
print("\n=== Filtered Search ===")
3032

31-
# Search in specific vocabularies
32-
concepts = client.search.basic(
33+
# Search in specific vocabularies. Same dict-shaped response as above.
34+
result = client.search.basic(
3335
"myocardial infarction",
3436
vocabulary_ids=["SNOMED", "ICD10CM"],
3537
domain_ids=["Condition"],
3638
standard_concept="S", # Only standard concepts
3739
page_size=10,
3840
)
41+
concepts = result["concepts"]
3942
print(f"Found {len(concepts)} standard condition concepts")
4043

4144
for c in concepts[:5]:
@@ -45,14 +48,15 @@ def filtered_search() -> None:
4548
def bulk_lexical_search() -> None:
4649
"""Demonstrate bulk lexical search — multiple queries in one call.
4750
48-
``bulk_basic`` returns a list of per-query result objects. Each item
49-
has ``search_id``, ``query``, ``results`` (a nested list), ``status``,
50-
and ``duration``.
51+
``bulk_basic`` returns a dict with a ``results`` list (plus
52+
``total_searches`` / ``completed_searches`` / ``failed_searches``
53+
counts). Each item in ``results`` has ``search_id``, ``query``,
54+
``results`` (a nested list of concepts), ``status``, and ``duration``.
5155
"""
5256
print("\n=== Bulk Lexical Search ===")
5357

5458
# Search for multiple terms at once (up to 50)
55-
items = client.search.bulk_basic(
59+
response = client.search.bulk_basic(
5660
[
5761
{"search_id": "q1", "query": "diabetes mellitus"},
5862
{"search_id": "q2", "query": "hypertension"},
@@ -61,13 +65,13 @@ def bulk_lexical_search() -> None:
6165
defaults={"vocabulary_ids": ["SNOMED"], "page_size": 5},
6266
)
6367

64-
for item in items:
68+
for item in response["results"]:
6569
print(
6670
f" {item['search_id']}: {len(item['results'])} results ({item['status']})"
6771
)
6872

6973
# Per-query overrides — different domains per query
70-
items = client.search.bulk_basic(
74+
response = client.search.bulk_basic(
7175
[
7276
{
7377
"search_id": "conditions",
@@ -80,7 +84,7 @@ def bulk_lexical_search() -> None:
8084
)
8185

8286
print("\n Per-query domain overrides:")
83-
for item in items:
87+
for item in response["results"]:
8488
print(f" {item['search_id']}:")
8589
for c in item["results"][:3]:
8690
print(f" {c['concept_name']} ({c['vocabulary_id']}/{c['domain_id']})")
@@ -124,8 +128,8 @@ def bulk_semantic_search() -> None:
124128
def autocomplete_example() -> None:
125129
"""Demonstrate autocomplete suggestions.
126130
127-
``concepts.suggest`` returns a flat list of concept dicts - the same
128-
shape as ``search.basic`` - so you read ``concept_name`` directly.
131+
``concepts.suggest`` returns its own response shape (distinct from
132+
``search.basic``); read suggestion fields off each item directly.
129133
"""
130134
print("\n=== Autocomplete ===")
131135

0 commit comments

Comments
 (0)