turbopuffer-python

The official Python client for turbopuffer, a serverless vector and full-text search database, with sync and async APIs.

SDK
PyPI
v2.9.0
162stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
75/100Good
Development Activity84
Maintenance96
Community52
Maturity48
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
76/100Good
Architecture78
Code Quality85
Innovation72
Learning Curve70

turbopuffer-python is the official Python API client for turbopuffer, a serverless vector database built on object storage. It gives Python applications a typed, ergonomic interface to turbopuffer’s HTTP API for writing rows into namespaces and querying them with ANN vector search, BM25 full-text search, or hybrid ranking with structured filters.

The library is generated with Stainless from turbopuffer’s OpenAPI spec, so it ships both a synchronous Turbopuffer client and an AsyncTurbopuffer client with identical method surfaces, Pydantic response models, TypedDict request params, and auto-paginating iterators for listing namespaces. Requests can be sent over httpx (the default), aiohttp, or urllib3, and responses can be accessed as parsed models, raw HTTP responses, or streamed bodies.

Because it targets a hosted, region-partitioned service, the client is thin by design: most of its surface area is request/response typing, retry and timeout handling, and transport selection rather than business logic. It is the primary way Python developers integrate turbopuffer’s search backend into RAG pipelines, recommendation systems, and other applications that need vector or text search at scale without operating their own search infrastructure.

What You Get

  • Synchronous Turbopuffer and asynchronous AsyncTurbopuffer clients with matching method surfaces
  • A namespace() helper returning a bound Namespace object scoped to one namespace for write/query calls
  • Vector ANN search, BM25 full-text search, and hybrid rank_by queries with structured filters expressions
  • Pluggable HTTP transports — default httpx, plus optional aiohttp and urllib3 backends
  • Auto-paginating iterators for listing namespaces, with manual has_next_page()/get_next_page() control when needed
  • Typed error hierarchy (APIConnectionError, RateLimitError, APIStatusError subclasses) mapped to HTTP status codes
  • .with_raw_response and .with_streaming_response variants for inspecting headers or streaming response bodies

Common Use Cases

  • Building RAG retrieval pipelines that need vector similarity search over embedded documents
  • Adding hybrid vector + BM25 keyword search to an existing Python backend
  • Filtering search results by structured attributes (e.g. tenant, category) alongside vector/text ranking
  • Running high-throughput async ingestion or query workloads with AsyncTurbopuffer and aiohttp
  • Multi-tenant applications that partition data into many turbopuffer namespaces per customer

Under The Hood

Architecture The client is layered: _base_client.py implements SyncAPIClient/AsyncAPIClient with retry, timeout, and request-building logic shared by both sync and async paths; resources/namespaces.py implements the single namespaces resource (turbopuffer’s one real API surface — write, query, list); and lib/namespace.py layers an ergonomic Namespace/AsyncNamespace object bound to a default_namespace on top of that resource so callers can do tpuf.namespace("x").query(...) directly. pagination.py provides SyncNamespacePage/AsyncNamespacePage auto-paginators, and _response.py/_streaming.py provide raw and streamed response wrappers layered over every method. Because sync and async clients are generated in parallel from the same spec, changing the base client’s request/retry logic ripples through every resource and both variants simultaneously.

Tech Stack Pure Python 3.9+, packaged with hatchling. Runtime dependencies are httpx (default transport, with lib/transport_httpx.py), optional aiohttp and urllib3 backends (transport_aiohttp.py, transport_urllib3.py) selected via extras, pydantic 1.x/2.x compatibility handled through _compat.py, orjson for fast JSON encoding, pybase64 for encoding vector payloads, and anyio/distro/sniffio for async-runtime detection. Tooling is uv-managed, with ruff for linting, pyright in strict mode plus mypy for type checking, and pytest with pytest-asyncio and respx for HTTP-mocked tests.

Code Quality The repo carries an extensive test suite under tests/api_resources, tests/custom, and tests/test_utils, exercising both sync and async clients against mocked HTTP responses. Type checking is strict — pyright’s strict mode and mypy with disallow_untyped_defs/disallow_any_generics enabled — and ruff enforces import ordering, unused-import removal, and bugbear rules. GitHub Actions workflows cover CI, PR targeting, PyPI publishing, and automated custom-type regeneration, indicating a maintained release pipeline.

API Design As a Stainless-generated SDK, the library invests heavily in developer ergonomics beyond a bare HTTP wrapper: a bound Namespace object removes repetitive namespace-name passing, TypedDict nested params give editor autocomplete for filter/rank_by expressions, Pydantic response models expose .to_json()/.to_dict() helpers, and .with_raw_response/.with_streaming_response give escape hatches to raw headers or streamed bodies without changing call sites. The tradeoff is a thin business-logic layer — most of the client’s value is typed access to turbopuffer’s hosted API rather than novel local computation.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search