Metadata-Version: 2.5
Name: 9gear-sentinel
Version: 0.1.0
Summary: Data quality checks for your warehouse, declared in YAML, run anywhere.
Project-URL: Homepage, https://github.com/Mirrz64/9Gear-Sentinel
Project-URL: Documentation, https://mirrz64.github.io/9Gear-Sentinel/
Project-URL: Repository, https://github.com/Mirrz64/9Gear-Sentinel
Project-URL: Issues, https://github.com/Mirrz64/9Gear-Sentinel/issues
Project-URL: Changelog, https://github.com/Mirrz64/9Gear-Sentinel/blob/main/CHANGELOG.md
Author: Miracle Osabuogbe
License: Apache-2.0
License-File: LICENSE
Keywords: data engineering,data observability,data quality,monitoring,sql
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
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 :: Software Development :: Quality Assurance
Requires-Python: >=3.11
Requires-Dist: pydantic>=2.7
Requires-Dist: python-dotenv>=1.0
Requires-Dist: rich>=13.7
Requires-Dist: ruamel-yaml>=0.18
Requires-Dist: sqlalchemy>=2.0
Requires-Dist: typer>=0.12
Provides-Extra: dev
Requires-Dist: mypy>=1.10; extra == 'dev'
Requires-Dist: psycopg[binary]>=3.1; extra == 'dev'
Requires-Dist: pytest-cov>=5; extra == 'dev'
Requires-Dist: pytest>=8; extra == 'dev'
Requires-Dist: ruff>=0.6; extra == 'dev'
Provides-Extra: docs
Requires-Dist: mkdocs-material>=9.5; extra == 'docs'
Provides-Extra: postgres
Requires-Dist: psycopg[binary]>=3.1; extra == 'postgres'
Description-Content-Type: text/markdown

# 9Gear Sentinel

[![CI](https://github.com/Mirrz64/9Gear-Sentinel/actions/workflows/ci.yml/badge.svg)](https://github.com/Mirrz64/9Gear-Sentinel/actions/workflows/ci.yml)
[![PyPI](https://img.shields.io/pypi/v/9gear-sentinel)](https://pypi.org/project/9gear-sentinel/)
[![Python](https://img.shields.io/pypi/pyversions/9gear-sentinel)](https://pypi.org/project/9gear-sentinel/)
[![License](https://img.shields.io/badge/license-Apache--2.0-blue)](LICENSE)

**Data quality checks for your warehouse, declared in YAML and run anywhere you can run a command.**

Sentinel catches stale tables, sudden row-count drops, null spikes, duplicate keys and silent schema changes before your stakeholders do. Every check runs as SQL inside your own database, so your data never leaves it.

![Sentinel running against a demo database](https://raw.githubusercontent.com/Mirrz64/9Gear-Sentinel/main/docs/assets/demo.gif)

## Why Sentinel

- **Ten minutes to the first alert.** `pip install`, one YAML file, done. No server, no UI to host.
- **Alerts that don't nag.** Slack or email once when a check breaks and once when it recovers, not every hour while it stays broken.
- **It remembers.** Every run is stored, so checks can catch a 40% overnight drop in rows, and you can see each check's recent trend.
- **Fits your pipeline.** Clear exit codes for CI and Airflow, a built-in scheduler, and a shareable HTML report.
- **Plain SQL you can read.** `--dry-run` shows exactly what will be sent to your database.

## Quickstart

```bash
pip install "9gear-sentinel[postgres]"
sentinel init                 # writes sentinel.yml and .env.example
cp .env.example .env          # set WAREHOUSE_URL
sentinel test-connection
sentinel run
```

```yaml
tables:
  - source: warehouse
    table: analytics.orders
    checks:
      - freshness: { column: updated_at, max_age: 6h }
      - row_count_change: { max_drop_pct: 30 }
      - unique: { columns: [order_id] }
      - null_rate: { column: customer_id, max_pct: 1, severity: warn }
      - accepted_values:
          column: status
          values: [pending, paid, shipped, refunded]
      - schema_drift: {}
```

Want to see it first? The repo includes a demo database with deliberate problems:

```bash
git clone https://github.com/Mirrz64/9Gear-Sentinel.git && cd 9Gear-Sentinel
pip install -e ".[postgres]"
docker compose up -d
sentinel run -c examples/sentinel.yml
```

## Checks

| Check | Fails when |
| --- | --- |
| `freshness` | The newest timestamp is older than `max_age` |
| `row_count` | The row count is outside `min` / `max` |
| `row_count_change` | The count moved more than allowed since the last run |
| `not_null` | Any null appears in the column |
| `null_rate` | The share of nulls is above `max_pct` |
| `unique` | Any key value appears more than once |
| `accepted_values` | A value outside the list appears |
| `schema_drift` | A column is added, removed or retyped since the baseline |
| `custom_sql` | Your query returns any rows |

## Reports

`sentinel report` turns the latest run into one self-contained HTML page, with failures first and each check's recent history.

![HTML report](https://raw.githubusercontent.com/Mirrz64/9Gear-Sentinel/main/docs/assets/report.png)

## Documentation

Full docs: **[mirrz64.github.io/9Gear-Sentinel](https://mirrz64.github.io/9Gear-Sentinel/)**, covering configuration, every check, alerts, scheduling, CI recipes and the CLI.

## Supported databases

Postgres and SQLite are supported and tested. Snowflake and BigQuery are planned for v0.2.

## Contributing

Issues and pull requests are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) for setup.

## Licence

[Apache-2.0](LICENSE). Built by Miracle Osabuogbe at 9Gear Tech.
