|
13 | 13 | from ..types.common import PaginationMeta |
14 | 14 | from ..types.concept import Concept |
15 | 15 | from ..types.search import ( |
| 16 | + BulkSearchDefaults, |
| 17 | + BulkSearchInput, |
| 18 | + BulkSearchResponse, |
| 19 | + BulkSemanticSearchDefaults, |
| 20 | + BulkSemanticSearchInput, |
| 21 | + BulkSemanticSearchResponse, |
16 | 22 | SearchResult, |
17 | 23 | SemanticSearchResult, |
18 | 24 | SimilarSearchResult, |
@@ -372,6 +378,77 @@ def fetch_page( |
372 | 378 |
|
373 | 379 | yield from paginate_sync(fetch_page, page_size) |
374 | 380 |
|
| 381 | + def bulk_basic( |
| 382 | + self, |
| 383 | + searches: list[BulkSearchInput], |
| 384 | + *, |
| 385 | + defaults: BulkSearchDefaults | None = None, |
| 386 | + ) -> BulkSearchResponse: |
| 387 | + """Execute multiple lexical searches in a single request. |
| 388 | +
|
| 389 | + Sends up to 50 search queries in one API call. Each search can have |
| 390 | + its own filters, or you can set shared defaults. |
| 391 | +
|
| 392 | + Args: |
| 393 | + searches: List of search inputs, each with a unique ``search_id`` |
| 394 | + and ``query``. Max 50 items. |
| 395 | + defaults: Default filters applied to all searches. Individual |
| 396 | + search-level values override defaults. |
| 397 | +
|
| 398 | + Returns: |
| 399 | + Bulk results with per-search status, results, and timing. |
| 400 | +
|
| 401 | + Example:: |
| 402 | +
|
| 403 | + results = client.search.bulk_basic([ |
| 404 | + {"search_id": "q1", "query": "diabetes"}, |
| 405 | + {"search_id": "q2", "query": "hypertension"}, |
| 406 | + ], defaults={"vocabulary_ids": ["SNOMED"], "page_size": 5}) |
| 407 | +
|
| 408 | + for item in results["results"]: |
| 409 | + print(item["search_id"], len(item["results"])) |
| 410 | + """ |
| 411 | + body: dict[str, Any] = {"searches": searches} |
| 412 | + if defaults: |
| 413 | + body["defaults"] = defaults |
| 414 | + return self._request.post("/search/bulk", json_data=body) |
| 415 | + |
| 416 | + def bulk_semantic( |
| 417 | + self, |
| 418 | + searches: list[BulkSemanticSearchInput], |
| 419 | + *, |
| 420 | + defaults: BulkSemanticSearchDefaults | None = None, |
| 421 | + ) -> BulkSemanticSearchResponse: |
| 422 | + """Execute multiple semantic searches in a single request. |
| 423 | +
|
| 424 | + Sends up to 25 natural-language queries in one API call using neural |
| 425 | + embeddings. Each search can have its own filters and threshold. |
| 426 | +
|
| 427 | + Args: |
| 428 | + searches: List of search inputs, each with a unique ``search_id`` |
| 429 | + and ``query`` (1-500 chars). Max 25 items. |
| 430 | + defaults: Default filters applied to all searches. Individual |
| 431 | + search-level values override defaults. |
| 432 | +
|
| 433 | + Returns: |
| 434 | + Bulk results with per-search status, similarity scores, and |
| 435 | + optional query enhancements. |
| 436 | +
|
| 437 | + Example:: |
| 438 | +
|
| 439 | + results = client.search.bulk_semantic([ |
| 440 | + {"search_id": "s1", "query": "heart failure treatment"}, |
| 441 | + {"search_id": "s2", "query": "type 2 diabetes medication"}, |
| 442 | + ], defaults={"threshold": 0.8, "page_size": 10}) |
| 443 | +
|
| 444 | + for item in results["results"]: |
| 445 | + print(item["search_id"], item.get("result_count", 0)) |
| 446 | + """ |
| 447 | + body: dict[str, Any] = {"searches": searches} |
| 448 | + if defaults: |
| 449 | + body["defaults"] = defaults |
| 450 | + return self._request.post("/search/semantic-bulk", json_data=body) |
| 451 | + |
375 | 452 | def similar( |
376 | 453 | self, |
377 | 454 | *, |
@@ -630,6 +707,46 @@ async def semantic_iter( |
630 | 707 |
|
631 | 708 | page += 1 |
632 | 709 |
|
| 710 | + async def bulk_basic( |
| 711 | + self, |
| 712 | + searches: list[BulkSearchInput], |
| 713 | + *, |
| 714 | + defaults: BulkSearchDefaults | None = None, |
| 715 | + ) -> BulkSearchResponse: |
| 716 | + """Execute multiple lexical searches in a single request. |
| 717 | +
|
| 718 | + Args: |
| 719 | + searches: List of search inputs (max 50). |
| 720 | + defaults: Default filters for all searches. |
| 721 | +
|
| 722 | + Returns: |
| 723 | + Bulk results with per-search status and results. |
| 724 | + """ |
| 725 | + body: dict[str, Any] = {"searches": searches} |
| 726 | + if defaults: |
| 727 | + body["defaults"] = defaults |
| 728 | + return await self._request.post("/search/bulk", json_data=body) |
| 729 | + |
| 730 | + async def bulk_semantic( |
| 731 | + self, |
| 732 | + searches: list[BulkSemanticSearchInput], |
| 733 | + *, |
| 734 | + defaults: BulkSemanticSearchDefaults | None = None, |
| 735 | + ) -> BulkSemanticSearchResponse: |
| 736 | + """Execute multiple semantic searches in a single request. |
| 737 | +
|
| 738 | + Args: |
| 739 | + searches: List of search inputs (max 25). |
| 740 | + defaults: Default filters for all searches. |
| 741 | +
|
| 742 | + Returns: |
| 743 | + Bulk results with per-search status and similarity scores. |
| 744 | + """ |
| 745 | + body: dict[str, Any] = {"searches": searches} |
| 746 | + if defaults: |
| 747 | + body["defaults"] = defaults |
| 748 | + return await self._request.post("/search/semantic-bulk", json_data=body) |
| 749 | + |
633 | 750 | async def similar( |
634 | 751 | self, |
635 | 752 | *, |
|
0 commit comments