ClickHouse FastAPI
Serve ClickHouse analytics from FastAPI without hand-writing every endpoint
Most FastAPI analytics endpoints are the same code repeated: parse filters, build SQL, add the tenant, check permissions, shape errors. hypequery serves your ClickHouse datasets as authenticated, tenant-scoped endpoints, so the route stops being where the analytics logic lives.
Framework
Mounted in FastAPI
Auth
Bearer tokens or API keys
Default
Authenticated, docs closed
Every endpoint rebuilds the same plumbing
Filter parsing, SQL building, pagination, and error shapes get reimplemented per route, and each one handles the edge cases slightly differently.
Tenant scoping lives in handler code
If each handler adds its own tenant filter, one missed handler exposes another customer’s data. The safe default should not depend on every developer remembering it.
Request bodies become an attack surface
Flexible analytics endpoints invite callers to send SQL fragments, extra fields, or a different tenant id. Validation has to be strict, and it is easy to get wrong.
Serve
Register a dataset as an authenticated endpoint, then mount it
Every route on the API requires authentication unless you mark it public, and authentication runs before the body is read. The tenant always comes from the authenticated principal.
- Bearer token or API key credentials, verified by your own authenticator
- Per-endpoint roles, scopes, and tenant requirements
- Strict JSON bodies: unknown fields, coercion, and tenant or SQL injection attempts are refused
- Pagination, result metadata, and an authenticated discovery catalog
- Rate limiting, allowed hosts, CORS, trusted proxies, and request ids
API
A tenant-scoped dataset endpoint
orders and analytics are the dataset and client from your Python model.
Call it
One request shape for every dataset
Callers post dimensions, measures, filters, ordering, a time grain, and pagination. Errors use one envelope with stable types, so clients handle them the same way everywhere.
The request and response shapes match the TypeScript Serve runtime, and shared HTTP fixtures run against both implementations in CI. HTTP clients written against one work against the other.
For a standalone service, the production profile runs one hardened Uvicorn worker with concurrency, timeout, row, and byte limits, and rejects debug settings at startup.
Request
Query the endpoint over HTTP
Measure values are strings on the wire, matching TypeScript.
Where teams usually get stuck
Questions teams ask
Who this is for
Teams exposing ClickHouse analytics from a Python backend, especially to customers in a multi-tenant product.
Fits your existing app
The API is a plain ASGI app, so it mounts under a prefix in your existing FastAPI app. Your own routes stay exactly as they are.
Security defaults
Docs and OpenAPI are closed unless you enable them for development, and authenticated responses are never cached.
Where to go next
Start with the Python datasets docs if you have not modelled a table yet, then come back to serving. To call these endpoints from React or an AI agent, add a client profile and generate typed hooks.
Further reading
Go deeper where it actually helps
Python Serve docs
Getting started, dataset endpoints, authentication, and multi-tenancy.
Open guide
Production profile
Run the service with validated process, timeout, and result limits.
Open guide
ClickHouse with Python
Model ClickHouse tables as datasets and query them by name.
Open guide
React and MCP clients
Type-safe React hooks and agent tools over the same endpoints.
Open guide
ClickHouse REST API
The same served API pattern in TypeScript.
Open guide
Next step
Serve one dataset behind your existing auth
Wire your token verification into the authenticator, register one dataset endpoint, and point a dashboard or customer integration at it.
Open source, and it runs in your own backend. Want it hosted?