scherlok 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. scherlok-0.1.0/.github/workflows/ci.yml +27 -0
  2. scherlok-0.1.0/.github/workflows/release.yml +35 -0
  3. scherlok-0.1.0/.gitignore +39 -0
  4. scherlok-0.1.0/CONTRIBUTING.md +52 -0
  5. scherlok-0.1.0/LICENSE +21 -0
  6. scherlok-0.1.0/PKG-INFO +235 -0
  7. scherlok-0.1.0/README.md +205 -0
  8. scherlok-0.1.0/pyproject.toml +57 -0
  9. scherlok-0.1.0/src/scherlok/__init__.py +3 -0
  10. scherlok-0.1.0/src/scherlok/alerter/__init__.py +1 -0
  11. scherlok-0.1.0/src/scherlok/alerter/console.py +73 -0
  12. scherlok-0.1.0/src/scherlok/alerter/exitcode.py +11 -0
  13. scherlok-0.1.0/src/scherlok/alerter/slack.py +52 -0
  14. scherlok-0.1.0/src/scherlok/cli.py +351 -0
  15. scherlok-0.1.0/src/scherlok/config.py +59 -0
  16. scherlok-0.1.0/src/scherlok/connectors/__init__.py +32 -0
  17. scherlok-0.1.0/src/scherlok/connectors/base.py +41 -0
  18. scherlok-0.1.0/src/scherlok/connectors/bigquery.py +160 -0
  19. scherlok-0.1.0/src/scherlok/connectors/postgres.py +131 -0
  20. scherlok-0.1.0/src/scherlok/detector/__init__.py +1 -0
  21. scherlok-0.1.0/src/scherlok/detector/anomaly.py +81 -0
  22. scherlok-0.1.0/src/scherlok/detector/cardinality.py +57 -0
  23. scherlok-0.1.0/src/scherlok/detector/distribution_shift.py +50 -0
  24. scherlok-0.1.0/src/scherlok/detector/freshness.py +56 -0
  25. scherlok-0.1.0/src/scherlok/detector/nullability.py +55 -0
  26. scherlok-0.1.0/src/scherlok/detector/schema_drift.py +55 -0
  27. scherlok-0.1.0/src/scherlok/detector/severity.py +46 -0
  28. scherlok-0.1.0/src/scherlok/profiler/__init__.py +1 -0
  29. scherlok-0.1.0/src/scherlok/profiler/distribution.py +26 -0
  30. scherlok-0.1.0/src/scherlok/profiler/freshness.py +26 -0
  31. scherlok-0.1.0/src/scherlok/profiler/schema.py +13 -0
  32. scherlok-0.1.0/src/scherlok/profiler/volume.py +18 -0
  33. scherlok-0.1.0/src/scherlok/store/__init__.py +1 -0
  34. scherlok-0.1.0/src/scherlok/store/remote.py +166 -0
  35. scherlok-0.1.0/src/scherlok/store/sqlite.py +143 -0
  36. scherlok-0.1.0/tests/__init__.py +0 -0
  37. scherlok-0.1.0/tests/test_alerter.py +77 -0
  38. scherlok-0.1.0/tests/test_bigquery.py +106 -0
  39. scherlok-0.1.0/tests/test_cli.py +53 -0
  40. scherlok-0.1.0/tests/test_config.py +62 -0
  41. scherlok-0.1.0/tests/test_connector.py +37 -0
  42. scherlok-0.1.0/tests/test_detector.py +294 -0
  43. scherlok-0.1.0/tests/test_profiler.py +97 -0
  44. scherlok-0.1.0/tests/test_store.py +91 -0
@@ -0,0 +1,27 @@
1
+ name: CI
2
+
3
+ on: [push, pull_request]
4
+
5
+ jobs:
6
+ test:
7
+ runs-on: ubuntu-latest
8
+ strategy:
9
+ matrix:
10
+ python-version: ["3.10", "3.12"]
11
+
12
+ steps:
13
+ - uses: actions/checkout@v4
14
+
15
+ - uses: actions/setup-python@v5
16
+ with:
17
+ python-version: ${{ matrix.python-version }}
18
+
19
+ - name: Install dependencies
20
+ run: |
21
+ pip install -e ".[dev]"
22
+
23
+ - name: Lint
24
+ run: ruff check src/ tests/
25
+
26
+ - name: Test
27
+ run: pytest tests/ -v
@@ -0,0 +1,35 @@
1
+ name: Release to PyPI
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ test:
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+ - uses: actions/setup-python@v5
17
+ with:
18
+ python-version: "3.12"
19
+ - run: pip install -e ".[dev]"
20
+ - run: ruff check src/ tests/
21
+ - run: pytest tests/ -v
22
+
23
+ publish:
24
+ needs: test
25
+ runs-on: ubuntu-latest
26
+ permissions:
27
+ id-token: write # trusted publishing
28
+ steps:
29
+ - uses: actions/checkout@v4
30
+ - uses: actions/setup-python@v5
31
+ with:
32
+ python-version: "3.12"
33
+ - run: pip install build
34
+ - run: python -m build
35
+ - uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,39 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+
7
+ # Distribution / packaging
8
+ dist/
9
+ build/
10
+ *.egg-info/
11
+ *.egg
12
+
13
+ # Virtual environments
14
+ .venv/
15
+ venv/
16
+ ENV/
17
+
18
+ # IDE
19
+ .idea/
20
+ .vscode/
21
+ *.swp
22
+ *.swo
23
+
24
+ # Environment
25
+ .env
26
+ .env.local
27
+
28
+ # Testing
29
+ .pytest_cache/
30
+ .coverage
31
+ htmlcov/
32
+
33
+ # OS
34
+ .DS_Store
35
+ Thumbs.db
36
+
37
+ # Scherlok local data
38
+ docs/
39
+ scripts/claude/tmp/
@@ -0,0 +1,52 @@
1
+ # Contributing to Scherlok
2
+
3
+ Thanks for your interest in contributing to Scherlok!
4
+
5
+ ## Development Setup
6
+
7
+ ```bash
8
+ # Clone the repo
9
+ git clone https://github.com/rbmuller/scherlok.git
10
+ cd scherlok
11
+
12
+ # Create virtual environment
13
+ python -m venv .venv
14
+ source .venv/bin/activate
15
+
16
+ # Install in development mode
17
+ pip install -e ".[dev]"
18
+
19
+ # Run tests
20
+ pytest tests/ -v
21
+
22
+ # Run linter
23
+ ruff check src/ tests/
24
+ ```
25
+
26
+ ## Code Standards
27
+
28
+ - Python 3.10+ with type hints on all function signatures
29
+ - Docstrings on all public functions
30
+ - Use `pathlib` for file paths
31
+ - Use `rich` for terminal output
32
+ - Follow conventional commits for commit messages
33
+
34
+ ## Adding a New Connector
35
+
36
+ 1. Create a new module in `src/scherlok/connectors/`
37
+ 2. Extend `BaseConnector` from `connectors/base.py`
38
+ 3. Register the scheme in `connectors/__init__.py`
39
+ 4. Add tests in `tests/test_connector.py`
40
+
41
+ ## Adding a New Alerter
42
+
43
+ 1. Create a new module in `src/scherlok/alerter/`
44
+ 2. Follow the pattern from `alerter/slack.py` or `alerter/console.py`
45
+ 3. Add tests
46
+
47
+ ## Pull Requests
48
+
49
+ - Create a branch from `main`
50
+ - Write tests for new functionality
51
+ - Make sure `pytest` and `ruff check` pass
52
+ - Open a PR with a clear description
scherlok-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Robson Bayer Müller
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,235 @@
1
+ Metadata-Version: 2.4
2
+ Name: scherlok
3
+ Version: 0.1.0
4
+ Summary: A detective for your data. Zero-config data quality monitoring.
5
+ Project-URL: Homepage, https://github.com/rbmuller/scherlok
6
+ Project-URL: Repository, https://github.com/rbmuller/scherlok
7
+ Project-URL: Issues, https://github.com/rbmuller/scherlok/issues
8
+ Author-email: Robson Muller <robson@tbdcdata.com>
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: anomaly-detection,data-engineering,data-quality,monitoring
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Topic :: Database
17
+ Classifier: Topic :: Software Development :: Quality Assurance
18
+ Requires-Python: >=3.10
19
+ Requires-Dist: psycopg2-binary>=2.9.0
20
+ Requires-Dist: requests>=2.28.0
21
+ Requires-Dist: rich>=13.0.0
22
+ Requires-Dist: typer>=0.9.0
23
+ Provides-Extra: bigquery
24
+ Requires-Dist: google-cloud-bigquery>=3.0.0; extra == 'bigquery'
25
+ Provides-Extra: dev
26
+ Requires-Dist: pytest-cov>=4.0.0; extra == 'dev'
27
+ Requires-Dist: pytest>=7.0.0; extra == 'dev'
28
+ Requires-Dist: ruff>=0.1.0; extra == 'dev'
29
+ Description-Content-Type: text/markdown
30
+
31
+ <div align="center">
32
+
33
+ <img src="https://img.shields.io/badge/python-3.10+-blue?logo=python&logoColor=white" alt="Python 3.10+">
34
+ <img src="https://img.shields.io/pypi/v/scherlok?color=green" alt="PyPI">
35
+ <img src="https://img.shields.io/github/license/rbmuller/scherlok" alt="MIT License">
36
+ <a href="https://github.com/rbmuller/scherlok/actions/workflows/ci.yml"><img src="https://github.com/rbmuller/scherlok/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
37
+
38
+ <br><br>
39
+
40
+ <h1>Scherlok</h1>
41
+
42
+ <p><strong>Your data broke in production. Again.</strong><br>
43
+ Scherlok makes sure it doesn't happen next time.</p>
44
+
45
+ </div>
46
+
47
+ ```bash
48
+ pip install scherlok
49
+ scherlok connect postgres://localhost/mydb
50
+ scherlok investigate
51
+ scherlok watch
52
+ ```
53
+
54
+ <div align="center">
55
+
56
+ **Zero config. Zero YAML. Zero rules to write.**<br>
57
+ Scherlok learns what "normal" looks like, then tells you when something changes.
58
+
59
+ </div>
60
+
61
+ ---
62
+
63
+ ## The Problem
64
+
65
+ Every data team has the same nightmare:
66
+
67
+ > A source API silently changes from **dollars to cents**. Revenue dashboards show wrong numbers for **3 weeks** before anyone notices.
68
+ >
69
+ > A column starts returning **NULLs**. A table stops updating. Row counts drop **40% on a Tuesday**. Nobody knows until the CEO asks why the report looks weird.
70
+
71
+ Current tools (Great Expectations, Soda, dbt tests) require you to **define what "correct" looks like** before you can detect what's wrong. Hundreds of rules. Dozens of YAML files. And you still miss things — because you can't write rules for problems you haven't imagined yet.
72
+
73
+ ## The Solution
74
+
75
+ Scherlok takes the opposite approach: **learn first, then detect.**
76
+
77
+ ```bash
78
+ scherlok connect postgres://user:pass@host/db # connect once
79
+ scherlok investigate # learn your data
80
+ scherlok watch # detect anomalies
81
+ ```
82
+
83
+ Three commands. Five minutes. Done.
84
+
85
+ ## What It Catches
86
+
87
+ | Anomaly | What Happened | Severity |
88
+ |---------|---------------|----------|
89
+ | **Volume drop** | Row count dropped 40% overnight | CRITICAL |
90
+ | **Volume spike** | 3x more rows than normal | WARNING |
91
+ | **Freshness alert** | Table hasn't updated in 12h (normally every 2h) | CRITICAL |
92
+ | **Schema drift** | Column removed or type changed | CRITICAL |
93
+ | **NULL surge** | NULL rate jumped from 2% to 45% | WARNING |
94
+ | **Distribution shift** | Column mean shifted 5+ standard deviations | WARNING |
95
+ | **Cardinality explosion** | Status column went from 5 values to 500 | CRITICAL |
96
+
97
+ Every anomaly is auto-scored: **INFO**, **WARNING**, or **CRITICAL**. No thresholds to configure.
98
+
99
+ ## How It Works
100
+
101
+ ### 1. `investigate` — Learn the patterns
102
+
103
+ ```bash
104
+ $ scherlok investigate
105
+
106
+ Profiling 12 tables...
107
+ ✓ users — 45,231 rows, 8 columns
108
+ ✓ orders — 1,203,847 rows, 15 columns
109
+ ✓ products — 892 rows, 12 columns
110
+ ...
111
+ Done. Profiles saved.
112
+ ```
113
+
114
+ Scherlok profiles every table: row counts, column types, NULL rates, value distributions, freshness cadence, cardinality. Stores everything locally in SQLite.
115
+
116
+ ### 2. `watch` — Detect anomalies
117
+
118
+ ```bash
119
+ $ scherlok watch
120
+
121
+ Checking 12 tables against learned profiles...
122
+
123
+ 🔴 CRITICAL orders volume_drop Row count dropped 52% (1,203,847 → 578,412)
124
+ 🟡 WARNING users null_increase Column "email": NULL rate 2.1% → 18.7%
125
+ 🔵 INFO products distribution Column "price": mean shifted 3.2σ
126
+
127
+ 3 anomalies detected. Exit code: 1
128
+ ```
129
+
130
+ ### 3. Alert — Slack, CI/CD, or both
131
+
132
+ ```bash
133
+ # Slack alerts
134
+ scherlok watch --slack https://hooks.slack.com/services/...
135
+
136
+ # CI/CD gate (fails pipeline on CRITICAL)
137
+ scherlok watch --exit-code --fail-on critical
138
+ ```
139
+
140
+ ## CI/CD Integration
141
+
142
+ Use Scherlok as a data quality gate:
143
+
144
+ ```yaml
145
+ # GitHub Actions
146
+ - name: Data quality check
147
+ run: |
148
+ pip install scherlok
149
+ scherlok connect ${{ secrets.DATABASE_URL }}
150
+ scherlok watch --exit-code --fail-on critical
151
+ ```
152
+
153
+ If Scherlok detects a critical anomaly, the pipeline fails. Bad data never reaches production.
154
+
155
+ ## Connectors
156
+
157
+ ```bash
158
+ # PostgreSQL
159
+ scherlok connect postgres://user:pass@host:5432/db
160
+
161
+ # BigQuery
162
+ pip install scherlok[bigquery]
163
+ scherlok connect bigquery://project-id/dataset-name
164
+ ```
165
+
166
+ | Database | Status |
167
+ |----------|--------|
168
+ | PostgreSQL | Available |
169
+ | BigQuery | Available |
170
+ | Snowflake | Coming soon |
171
+ | MySQL | Coming soon |
172
+ | DuckDB | Planned |
173
+
174
+ ## Remote Storage
175
+
176
+ Share profiles across CI runs and team members:
177
+
178
+ ```bash
179
+ # AWS S3
180
+ scherlok config --store s3://my-bucket/scherlok/profiles.db
181
+
182
+ # Google Cloud Storage
183
+ scherlok config --store gs://my-bucket/scherlok/profiles.db
184
+
185
+ # Azure Blob Storage
186
+ scherlok config --store az://my-container/scherlok/profiles.db
187
+ ```
188
+
189
+ ## Why Not [Other Tool]?
190
+
191
+ | | Great Expectations | Soda | Monte Carlo | **Scherlok** |
192
+ |---|---|---|---|---|
193
+ | Setup time | Hours | 30 min | Weeks | **5 minutes** |
194
+ | Config required | Hundreds of rules | YAML checks | Dashboard setup | **None** |
195
+ | Anomaly detection | Manual thresholds | Paid feature | Yes | **Yes, free** |
196
+ | Self-hosted | Yes | Limited | No (SaaS) | **Yes** |
197
+ | CI/CD gate | Yes | Yes | No | **Yes** |
198
+ | Price | Free | Freemium | $50-200K/yr | **Free, forever** |
199
+
200
+ ## CLI Reference
201
+
202
+ ```
203
+ scherlok connect <url> Connect to a database
204
+ scherlok investigate Profile all tables (learn patterns)
205
+ scherlok watch Detect anomalies and alert
206
+ scherlok status Quick health dashboard
207
+ scherlok report Detailed profile summary
208
+ scherlok history [--days N] Timeline of past anomalies
209
+ scherlok config --store <url> Set remote storage
210
+ scherlok version Show version
211
+ ```
212
+
213
+ ## Install
214
+
215
+ ```bash
216
+ pip install scherlok
217
+
218
+ # With BigQuery support
219
+ pip install scherlok[bigquery]
220
+ ```
221
+
222
+ Requires Python 3.10+.
223
+
224
+ ## Contributing
225
+
226
+ Contributions welcome! See [CONTRIBUTING.md](CONTRIBUTING.md).
227
+
228
+ We're especially looking for:
229
+ - New database connectors (Snowflake, MySQL, DuckDB)
230
+ - Anomaly detection improvements
231
+ - Documentation and examples
232
+
233
+ ## License
234
+
235
+ [MIT](LICENSE) — Developed by [Robson Bayer Müller](https://github.com/rbmuller)
@@ -0,0 +1,205 @@
1
+ <div align="center">
2
+
3
+ <img src="https://img.shields.io/badge/python-3.10+-blue?logo=python&logoColor=white" alt="Python 3.10+">
4
+ <img src="https://img.shields.io/pypi/v/scherlok?color=green" alt="PyPI">
5
+ <img src="https://img.shields.io/github/license/rbmuller/scherlok" alt="MIT License">
6
+ <a href="https://github.com/rbmuller/scherlok/actions/workflows/ci.yml"><img src="https://github.com/rbmuller/scherlok/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
7
+
8
+ <br><br>
9
+
10
+ <h1>Scherlok</h1>
11
+
12
+ <p><strong>Your data broke in production. Again.</strong><br>
13
+ Scherlok makes sure it doesn't happen next time.</p>
14
+
15
+ </div>
16
+
17
+ ```bash
18
+ pip install scherlok
19
+ scherlok connect postgres://localhost/mydb
20
+ scherlok investigate
21
+ scherlok watch
22
+ ```
23
+
24
+ <div align="center">
25
+
26
+ **Zero config. Zero YAML. Zero rules to write.**<br>
27
+ Scherlok learns what "normal" looks like, then tells you when something changes.
28
+
29
+ </div>
30
+
31
+ ---
32
+
33
+ ## The Problem
34
+
35
+ Every data team has the same nightmare:
36
+
37
+ > A source API silently changes from **dollars to cents**. Revenue dashboards show wrong numbers for **3 weeks** before anyone notices.
38
+ >
39
+ > A column starts returning **NULLs**. A table stops updating. Row counts drop **40% on a Tuesday**. Nobody knows until the CEO asks why the report looks weird.
40
+
41
+ Current tools (Great Expectations, Soda, dbt tests) require you to **define what "correct" looks like** before you can detect what's wrong. Hundreds of rules. Dozens of YAML files. And you still miss things — because you can't write rules for problems you haven't imagined yet.
42
+
43
+ ## The Solution
44
+
45
+ Scherlok takes the opposite approach: **learn first, then detect.**
46
+
47
+ ```bash
48
+ scherlok connect postgres://user:pass@host/db # connect once
49
+ scherlok investigate # learn your data
50
+ scherlok watch # detect anomalies
51
+ ```
52
+
53
+ Three commands. Five minutes. Done.
54
+
55
+ ## What It Catches
56
+
57
+ | Anomaly | What Happened | Severity |
58
+ |---------|---------------|----------|
59
+ | **Volume drop** | Row count dropped 40% overnight | CRITICAL |
60
+ | **Volume spike** | 3x more rows than normal | WARNING |
61
+ | **Freshness alert** | Table hasn't updated in 12h (normally every 2h) | CRITICAL |
62
+ | **Schema drift** | Column removed or type changed | CRITICAL |
63
+ | **NULL surge** | NULL rate jumped from 2% to 45% | WARNING |
64
+ | **Distribution shift** | Column mean shifted 5+ standard deviations | WARNING |
65
+ | **Cardinality explosion** | Status column went from 5 values to 500 | CRITICAL |
66
+
67
+ Every anomaly is auto-scored: **INFO**, **WARNING**, or **CRITICAL**. No thresholds to configure.
68
+
69
+ ## How It Works
70
+
71
+ ### 1. `investigate` — Learn the patterns
72
+
73
+ ```bash
74
+ $ scherlok investigate
75
+
76
+ Profiling 12 tables...
77
+ ✓ users — 45,231 rows, 8 columns
78
+ ✓ orders — 1,203,847 rows, 15 columns
79
+ ✓ products — 892 rows, 12 columns
80
+ ...
81
+ Done. Profiles saved.
82
+ ```
83
+
84
+ Scherlok profiles every table: row counts, column types, NULL rates, value distributions, freshness cadence, cardinality. Stores everything locally in SQLite.
85
+
86
+ ### 2. `watch` — Detect anomalies
87
+
88
+ ```bash
89
+ $ scherlok watch
90
+
91
+ Checking 12 tables against learned profiles...
92
+
93
+ 🔴 CRITICAL orders volume_drop Row count dropped 52% (1,203,847 → 578,412)
94
+ 🟡 WARNING users null_increase Column "email": NULL rate 2.1% → 18.7%
95
+ 🔵 INFO products distribution Column "price": mean shifted 3.2σ
96
+
97
+ 3 anomalies detected. Exit code: 1
98
+ ```
99
+
100
+ ### 3. Alert — Slack, CI/CD, or both
101
+
102
+ ```bash
103
+ # Slack alerts
104
+ scherlok watch --slack https://hooks.slack.com/services/...
105
+
106
+ # CI/CD gate (fails pipeline on CRITICAL)
107
+ scherlok watch --exit-code --fail-on critical
108
+ ```
109
+
110
+ ## CI/CD Integration
111
+
112
+ Use Scherlok as a data quality gate:
113
+
114
+ ```yaml
115
+ # GitHub Actions
116
+ - name: Data quality check
117
+ run: |
118
+ pip install scherlok
119
+ scherlok connect ${{ secrets.DATABASE_URL }}
120
+ scherlok watch --exit-code --fail-on critical
121
+ ```
122
+
123
+ If Scherlok detects a critical anomaly, the pipeline fails. Bad data never reaches production.
124
+
125
+ ## Connectors
126
+
127
+ ```bash
128
+ # PostgreSQL
129
+ scherlok connect postgres://user:pass@host:5432/db
130
+
131
+ # BigQuery
132
+ pip install scherlok[bigquery]
133
+ scherlok connect bigquery://project-id/dataset-name
134
+ ```
135
+
136
+ | Database | Status |
137
+ |----------|--------|
138
+ | PostgreSQL | Available |
139
+ | BigQuery | Available |
140
+ | Snowflake | Coming soon |
141
+ | MySQL | Coming soon |
142
+ | DuckDB | Planned |
143
+
144
+ ## Remote Storage
145
+
146
+ Share profiles across CI runs and team members:
147
+
148
+ ```bash
149
+ # AWS S3
150
+ scherlok config --store s3://my-bucket/scherlok/profiles.db
151
+
152
+ # Google Cloud Storage
153
+ scherlok config --store gs://my-bucket/scherlok/profiles.db
154
+
155
+ # Azure Blob Storage
156
+ scherlok config --store az://my-container/scherlok/profiles.db
157
+ ```
158
+
159
+ ## Why Not [Other Tool]?
160
+
161
+ | | Great Expectations | Soda | Monte Carlo | **Scherlok** |
162
+ |---|---|---|---|---|
163
+ | Setup time | Hours | 30 min | Weeks | **5 minutes** |
164
+ | Config required | Hundreds of rules | YAML checks | Dashboard setup | **None** |
165
+ | Anomaly detection | Manual thresholds | Paid feature | Yes | **Yes, free** |
166
+ | Self-hosted | Yes | Limited | No (SaaS) | **Yes** |
167
+ | CI/CD gate | Yes | Yes | No | **Yes** |
168
+ | Price | Free | Freemium | $50-200K/yr | **Free, forever** |
169
+
170
+ ## CLI Reference
171
+
172
+ ```
173
+ scherlok connect <url> Connect to a database
174
+ scherlok investigate Profile all tables (learn patterns)
175
+ scherlok watch Detect anomalies and alert
176
+ scherlok status Quick health dashboard
177
+ scherlok report Detailed profile summary
178
+ scherlok history [--days N] Timeline of past anomalies
179
+ scherlok config --store <url> Set remote storage
180
+ scherlok version Show version
181
+ ```
182
+
183
+ ## Install
184
+
185
+ ```bash
186
+ pip install scherlok
187
+
188
+ # With BigQuery support
189
+ pip install scherlok[bigquery]
190
+ ```
191
+
192
+ Requires Python 3.10+.
193
+
194
+ ## Contributing
195
+
196
+ Contributions welcome! See [CONTRIBUTING.md](CONTRIBUTING.md).
197
+
198
+ We're especially looking for:
199
+ - New database connectors (Snowflake, MySQL, DuckDB)
200
+ - Anomaly detection improvements
201
+ - Documentation and examples
202
+
203
+ ## License
204
+
205
+ [MIT](LICENSE) — Developed by [Robson Bayer Müller](https://github.com/rbmuller)
@@ -0,0 +1,57 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "scherlok"
7
+ version = "0.1.0"
8
+ description = "A detective for your data. Zero-config data quality monitoring."
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ requires-python = ">=3.10"
12
+ authors = [
13
+ { name = "Robson Muller", email = "robson@tbdcdata.com" },
14
+ ]
15
+ keywords = ["data-quality", "monitoring", "anomaly-detection", "data-engineering"]
16
+ classifiers = [
17
+ "Development Status :: 3 - Alpha",
18
+ "Intended Audience :: Developers",
19
+ "License :: OSI Approved :: MIT License",
20
+ "Programming Language :: Python :: 3",
21
+ "Topic :: Database",
22
+ "Topic :: Software Development :: Quality Assurance",
23
+ ]
24
+ dependencies = [
25
+ "typer>=0.9.0",
26
+ "rich>=13.0.0",
27
+ "psycopg2-binary>=2.9.0",
28
+ "requests>=2.28.0",
29
+ ]
30
+
31
+ [project.optional-dependencies]
32
+ bigquery = [
33
+ "google-cloud-bigquery>=3.0.0",
34
+ ]
35
+ dev = [
36
+ "pytest>=7.0.0",
37
+ "pytest-cov>=4.0.0",
38
+ "ruff>=0.1.0",
39
+ ]
40
+
41
+ [project.scripts]
42
+ scherlok = "scherlok.cli:app"
43
+
44
+ [project.urls]
45
+ Homepage = "https://github.com/rbmuller/scherlok"
46
+ Repository = "https://github.com/rbmuller/scherlok"
47
+ Issues = "https://github.com/rbmuller/scherlok/issues"
48
+
49
+ [tool.ruff]
50
+ target-version = "py310"
51
+ line-length = 100
52
+
53
+ [tool.ruff.lint]
54
+ select = ["E", "F", "I", "N", "W", "UP"]
55
+
56
+ [tool.pytest.ini_options]
57
+ testpaths = ["tests"]
@@ -0,0 +1,3 @@
1
+ """Scherlok — A detective for your data. Zero-config data quality monitoring."""
2
+
3
+ __version__ = "0.1.0"
@@ -0,0 +1 @@
1
+ """Alerting modules for Scherlok."""