ClickHouse Flask
ClickHouse analytics in Flask routes, defined once
Flask keeps your routes small. hypequery keeps your ClickHouse analytics small too: measures and dimensions defined once in Python, queried by name from any route, and scoped to the customer making the request.
Works in
Any Flask route
Tenant from
A tenant loader
Exports
Typed pandas DataFrames
SQL strings in every route
Each report route builds its own ClickHouse query. Renaming a column or changing what “revenue” means touches all of them.
Request parsing is hand-rolled
Filters, groupings, and page sizes come from query strings, and each route validates them differently, or not at all.
Customer scoping depends on memory
If a route forgets the organisation filter, it returns every customer’s data.
Flask routes
Query datasets from your routes
Register the extension and a tenant loader. hq.client is then bound to the current customer in each request. hypequery plans and validates the query from your dataset, then adds the tenant filter.
- Config comes from
app.configorCLICKHOUSE_URL, andinit_appvalidates it at startup async defroutes usehq.async_client; the tenant loader runs once per request- Queries without a tenant fail instead of reading every customer
- One client per process, closed at exit, never per request
app.py
A tenant-scoped Flask route
Flask-Login’s current_user stands in for your own auth.
Exports
CSV and DataFrame exports from the same definitions
Results convert to typed pandas, Polars or Arrow frames using the dataset definition, so an export route is a few lines and its numbers match the dashboard.
pip install "hypequery[flask,pandas]==0.1.0b2". Decimals become floats by default; pass decimals="decimal" to keep them exact.
For typed React hooks or the MCP bridge, register hypequery’s HTTP endpoints as a blueprint with blueprint(api): no second service, and the session API uses your Flask login.
app.py
A tenant-scoped CSV export
The route reads the same tenant as every other route.
Where teams usually get stuck
Questions teams ask
Flask ClickHouse API
Return measures by dimension from Flask routes, scoped to the signed-in customer.
Flask analytics dashboard
Back a dashboard with named measures so every chart uses the same definition.
clickhouse-connect in Flask
hypequery runs on clickhouse-connect. You get the same driver, plus planning, validation, and tenancy on top.
Is there a Flask extension?
Yes: hypequery.contrib.flask.Hypequery supports app factories, app.config, a tenant loader, and async routes.
Further reading
Go deeper where it actually helps
Next step
Move one Flask report onto a dataset
Define the dataset behind your busiest report route, then replace its SQL with a scoped query.
Open source, and it runs in your own backend. Want it hosted?