Rust Spice SDK
Rust SDK for Spice.ai.
Installation
Add the SDK:
Usage
Query a local Spice runtime
Follow the quickstart guide to install and run Spice locally.
use ;
async
Use Arrow types re-exported by the SDK
The SDK re-exports arrow as spiceai::arrow, which keeps your Arrow types aligned with the SDK's public API.
use ;
async
Parameterized queries
For common scalar bindings, use QueryParameters. For any Arrow data type, wrap a one-element Arrow array with QueryParameter::array(...). For advanced Arrow parameter batches, use Client::sql_with_params.
use ;
async
Connect to Spice.ai Cloud
use ClientBuilder;
async
Async query jobs and dataset refresh
Async query management and dataset refresh use the Spice HTTP API, so configure http_url() in addition to the Flight endpoint when needed.
use ;
async
Async queries also accept positional bindings ($1, $2, ...) and submit options. Use query_with_bindings for the common parameterized case, or query_with_options to also set an execution timeout_seconds or a maximum_size cap on the materialized result.
use ;
async
List and cancel running queries
active_queries() reports the synchronous queries currently running in the caller's scope — the ones started by sql(), FlightSQL, /v1/sql, NSQL, and search — and cancel_active_query() stops one by id.
The runtime does not hand a query's id back to the client that submitted it, so the two are used together: list to find the query, then cancel it.
Two boundaries apply, and a query is reachable only inside both.
One runtime instance. The runtime tracks active synchronous queries in memory, per instance, and these endpoints report only what the instance answering them knows. A Client configures its Flight and HTTP endpoints independently, so behind a load balancer the query submitted over Flight may be running on a different instance than the one answering here — it will not be listed, and its id reports as not found. Point http_url() at the instance running the query.
One authenticated principal, not a Client instance. The principal is whatever credential the runtime authenticates — an API key or a client certificate — so every client presenting the same credential lists and cancels the same queries. Only requests for which the runtime establishes no principal at all share the public scope. A query outside the caller's scope is reported as if it did not exist.
Runtime version. Principal scoping on these two endpoints landed in spiceai/spiceai#12841 and is in no runtime release up to and including
v2.1.5. Against an earlier runtime both calls operate on every active query the instance holds, for any caller with write access. Check your runtime version before relying on the scope described above.
use ClientBuilder;
async
To cancel an async query job instead, use cancel_query() — see Async query jobs above.
Search
search finds documents similar to a piece of text using the runtime's /v1/search endpoint. It runs against datasets that have an embedding column and a loaded embedding model — see Search & Retrieval for how to configure them. Like dataset refresh, it uses the HTTP API, so http_url() must be configured.
use ;
async
Adding with_keywords([...]) runs a lexical pass alongside the vector pass, which the runtime combines into a single hybrid ranking. with_where("user_id = 42") filters candidate rows with a SQL predicate.
Each SearchMatch carries dataset, score (higher is more similar), matches (matched values keyed by source column — a list per column, since one column can contribute several chunks to a match), primary_key, data, and metadata.
Text-to-SQL (NSQL)
nsql() answers a question in natural language: the configured LLM generates SQL, the
runtime runs it read-only, and both the rows and the generated query come back. It needs
an LLM model in the Spicepod — see Text to SQL
for how to configure one.
use ;
async
NsqlRequest takes the question plus with_model() (needed only when the Spicepod
configures more than one compatible model), with_datasets() (a hint about what to
sample for the model's context — it does not restrict which tables the generated query
may reference), with_sample_data(), and with_prompt_cache_key().
Rows in data are decoded from JSON, so they carry JSON's types rather than the Arrow
types named in schema. When Arrow types matter, generate the query and run it yourself
— which is also how to inspect or edit a generated query before it runs:
use ;
async
Inspecting the model's context
nsql_context() returns the markdown block nsql() sends the model: the in-scope
datasets and their schemas, the SQL functions available, and optionally sample rows.
Use it to see why a generated query was wrong, or to reuse the runtime's schema
context in a prompt of your own.
use ;
async
Every option is optional — a default NsqlContextRequest asks for the context the
runtime would build for all datasets its NSQL model can see. with_sampling_limit()
and with_examples_limit() cap rows per dataset, up to NSQL_CONTEXT_MAX_LIMIT.
Runtime health and status
is_ready() is a single boolean for the whole runtime. When you need to know which
component is not ready, runtime_status() reports each connection separately. Both use
the HTTP API, so configure http_url().
use ClientBuilder;
async
Each ConnectionDetails carries the component name (http, flight, metrics or
opentelemetry), its endpoint, and its status — a ComponentStatus of Initializing,
Ready, Disabled, Error, Refreshing, ShuttingDown or NotLoaded. A status a
future runtime adds deserializes into ComponentStatus::Other rather than failing.
Documentation
Check out our Documentation to learn more about how to use the Rust SDK.