Skip to content

feat: add search for the runtime's /v1/search endpoint - #177

Open
claudespice wants to merge 2 commits into
spiceai:trunkfrom
claudespice:feat/search
Open

feat: add search for the runtime's /v1/search endpoint#177
claudespice wants to merge 2 commits into
spiceai:trunkfrom
claudespice:feat/search

Conversation

@claudespice

Copy link
Copy Markdown

What

Adds Client.search(...), wrapping the runtime's /v1/search endpoint — vector similarity search, with optional keywords for a hybrid lexical + vector ranking.

result = client.search(
    'tokyo plane tickets',
    datasets=['app_messages'],
    limit=3,
    additional_columns=['timestamp'],
)
for match in result:
    print(match.score, match.dataset, match.matches)

Why

/v1/search works on a default spice run, but of the six client SDKs only spice.js could reach it. Python users had to hand-roll the HTTP call, including the response shape.

Part of aligning capabilities across the SDKs against the runtime's own API surface.

Two details the response types encode, taken from the runtime's wire format rather than the OpenAPI example (which is out of date on the first point):

  • matches is a list of values per column — one column can contribute several chunks to a single match.
  • data, primary_key, and metadata are omitted by the runtime when empty, so each defaults to {} rather than being required.

Also adds HttpRequests.post_json. send_request relies on raise_for_status, which discards the response body; the runtime reports search failures as plain text ("No data sources provided"), so that message would otherwise be lost behind a generic 400 Client Error. Arguments the runtime would reject with a 400 — empty text, an empty datasets list, a limit below 1 — are validated locally so the error names the argument to fix.

Verification

  • pytest tests/test_search.py tests/test_http.py — 58 passed
  • Full unit suite (pytest -m "unit or not (integration or cloud or slow)") — 401 passed, 8 failed. All 8 failures are pre-existing ImportError: adbc_driver_manager in tests/test_main.py (ADBC driver not installed in this environment); none are in changed code.
  • ruff check clean on spicepy/_search.py, spicepy/_http.py, spicepy/__init__.py, tests/test_search.py, tests/test_http.py. spicepy/_client.py reports 2 PLR0917, both pre-existing on _SpiceFlight.__init__ and Client.__init__.
  • mypy spicepy --ignore-missing-imports — success, no issues in 11 source files
  • Integration tests — not run (no live runtime available)
  • make format-check — not run. It fails on trunk today (17 files would be reformatted under the configured line-length = 120), so the new code follows the wrapping style actually committed in the repo rather than reformatting.

Adds Client.search, exposing vector, keyword, and hybrid search from
Python. Previously only spice.js could reach /v1/search; users of every
other SDK had to hand-roll the HTTP call.

Response types (SearchResult, SearchMatch) are modelled on the runtime's
actual wire shape: matches is a list per column because one column can
contribute several chunks to a match, and data / primary_key / metadata
are omitted by the runtime when empty.

Adds HttpRequests.post_json, which surfaces the runtime's plain-text
error body instead of the generic message raise_for_status produces.
@lukekim
lukekim requested review from Jeadie and Copilot August 1, 2026 20:42
@lukekim lukekim self-assigned this Aug 1, 2026
@lukekim lukekim added the enhancement New feature or request label Aug 1, 2026
@lukekim lukekim added this to the v4.0.0 milestone Aug 1, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds first-class Python SDK support for the runtime’s /v1/search endpoint by introducing request/response types, local argument validation, and HTTP plumbing to preserve runtime error messages, alongside documentation and unit tests.

Changes:

  • Add Client.search(...) plus _search.py request builder and response dataclasses (SearchResult, SearchMatch).
  • Add HttpRequests.post_json(...) to surface plain-text error bodies from the runtime instead of losing them via raise_for_status().
  • Add unit tests for search body building/parsing and for the new HTTP helper; document search() usage in the README.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated no comments.

Show a summary per file
File Description
tests/test_search.py Adds unit coverage for request-body validation/building, response parsing, and Client.search wiring.
tests/test_http.py Adds unit coverage for HttpRequests.post_json behavior and error handling.
spicepy/_search.py Introduces search types and request body construction/validation for /v1/search.
spicepy/_http.py Adds post_json helper to POST JSON and preserve runtime error details.
spicepy/_client.py Adds Client.search method that calls /v1/search and parses results.
spicepy/init.py Exports SearchMatch and SearchResult at the package top level.
README.md Documents Client.search usage, parameters, and returned types.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@claudespice

Copy link
Copy Markdown
Author

CI ran on this branch for the first time (the workflow runs had been parked at action_required since creation). Three checks came back red; one was mine, two are not.

Mine, fixed in 0a4826c: Lint with black flagged tests/test_search.py and tests/test_http.py. Both were pure re-wraps — a list literal and a test signature that fit ruff's configured 120 columns but not black's default 88. No argument, expression, or assertion changed; pytest tests/test_search.py tests/test_http.py is 58 passed before and after, and black --check spicepy tests is now clean across all 24 files. The underlying config mismatch that keeps causing this is #179.

Not mine — pre-existing on trunk: Lint with ruff fails with two PLR0917 errors in spicepy/_client.py. A clean checkout of trunk (a199cfa) reproduces both with nothing of this branch applied, so every open PR inherits them. Fixing it here would be out of scope; #178 clears it against trunk.

Not mine — fork secret: Cloud tests (Python 3.12) fails with SPICE_API_KEY: empty in the job environment. Secrets are not exposed to pull requests from forks, so all 40 test_main.py cloud tests fail at connection. Same on #173. Nothing in the branch can change this.

@claudespice

Copy link
Copy Markdown
Author

Correction to my previous comment: the ruff PLR0917 fix I pointed at is #176, not #178. I had missed that @lukekim already fixed this five days ago; #176 adds the same ignore entry and fixes the spice add spiceai/quickstart registry failure in test.yml. I have closed #178 as a duplicate.

#176 is green and awaiting review. Merging it turns the Lint with ruff job green here and on every other open PR in the repo.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants