Metadata-Version: 2.5
Name: hypequery
Version: 0.1.0b3
Summary: Type-safe ClickHouse semantic layer and serving for Python.
Project-URL: Homepage, https://hypequery.com
Project-URL: Repository, https://github.com/hypequery/hypequery
Project-URL: Issues, https://github.com/hypequery/hypequery/issues
Project-URL: Documentation, https://hypequery.com/docs/python
Project-URL: Changelog, https://github.com/hypequery/hypequery/blob/main/python/hypequery/CHANGELOG.md
Author: Hypequery
License-Expression: Apache-2.0
License-File: LICENSE
Keywords: analytics,arrow,asgi,clickhouse,datasets,django,fastapi,flask,mcp,metrics,multi-tenant,pandas,polars,semantic layer,semantic-layer
Classifier: Development Status :: 4 - Beta
Classifier: Framework :: AsyncIO
Classifier: Framework :: Django
Classifier: Framework :: FastAPI
Classifier: Framework :: Flask
Classifier: Framework :: Pydantic :: 2
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Database
Classifier: Topic :: Scientific/Engineering :: Information Analysis
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.11
Requires-Dist: anyio>=4.14.2
Requires-Dist: idna>=3.15
Requires-Dist: pydantic>=2.12.2; python_version >= '3.14'
Requires-Dist: pydantic>=2.9.2; python_version < '3.14'
Requires-Dist: tzdata>=2025.2
Provides-Extra: arrow
Requires-Dist: pyarrow>=23.0.1; extra == 'arrow'
Provides-Extra: chdb
Requires-Dist: chdb>=4.4.0; extra == 'chdb'
Provides-Extra: clickhouse
Requires-Dist: certifi>=2026.10.19; extra == 'clickhouse'
Requires-Dist: clickhouse-connect>=1.4.2; extra == 'clickhouse'
Requires-Dist: urllib3>=2.8.0; extra == 'clickhouse'
Provides-Extra: clickhouse-async
Requires-Dist: aiohttp>=3.14.4; extra == 'clickhouse-async'
Requires-Dist: certifi>=2026.10.19; extra == 'clickhouse-async'
Requires-Dist: clickhouse-connect[async]>=1.4.2; extra == 'clickhouse-async'
Requires-Dist: idna>=3.15; extra == 'clickhouse-async'
Requires-Dist: urllib3>=2.8.0; extra == 'clickhouse-async'
Provides-Extra: django
Requires-Dist: asgiref>=3.8.1; extra == 'django'
Requires-Dist: certifi>=2026.10.19; extra == 'django'
Requires-Dist: clickhouse-connect>=1.4.2; extra == 'django'
Requires-Dist: django>=5.2.17; extra == 'django'
Requires-Dist: sqlparse>=0.6.0; extra == 'django'
Requires-Dist: urllib3>=2.8.0; extra == 'django'
Provides-Extra: flask
Requires-Dist: certifi>=2026.10.19; extra == 'flask'
Requires-Dist: clickhouse-connect>=1.4.2; extra == 'flask'
Requires-Dist: flask[async]>=3.1.3; extra == 'flask'
Requires-Dist: jinja2>=3.1.6; extra == 'flask'
Requires-Dist: urllib3>=2.8.0; extra == 'flask'
Requires-Dist: werkzeug>=3.1.9; extra == 'flask'
Provides-Extra: jwt
Requires-Dist: cryptography>=50.0.0; extra == 'jwt'
Requires-Dist: pyjwt[crypto]>=2.15.0; extra == 'jwt'
Provides-Extra: pandas
Requires-Dist: pandas>=2.3.3; extra == 'pandas'
Provides-Extra: polars
Requires-Dist: polars>=1.0.0; extra == 'polars'
Provides-Extra: server
Requires-Dist: h11>=0.16.0; extra == 'server'
Requires-Dist: uvicorn>=0.30.6; extra == 'server'
Description-Content-Type: text/markdown

# hypequery for Python

**A code-first semantic layer for ClickHouse.** Define dimensions, measures and
tenant rules once in Python, query them by name, serve them from FastAPI, Django
or Flask, and reuse the same definitions from React and AI agents.

[![PyPI](https://img.shields.io/pypi/v/hypequery.svg)](https://pypi.org/project/hypequery/)
[![Python versions](https://img.shields.io/pypi/pyversions/hypequery.svg)](https://pypi.org/project/hypequery/)
[![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](https://github.com/hypequery/hypequery/blob/main/LICENSE)
[![Docs](https://img.shields.io/badge/docs-hypequery.com-0a7cff.svg)](https://hypequery.com/docs/python)

- **No metrics service.** It is a library. Definitions live in your codebase
  and queries run in your process, on your ClickHouse.
- **Typed, validated queries.** Requests are checked against the dataset before
  any SQL is generated, and the SQL is parameterized.
- **Multi-tenant by default.** Declare `tenant_key` once and every query is
  scoped to the caller's tenant.
- **One definition, every surface.** Rows, pandas, polars or Arrow in Python;
  authenticated HTTP endpoints; generated React hooks; governed MCP tools for
  agents.

## Install

```bash
pip install "hypequery[clickhouse]"
```

Python 3.11 or later. Extras: `clickhouse-async`, `server`, `jwt`, `django`,
`flask`, `pandas`, `polars`, `arrow`, and `chdb` to run on embedded ClickHouse
with no server (Linux and macOS).

## Define a dataset and query it

```python
from hypequery.datasets import (
    DatasetQuery,
    ExecutionContext,
    create_dataset_client,
    dataset,
    dimension,
    filter,
    measure,
    order,
    tenant,
)
from hypequery.execution import ClickHouseConnection, create_clickhouse_executor

orders = dataset(
    "orders",
    source="orders",
    tenant_key="tenant_id",
    time_key="created_at",
    dimensions={
        "country": dimension.string(),
        "status": dimension.string(),
        "createdAt": dimension.timestamp(column="created_at"),
    },
    measures={
        "revenue": measure.sum("amount"),
        "orderCount": measure.count("id"),
    },
)

analytics = create_dataset_client(
    executor=create_clickhouse_executor(ClickHouseConnection.from_env()),
)

result = analytics.execute(
    orders,
    DatasetQuery(
        dimensions=("country",),
        measures=("revenue", "orderCount"),
        filters=(filter.eq("status", "paid"),),
        order_by=(order.desc("revenue"),),
        limit=10,
    ),
    context=ExecutionContext(tenant=tenant("org_123")),
)
print(result.data)
```

`ClickHouseConnection.from_env()` reads `CLICKHOUSE_HOST`, `CLICKHOUSE_PORT`,
`CLICKHOUSE_DATABASE`, `CLICKHOUSE_USERNAME` and `CLICKHOUSE_PASSWORD`, or a
single `CLICKHOUSE_URL`. Already have tables? `hypequery init` introspects your
schema and writes the dataset definitions for you.

## Serve it over HTTP

The API is plain ASGI, so it mounts in FastAPI, Starlette or any ASGI app, and
is served natively from Django and Flask. Every endpoint authenticates before
reading the body and takes the tenant from the caller.

```bash
pip install "hypequery[clickhouse,jwt]" fastapi uvicorn
```

```python
from fastapi import FastAPI
from hypequery.serve import HttpSecurity, create_api, jwt_strategy, to_asgi_app

api = create_api(
    auth=jwt_strategy(
        jwks_url="https://example.auth0.com/.well-known/jwks.json",
        issuer="https://example.auth0.com/",
        audience="https://api.example.com",
    ),
    client=analytics,
    datasets={"orders": orders},
    security=HttpSecurity(allowed_hosts=("api.example.com",)),
)

app = FastAPI()
app.mount("/analytics", to_asgi_app(api))
```

`POST /analytics/datasets/orders/query` now runs the same validated, tenant-scoped
query as the Python call above. The same endpoints feed generated, type-safe React
hooks (`@hypequery/react`) and a governed MCP server (`@hypequery/mcp`) that gives
agents named metrics instead of raw SQL.

## Learn more

- [Quick start](https://hypequery.com/docs/python/quick-start)
- [Python CLI](https://hypequery.com/docs/python/cli): guided setup from a live schema, with FastAPI, Django or Flask scaffolds
- [FastAPI](https://hypequery.com/docs/python/fastapi), [Django](https://hypequery.com/docs/python/django), [Flask](https://hypequery.com/docs/python/flask)
- [DataFrames](https://hypequery.com/docs/python/dataframes): pandas, polars and Arrow results
- [React and MCP clients](https://hypequery.com/docs/python/client-endpoints)
- [Changelog](https://github.com/hypequery/hypequery/blob/main/python/hypequery/CHANGELOG.md)
- [Source and issues](https://github.com/hypequery/hypequery)

hypequery is Apache 2.0 licensed. The TypeScript edition, with a type-safe query
builder, lives in the same repository and implements the same specifications.

> **Beta.** The Python SDK is tested end to end from the installed package, but
> its APIs may still change before 1.0. Pin the version you deploy and report
> problems on [GitHub](https://github.com/hypequery/hypequery/issues).
