Skip to content

Release v4.0.1

Latest

Choose a tag to compare

@github-actions github-actions released this 27 Oct 19:17
· 3 commits to trunk since this release
849ffb1

Spice Python SDK v4.0.1

v4.0.1 is a bug-fix release on top of v4.0.0. It changes how API keys reach a self-managed Spice runtime, binds numpy and pandas scalars as query parameters, and reports the runtime's own error message from HTTP calls.

pip install git+https://github.com/spiceai/spicepy@v4.0.1

Security

certifi 2026.10.19 or later

spicepy now requires certifi 2026.10.19 or later. That release removes the emSign ECC Root CA - G3 root after the eMudhra intermediate certificate compromise. When you do not give a root certificate, spicepy uses the certifi bundle to verify TLS for Arrow Flight and HTTP calls.

Fixes

API keys on self-managed runtimes

API key authentication is now set as Authorization: Bearer <key> on all Flight and ADBC calls, except a Spice Cloud key (<appId>|<secret>) sent to a Spice Cloud address, which keeps the Basic handshake. This reduces the number of Basic FlightSQL handshakes required. HTTP calls still send X-API-Key. (#211)

numpy and pandas scalars as query parameters

Values read back out of a DataFrame now bind as parameters. Before, they raised errors such as TypeError: Unsupported parameter type: int64. (#206)

  • numpy integers, floats, and numpy.bool_ keep their width: numpy.int32 binds as int32, not a widened type.
  • numpy.datetime64 and numpy.timedelta64 bind as a date, timestamp, or duration in the nearest unit Arrow supports. For example, datetime64[D] becomes date32 and minutes become seconds. Units finer than a nanosecond truncate to nanoseconds.
  • pandas.Timestamp and pandas.Timedelta keep their own unit, so a nanosecond value is no longer truncated to microseconds. A timezone-aware Timestamp binds as its UTC instant.
  • NaT binds as a null of the type its unit would get.
  • Month and year timedelta64 values have no fixed length, so they are refused with a TypeError.
import numpy as np

reader = client.sql_with_params("SELECT name FROM items WHERE id = $1", [np.int64(1)])

The runtime's error message on HTTP calls

refresh_dataset() and runtime_status() raise SpiceAIError carrying the runtime's explanation, for example Dataset no_such_dataset not found. Before, they raised requests.HTTPError with only the status line. search() and nsql() errors report the runtime's message rather than its raw JSON envelope. (#197)

Malformed search responses

search() raises SpiceAIError when a /v1/search response lacks a field the runtime always sends. Before, a body such as {} or a proxy's error came back as an empty result. (#205)

Upgrade notes

  • Code that catches requests.HTTPError around refresh_dataset() or runtime_status() should catch spicepy.error.SpiceAIError instead.

Documentation

  • The search() docs now describe keywords as a prefilter: each keyword is a case-insensitive substring match that rows must contain, not a hybrid ranking signal. (#208)