Status: 1.0.0
GraphNight is an embeddable semantic layer for AI agents and humans. Define metrics once, query them through GraphQL or a CLI, and generate dialect-specific SQL for Postgres, MySQL, SQLite, and DuckDB.
Language Bindings: Python (PyPI) | Elixir (Hex.pm) | Node.js (npm)
See LAUNCH.md for the full checklist. Remaining gaps (vault secret managers, some observability polish) are documented under Security notes in CHANGELOG.md.
- Semantic models (measures, dimensions, time dimensions, joins)
- Formula helpers (
sum,avg,count,time_shift,ratio, …) - SQL generation for Postgres / MySQL / SQLite / DuckDB
- GraphQL API on Axum + CLI (
graphnight init, query dry-run, model list) - YAML / SQLite / Postgres metadata storage (HA shared store) and Tantivy search (Postgres search is ILIKE-only)
- API keys + OIDC JWT auth;
PolicyEnforceron the live query path (allow/deny, forced filters, RLS, max rows) - Plan/result caches, streaming executor, Docker, durable JSONL audit
- Rust 1.75+ (stable)
- Optional: a SQL database for non-
dryRunqueries
cargo build --release -p graphnight-cli -p graphnight-servercargo run -p graphnight-cli -- init ./my-project
cargo run -p graphnight-cli -- \
--storage-path ./my-project/graphnight_data \
query dry-run --file ./my-project/query.jsonOr use the checked-in examples:
cargo run -p graphnight-cli -- \
--storage-path ./examples/data \
model list
cargo run -p graphnight-cli -- \
--storage-path ./examples/data \
query dry-run --file ./examples/query.jsonMore samples (auth curls, GraphQL docs, HA, ratio/join dry-runs): examples/README.md.
Longer walkthrough: docs/getting-started.md. Full docs index: docs/README.md.
./target/release/graphnight-server \
--config examples/graphnight.toml \
--storage-path examples/data \
--host 127.0.0.1 \
--port 8080Health check (JSON; 503 if metadata storage is unreachable):
curl -s http://127.0.0.1:8080/health
GraphQL: POST http://127.0.0.1:8080/graphql
docker compose up --build
# http://127.0.0.1:8080/health
# optional auth: GRAPHNIGHT_API_KEYS=alice:secret1 docker compose up --buildData persists in the graphnight-data volume (/data in the container). Image includes graphnight-server and the graphnight CLI.
HA metadata (optional Postgres):
docker compose --profile ha up --build metadata-db server-postgres
# metadata on :5433, server on :8081
# GRAPHNIGHT_METADATA_DATABASE_URL=postgresql://graphnight:graphnight@127.0.0.1:5433/graphnight_metaFor multi-replica deployments, set shared metadata in graphnight.toml:
[storage]
type = "postgres"
path = "env:GRAPHNIGHT_METADATA_DATABASE_URL"Or omit path and export GRAPHNIGHT_METADATA_DATABASE_URL directly. path / --storage-path may also be a raw postgresql://… URL. Schema tables are created on connect (CREATE TABLE IF NOT EXISTS). Model search on this backend is basic ILIKE (not Tantivy). See examples/graphnight.postgres.toml.
curl http://127.0.0.1:8080/graphql \
-H 'content-type: application/json' \
-d @- <<'EOF'
{
"query": "query { query(input: { name: \"orders\", measures: [{ formula: \"amount_usd\", aggregation: SUM, label: \"Revenue\" }], dimensions: [{ name: \"status\" }], limit: 10 }, dryRun: true) { sql columns executionTimeMs } }"
}
EOF| Path | Purpose |
|---|---|
examples/README.md |
Index of all examples |
examples/graphnight.toml |
Server config (YAML metadata) |
examples/graphnight.postgres.toml |
HA Postgres metadata config |
examples/data/models.yaml |
Demo semantic models |
examples/data/datasources.yaml |
Demo datasource |
examples/query.json |
CLI query payload |
examples/query.graphql |
GraphQL examples |
examples/queries/ |
Extra CLI dry-run JSON |
examples/graphql/ |
GraphQL ops + curl one-liners |
examples/auth/ |
API key / OIDC curls + policy notes |
examples/ha/ |
Compose --profile ha notes |
node-client/ |
Node.js HTTP client source & tests |
node-native/ |
Node.js native SDK source & tests |
Cargo.toml # workspace root
crates/
graphnight-core/ # models, formulas, joins, security types
graphnight-sql/ # SQL generator + sqlx executor
graphnight-storage/ # YAML / SQLite / Postgres / Tantivy
graphnight-graphql/ # async-graphql schema
graphnight-server/ # Axum GraphQL server binary
graphnight-cli/ # CLI binary
graphnight-python/ # PyO3 bindings (early)
examples/ # sample config, models, auth/GraphQL/HA usage
docs/ # practical guides (see Docs below)
See ARCHITECTURE.md for the longer-term blueprint (REST, MCP, Flight SQL, importers). Many items there are vision-only.
| Doc | Contents |
|---|---|
| docs/README.md | Docs index |
| docs/getting-started.md | Build, init, dry-run, server, Docker, pip |
| docs/concepts.md | Models, auth modes, storage backends, caching |
| docs/usage-cli.md | CLI: init, model list, dry-run, serve tip |
| docs/usage-graphql.md | curl, dryRun, auth headers, GraphiQL |
| docs/usage-python.md | pip install graphnight + client examples |
| docs/usage-node.md | npm install @graphnight/sdk + TypeScript examples |
| docs/auth.md | API keys, OIDC JWT, PolicyEnforcer, tenant, DEV_OPEN |
| docs/deploy.md | Docker, compose HA, reverse-proxy TLS, env cheat sheet |
By default (no API keys / OIDC), GraphQL remains open for local demos and logs a warning.
To require auth:
export GRAPHNIGHT_API_KEYS='alice:secret1'
export GRAPHNIGHT_ADMIN_KEYS='admin:adminsecret'
# optional SSO: export GRAPHNIGHT_OIDC_ISSUER='https://login.example.com/realms/app'
cargo run -p graphnight-server -- --host 127.0.0.1 --storage-path ./examples/data
# curl -H 'Authorization: Bearer secret1' ...When keys or OIDC are set: anonymous requests fail; queries use PolicyEnforcer; datasource/model writes need an admin identity. See docs/auth.md and SECURITY.md for CORS (GRAPHNIGHT_CORS_ORIGINS), TLS (terminate at a reverse proxy), and env:VARNAME datasource secret refs.
Still do not expose this to the internet with production warehouse credentials. Vault integrations and some policy edges (column masks, full query timeout) remain incomplete — see CHANGELOG.md.
pip install graphnightPyPI: https://pypi.org/project/graphnight/ (1.0.1)
Bindings live under crates/graphnight-python/ (Rust extension). Multi-platform wheels are built by .github/workflows/wheels.yml (Linux manylinux/musllinux, macOS, Windows) and published on version tags / manual dispatch. Optional: pip install 'graphnight[pandas]'.
Local develop + tests (not in default CI):
cd crates/graphnight-python && maturin develop && pytestRunnable scripts: examples/python/.
| Language | Package | Install |
|---|---|---|
| Python | PyPI: graphnight | pip install graphnight |
| Elixir | Hex.pm: graphnight | {:graphnight, "~> 1.0"} in mix.exs |
| Node.js (Native) | npm: @graphnight/native | npm install @graphnight/native |
| Node.js (HTTP) | npm: @graphnight/client | npm install @graphnight/client |
| Rust | Workspace crates | cargo add graphnight-core |
Native Rustler NIF bindings providing zero-copy access to the GraphNight engine:
{:ok, engine} = GraphNight.Client.init("./graphnight_data")
{:ok, result} = GraphNight.Client.execute_query(engine, query)See graphnight-elixir for full documentation.
Zero-copy native bindings via NAPI-RS — runs the Rust engine directly in Node.js:
import { createClient } from '@graphnight/native';
const client = createClient('./graphnight_data');
const result = await client.query({
name: 'orders',
measures: [{ formula: { expression: 'amount_usd', label: 'Revenue' }, aggregation: 'sum' }],
dimensions: [{ name: 'status' }],
});
const rows = JSON.parse(result.data);See crates/graphnight-node for source and docs/usage-native.md for full documentation.
TypeScript client for GraphNight GraphQL API — connects to a remote server:
import { createClient } from '@graphnight/client';
const client = createClient({
url: 'http://localhost:8080/graphql',
headers: { Authorization: 'Bearer <token>' },
});
const result = await client.query({
name: 'orders',
measures: [{ formula: { expression: 'amount_usd', label: 'Revenue' }, aggregation: 'sum' }],
dimensions: [{ name: 'status' }],
});See node-client for source and docs/usage-client.md for full documentation.
cargo test --workspace --exclude graphnight-python
cargo fmt --all -- --check
cargo clippy --workspace --exclude graphnight-python --all-targetsCI runs unit/integration tests plus an example CLI dry-run (see .github/workflows/ci.yml).
See CONTRIBUTING.md. Security reports: SECURITY.md.
Apache License 2.0. See LICENSE.
Tracked in LAUNCH.md:
- v0.1–v0.4 — alpha/beta trains (core → auth → cache → Docker/e2e)
- v1.0.0 — OIDC JWT, HA Postgres metadata, Postgres testcontainers, multi-platform PyPI
- Next — vault/cloud secret managers, OpenTelemetry, MCP/REST, multi-stage DAG