Rust-first data quality monitoring middleware for FastAPI
Project description
Jin
Open-source Rust-first data quality monitoring for FastAPI.
Jin watches API responses at the business grain level, stores observations in DuckDB,
detects anomalies, and mounts an operator console at /jin.
Project docs are published on GitHub Pages at https://amit-devb.github.io/jin/.
What You Get
- embedded FastAPI middleware
- Rust-backed anomaly detection
- local DuckDB persistence
- reference uploads and templates
- scheduler-backed watch runs
- health and report APIs for review
- inline operator console at
/jin - operator workflows for setup, checks, triage, and reporting
- incident triage with acknowledge, snooze, suppress, bulk actions, notes, and resolution
- project-local single-user auth through
.env
Quick Start
Install with your preferred workflow:
pip install jin-monitor
or
uv add jin-monitor
or
poetry add jin-monitor
Fastest setup:
uv add jin-monitor
jin setup app.main
If your FastAPI object is named something other than app:
jin setup app.main --app-var api
Add Jin to your FastAPI app:
from fastapi import FastAPI
from jin import JinMiddleware
app = FastAPI()
app.add_middleware(JinMiddleware, db_path="./jin.duckdb", global_threshold=10.0)
Optional project-local auth in .env:
JIN_PROJECT_NAME=my-fastapi-project
JIN_DB_PATH=./jin.duckdb
JIN_LOG_LEVEL=INFO
JIN_AUTH_ENABLED=true
JIN_USERNAME=operator
JIN_PASSWORD=change-me
JIN_RUNTIME_HISTORY_LIMIT=2000
JIN_RUNTIME_ANOMALY_LIMIT=2000
JIN_ASYNC_INGEST_ENABLED=true
JIN_INGEST_QUEUE_SIZE=2000
JIN_INGEST_WORKERS=1
JIN_SCHEDULER_LEADER_LOCK=true
JIN_SCHEDULER_LOCK_DIR=./.jin/locks
To generate stronger local auth values:
jin auth rotate --write-env
jin auth status
jin env check
jin env set --project-name my-fastapi-project --db-path ./jin.duckdb
jin status --app package.module:app
jin urls --port 8000
jin urls --port 8000 --launch console
jin open --port 8000 --launch
jin doctor --fix --app package.module:app
jin doctor --app package.module:app --format json
jin ci check --app package.module:app --format json
jin report summary --format markdown
jin endpoints list --app package.module:app --format json
jin watches list --app package.module:app --format json
jin references validate --endpoint "/api/revenue/{retailer}/{period}" --file refs.csv --format json
jin completion zsh
Watch schedules support:
every Nh(interval)daily HH:MMweekly mon[,tue,...] HH:MM
Or use your own chosen password:
jin auth rotate --password "your-password" --write-env
Repo contributors can still use:
make auth-generate
make smoke-installs
CLI
Installed users can operate Jin from the terminal too:
jin setup app.main
jin quickstart --app package.module:app --write
jin init --interactive
jin init --app package.module:app --write
jin init --app package.module:app --write --open
jin patch fastapi --app-file app.main
jin doctor --app package.module:app
jin verify --app package.module:app
jin ci check --app package.module:app --fail-on-issues
jin endpoints list --app package.module:app
jin config show --endpoint "/api/revenue/{retailer}/{period}"
jin config set --endpoint "/api/revenue/{retailer}/{period}" --dimensions retailer,period --kpis revenue
jin templates generate --endpoint "/api/revenue/{retailer}/{period}" --format csv
jin references import --endpoint "/api/revenue/{retailer}/{period}" --file refs.csv
jin references export --endpoint "/api/revenue/{retailer}/{period}" --format json
jin issues list
jin issues update --id 12 --action acknowledged --note "reviewed"
jin watches list --app package.module:app
jin watches run --app package.module:app --endpoint "/api/watch/{retailer}"
You can also seed the local Jin database with discovered FastAPI endpoints during setup:
jin init --interactive --app package.module:app
Jin is designed to live inside the client project's own infrastructure:
- the dashboard is mounted inside the FastAPI app
- DuckDB stays local to the project deployment
- project identity is local to that install
- recent operator errors and incidents are isolated per project
- terminal logs use the configured
JIN_LOG_LEVELfor project-local diagnostics
Or start from the included template:
cp .env.example .env
Start the app, then open:
/jin
Core Operator APIs
The first-release workflow centers on a single project. The endpoints below can automate that path, with preferred PO-friendly names first and legacy aliases still supported:
For the data shape learning guide, see Data Shape Guide.
-
Preferred stable base:
/jin/api/v2/... -
Backward compatibility:
/jin/api/...aliases remain available during migration -
Migration notes:
docs/api-v2-migration.md -
Legacy core routes now emit deprecation headers with a sunset:
Deprecation,Sunset, andLinkto/jin/api/v2/migration -
POST /jin/api/upload/{path}: configure baseline by uploading CSV/XLSX references -
POST /jin/api/check/{path}: trigger a monitor run now -
POST /jin/api/promote-baseline/{path}: refresh baseline from recent history -
GET /jin/api/health: project-level health checks (/jin/api/health-checkalias) -
POST /jin/api/projects/register(legacy:POST /jin/api/register): register operator credentials and initialize current project metadata -
GET/POST /jin/api/projects: list and add projects in the local install -
POST /jin/api/projects/activate(legacy:POST /jin/api/projects/select): switch active project context -
GET /jin/api/projects/current(legacy:GET /jin/api/projects/active): return currently selected project -
GET /jin/api/portfolio/health(legacy:GET /jin/api/projects/monitor): monitor health snapshots across projects in the local install -
GET/POST /jin/api/projects/{project_id}/check-plan(legacy:/monitor-policy): configure schedule template, baseline mode, and recurring report defaults per project -
POST /jin/api/projects/{project_id}/check-plan/apply(legacy:/monitor-policy/apply): apply project check plan to endpoint watch configs -
POST /jin/api/projects/{project_id}/check-plan/bootstrap(legacy:/monitor-bootstrap): one-shot bootstrap apply for current runtime endpoints -
POST /jin/api/projects/{project_id}/checks/run(legacy:/run-bundle): execute a monitoring bundle across selected watched endpoints -
GET /jin/api/projects/{project_id}/checks/history(legacy:/run-bundle/history): list recent bundle run artifacts -
GET /jin/api/projects/{project_id}/checks/{run_id}(legacy:/run-bundle/{run_id}): retrieve one bundle run artifact -
GET /jin/api/projects/{project_id}/checks/{run_id}/report(legacy:/run-bundle/{run_id}/report): report pack (?format=markdownsupported) -
POST /jin/api/projects/{project_id}/baseline/refresh(legacy:/baseline/promote): promote baselines in bulk for a selected project -
GET /jin/api/status?project_id=...: read status for a selected project context -
GET /jin/api/health?project_id=...: run health checks for a selected project context -
POST /jin/api/watch-config/{path}: schedule checks and baseline mode per endpoint -
GET /jin/api/reports/summary(legacy:/report/summary): executive summary (?format=markdown&project_id=...supported) -
GET /jin/api/reports/leadership-digest(legacy:/report/executive-digest): project digest (?days=7&format=markdown&project_id=...supported) -
GET /jin/api/reports/endpoint/{path}(legacy:/report/endpoint/{path}): endpoint-level report (?format=markdown&project_id=...supported) -
GET /jin/api/v2/po/playbook(legacy alias:/jin/api/po/playbook): workflow catalog for monitor, validate, regression, and reporting -
GET /jin/po(alias:/jin/po/docs): dashboard entrypoint that opens Jin in Playbook mode
Maintainer Demo Harness
An internal maintainer harness lives in examples/fastapi_demo/app.py.
Run it with:
make demo-run
Then visit:
http://127.0.0.1:8000/api/revenue/amazon/YTDhttp://127.0.0.1:8000/api/inventory/amazonhttp://127.0.0.1:8000/jinhttp://127.0.0.1:8000/jin/po
This harness is for repository verification and maintainer onboarding only.
Docs
The docs site scaffold lives under docs/ and mkdocs.yml.
To serve it locally:
make docs-serve
Key pages:
docs/getting-started.mddocs/operator-guide.mddocs/incidents.mddocs/configuration.mddocs/api-v2-migration.mddocs/example-app.mddocs/release.md
Architecture
Jin is intentionally split into a native core and a thin Python wrapper.
Rust core
src/core/types.rs: config and result typessrc/core/json.rs: flattening and numeric helperssrc/core/grain.rs: dimension lookup and deterministic grain keyssrc/core/storage.rs: DuckDB schema, persistence, config/reference storagesrc/core/engine.rs: observation processing, anomaly logic, status/detail orchestrationsrc/lib.rs: PyO3 bindings only
Python adapter
python/jin/config.py: Pydantic/FastAPI reflection and normalized config shapingpython/jin/middleware.py: FastAPI middleware, runtime cache, and DB-coordination gluepython/jin/router.py:/jinAPI routes and native-first fallback orchestrationpython/jin/scheduler.py: APScheduler integration and watch job runtime statepython/jin/dashboard.py: operator dashboard HTML/JSpython/jin/uploader.py: CSV/XLSX parsing and validationpython/jin/templates.py: reference template generationpython/jin/watch.py: watch decorator
Compatibility entrypoints are preserved under:
python/jin/app/python/jin/core/python/jin/io/
Verification
Primary commands:
make develop
make test-python
make coverage-python
make test-rust
make docs-serve
make verify
make verify-full
make coverage-rust
Direct commands:
UV_CACHE_DIR=.uv-cache PYO3_USE_ABI3_FORWARD_COMPATIBILITY=1 PYTHONPATH=python .venv/bin/maturin develop
PYTHONPATH=python .venv/bin/coverage run --rcfile=.coveragerc -m pytest
PYTHONPATH=python .venv/bin/coverage report --rcfile=.coveragerc -m
PYO3_USE_ABI3_FORWARD_COMPATIBILITY=1 cargo test
PYO3_USE_ABI3_FORWARD_COMPATIBILITY=1 cargo llvm-cov --ignore-filename-regex '(/.cargo/registry|target/)' --summary-only
Branch protection setup (required checks on main):
GH_TOKEN=your_repo_admin_token make protect-main
This sets required checks to:
CI / verifyCI / e2e
CI / verify exercises both native Rust execution and the Python fallback path, so a
failure there usually points to a storage/bootstrap mismatch rather than a single test file.
Current Expectations
- Python integration and end-to-end tests stay green
- Python package coverage stays at
100% - Rust tests stay green
- Native coverage is tracked and improved as Rust behavior expands
Status
The project is functional as a Rust-first FastAPI product and includes:
- MVP operator UX
- reference management and uploads
- scheduler controls
- incident explainability and triage
- docs scaffold
- maintainer demo harness
- CI and publish workflow scaffolding
External release steps still depend on your final execution:
- real PyPI publish
- running GitHub Actions in your remote repo
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file jin_monitor-0.1.0.tar.gz.
File metadata
- Download URL: jin_monitor-0.1.0.tar.gz
- Upload date:
- Size: 583.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
febcd1f2da7ef2a75328edbb9de94c16ac0cd8ae75b92167d4e1b22503eb00d0
|
|
| MD5 |
c4c8fd4ca5594c53d77b535c112ffd1c
|
|
| BLAKE2b-256 |
c45bf142d77bd9f5bb8afc27a1a15c108825e4c320488b8b187f15787c8e692c
|
Provenance
The following attestation bundles were made for jin_monitor-0.1.0.tar.gz:
Publisher:
publish.yml on amit-devb/jin
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
jin_monitor-0.1.0.tar.gz -
Subject digest:
febcd1f2da7ef2a75328edbb9de94c16ac0cd8ae75b92167d4e1b22503eb00d0 - Sigstore transparency entry: 1235514220
- Sigstore integration time:
-
Permalink:
amit-devb/jin@8245eaa8f437cdced56b45a48cdfb04b9c25a957 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/amit-devb
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@8245eaa8f437cdced56b45a48cdfb04b9c25a957 -
Trigger Event:
push
-
Statement type:
File details
Details for the file jin_monitor-0.1.0-cp313-cp313-win_amd64.whl.
File metadata
- Download URL: jin_monitor-0.1.0-cp313-cp313-win_amd64.whl
- Upload date:
- Size: 10.4 MB
- Tags: CPython 3.13, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5774185c7f7f458a42a1d72e7a040d1fbd1a60c77e70f1dd73d6fa4ade78973a
|
|
| MD5 |
5680e80d2f84ec6644a8020c1c0f1ffe
|
|
| BLAKE2b-256 |
288a703bab0938f9e5818423d266b00feb8a0e43807fb6f707f85cc09c6066c6
|
Provenance
The following attestation bundles were made for jin_monitor-0.1.0-cp313-cp313-win_amd64.whl:
Publisher:
publish.yml on amit-devb/jin
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
jin_monitor-0.1.0-cp313-cp313-win_amd64.whl -
Subject digest:
5774185c7f7f458a42a1d72e7a040d1fbd1a60c77e70f1dd73d6fa4ade78973a - Sigstore transparency entry: 1235514310
- Sigstore integration time:
-
Permalink:
amit-devb/jin@8245eaa8f437cdced56b45a48cdfb04b9c25a957 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/amit-devb
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@8245eaa8f437cdced56b45a48cdfb04b9c25a957 -
Trigger Event:
push
-
Statement type:
File details
Details for the file jin_monitor-0.1.0-cp313-cp313-manylinux_2_38_x86_64.whl.
File metadata
- Download URL: jin_monitor-0.1.0-cp313-cp313-manylinux_2_38_x86_64.whl
- Upload date:
- Size: 16.2 MB
- Tags: CPython 3.13, manylinux: glibc 2.38+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8466f47a05dbfab149f34cd2c9487c562e71f634eea5dca92903685a18c94280
|
|
| MD5 |
9b6073427e417a55ef37bc1cf4076e5c
|
|
| BLAKE2b-256 |
533a6b0a45b8a1c34c115a9d531a91bad85c0cd985d26a00d748ed315d68c3b6
|
Provenance
The following attestation bundles were made for jin_monitor-0.1.0-cp313-cp313-manylinux_2_38_x86_64.whl:
Publisher:
publish.yml on amit-devb/jin
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
jin_monitor-0.1.0-cp313-cp313-manylinux_2_38_x86_64.whl -
Subject digest:
8466f47a05dbfab149f34cd2c9487c562e71f634eea5dca92903685a18c94280 - Sigstore transparency entry: 1235514263
- Sigstore integration time:
-
Permalink:
amit-devb/jin@8245eaa8f437cdced56b45a48cdfb04b9c25a957 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/amit-devb
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@8245eaa8f437cdced56b45a48cdfb04b9c25a957 -
Trigger Event:
push
-
Statement type:
File details
Details for the file jin_monitor-0.1.0-cp313-cp313-macosx_11_0_arm64.whl.
File metadata
- Download URL: jin_monitor-0.1.0-cp313-cp313-macosx_11_0_arm64.whl
- Upload date:
- Size: 12.2 MB
- Tags: CPython 3.13, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a2a7c23b3bfc8f1377b349a5932eb852a8417c717cc2017203c5f1343b0a2afb
|
|
| MD5 |
6088017d3b221f0d7b8f7c8ace635373
|
|
| BLAKE2b-256 |
754e4581b2bbdefc9dccd99e41504471dc995393643d163ad8ab02bd16cc23f4
|
Provenance
The following attestation bundles were made for jin_monitor-0.1.0-cp313-cp313-macosx_11_0_arm64.whl:
Publisher:
publish.yml on amit-devb/jin
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
jin_monitor-0.1.0-cp313-cp313-macosx_11_0_arm64.whl -
Subject digest:
a2a7c23b3bfc8f1377b349a5932eb852a8417c717cc2017203c5f1343b0a2afb - Sigstore transparency entry: 1235514379
- Sigstore integration time:
-
Permalink:
amit-devb/jin@8245eaa8f437cdced56b45a48cdfb04b9c25a957 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/amit-devb
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@8245eaa8f437cdced56b45a48cdfb04b9c25a957 -
Trigger Event:
push
-
Statement type: