dash-dq 0.1.1__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.
- dash_dq-0.1.1/.github/workflows/ci.yml +53 -0
- dash_dq-0.1.1/.github/workflows/daily.yml +33 -0
- dash_dq-0.1.1/.github/workflows/release.yml +280 -0
- dash_dq-0.1.1/.gitignore +9 -0
- dash_dq-0.1.1/CLAUDE.md +31 -0
- dash_dq-0.1.1/PKG-INFO +351 -0
- dash_dq-0.1.1/README.md +326 -0
- dash_dq-0.1.1/dashdq/__init__.py +25 -0
- dash_dq-0.1.1/dashdq/checks.py +1200 -0
- dash_dq-0.1.1/dashdq/suite.py +176 -0
- dash_dq-0.1.1/dashdq/ui.py +565 -0
- dash_dq-0.1.1/docs/api/dashdq.html +1316 -0
- dash_dq-0.1.1/docs/api/index.html +7 -0
- dash_dq-0.1.1/docs/api/search.js +46 -0
- dash_dq-0.1.1/docs/screenshots/.gitkeep +0 -0
- dash_dq-0.1.1/docs/screenshots/README.txt +1 -0
- dash_dq-0.1.1/marketplace/listing.json +13 -0
- dash_dq-0.1.1/marketplace/quickstart_notebook.py +29 -0
- dash_dq-0.1.1/pyproject.toml +36 -0
- dash_dq-0.1.1/tests/test_suite.py +103 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
lint:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v4
|
|
14
|
+
- uses: actions/setup-python@v5
|
|
15
|
+
with:
|
|
16
|
+
python-version: "3.11"
|
|
17
|
+
- run: pip install ruff
|
|
18
|
+
- run: ruff check dashdq/
|
|
19
|
+
|
|
20
|
+
test:
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
needs: lint
|
|
23
|
+
strategy:
|
|
24
|
+
matrix:
|
|
25
|
+
python-version: ["3.9", "3.10", "3.11", "3.12"]
|
|
26
|
+
steps:
|
|
27
|
+
- uses: actions/checkout@v4
|
|
28
|
+
- uses: actions/setup-python@v5
|
|
29
|
+
with:
|
|
30
|
+
python-version: ${{ matrix.python-version }}
|
|
31
|
+
- name: Install
|
|
32
|
+
run: pip install -e ".[dev]" pytest pytest-cov
|
|
33
|
+
- name: Test
|
|
34
|
+
run: pytest tests/ -v --cov=dashdq --cov-report=xml
|
|
35
|
+
- name: Upload coverage
|
|
36
|
+
uses: codecov/codecov-action@v4
|
|
37
|
+
with:
|
|
38
|
+
files: coverage.xml
|
|
39
|
+
|
|
40
|
+
build:
|
|
41
|
+
runs-on: ubuntu-latest
|
|
42
|
+
needs: test
|
|
43
|
+
steps:
|
|
44
|
+
- uses: actions/checkout@v4
|
|
45
|
+
- uses: actions/setup-python@v5
|
|
46
|
+
with:
|
|
47
|
+
python-version: "3.11"
|
|
48
|
+
- run: pip install hatch
|
|
49
|
+
- run: hatch build
|
|
50
|
+
- uses: actions/upload-artifact@v4
|
|
51
|
+
with:
|
|
52
|
+
name: dist
|
|
53
|
+
path: dist/
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
name: Daily Tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
schedule:
|
|
5
|
+
- cron: "0 6 * * *" # Every day 06:00 UTC — tests only, no commit
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
test:
|
|
10
|
+
name: Test (Python ${{ matrix.python-version }})
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
strategy:
|
|
13
|
+
fail-fast: false
|
|
14
|
+
matrix:
|
|
15
|
+
python-version: ["3.9", "3.10", "3.11", "3.12"]
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- uses: actions/setup-python@v5
|
|
20
|
+
with:
|
|
21
|
+
python-version: ${{ matrix.python-version }}
|
|
22
|
+
|
|
23
|
+
- name: Install
|
|
24
|
+
run: pip install -e ".[dev]" pytest pytest-cov
|
|
25
|
+
|
|
26
|
+
- name: Run tests
|
|
27
|
+
run: pytest tests/ -v --cov=dashdq --cov-report=xml --cov-report=term-missing
|
|
28
|
+
|
|
29
|
+
- name: Upload coverage
|
|
30
|
+
uses: codecov/codecov-action@v4
|
|
31
|
+
with:
|
|
32
|
+
files: coverage.xml
|
|
33
|
+
fail_ci_if_error: false
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
name: Weekly Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
schedule:
|
|
5
|
+
- cron: "0 9 * * 1" # Every Monday 09:00 UTC
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
inputs:
|
|
8
|
+
release_note:
|
|
9
|
+
description: "Optional release note (shown in GitHub release body)"
|
|
10
|
+
required: false
|
|
11
|
+
default: ""
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
# ── Gate: tests must pass ────────────────────────────────────────────────
|
|
15
|
+
test:
|
|
16
|
+
name: Test (Python ${{ matrix.python-version }})
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
strategy:
|
|
19
|
+
fail-fast: true
|
|
20
|
+
matrix:
|
|
21
|
+
python-version: ["3.9", "3.10", "3.11", "3.12"]
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@v4
|
|
24
|
+
|
|
25
|
+
- uses: actions/setup-python@v5
|
|
26
|
+
with:
|
|
27
|
+
python-version: ${{ matrix.python-version }}
|
|
28
|
+
|
|
29
|
+
- name: Install
|
|
30
|
+
run: pip install -e ".[dev]" pytest pytest-cov
|
|
31
|
+
|
|
32
|
+
- name: Run tests
|
|
33
|
+
run: pytest tests/ -v --cov=dashdq --cov-report=xml --cov-report=term-missing
|
|
34
|
+
|
|
35
|
+
- name: Upload coverage
|
|
36
|
+
uses: codecov/codecov-action@v4
|
|
37
|
+
with:
|
|
38
|
+
files: coverage.xml
|
|
39
|
+
fail_ci_if_error: false
|
|
40
|
+
|
|
41
|
+
# ── Generate docs ────────────────────────────────────────────────────────
|
|
42
|
+
docs:
|
|
43
|
+
name: Generate API docs
|
|
44
|
+
runs-on: ubuntu-latest
|
|
45
|
+
needs: test
|
|
46
|
+
steps:
|
|
47
|
+
- uses: actions/checkout@v4
|
|
48
|
+
|
|
49
|
+
- uses: actions/setup-python@v5
|
|
50
|
+
with:
|
|
51
|
+
python-version: "3.11"
|
|
52
|
+
|
|
53
|
+
- name: Install
|
|
54
|
+
run: pip install -e ".[dev]" pdoc
|
|
55
|
+
|
|
56
|
+
- name: Generate docs
|
|
57
|
+
run: |
|
|
58
|
+
pdoc dashdq --output-dir docs/api --docformat google
|
|
59
|
+
echo "Docs generated at $(date -u)" > docs/api/.generated
|
|
60
|
+
|
|
61
|
+
- name: Upload docs artifact
|
|
62
|
+
uses: actions/upload-artifact@v4
|
|
63
|
+
with:
|
|
64
|
+
name: api-docs
|
|
65
|
+
path: docs/api/
|
|
66
|
+
|
|
67
|
+
# ── Release: tag, GitHub release, commit docs ────────────────────────────
|
|
68
|
+
release:
|
|
69
|
+
name: Bump version & release
|
|
70
|
+
runs-on: ubuntu-latest
|
|
71
|
+
needs: [test, docs]
|
|
72
|
+
permissions:
|
|
73
|
+
contents: write
|
|
74
|
+
outputs:
|
|
75
|
+
version: ${{ steps.bump.outputs.version }}
|
|
76
|
+
steps:
|
|
77
|
+
- uses: actions/checkout@v4
|
|
78
|
+
with:
|
|
79
|
+
fetch-depth: 0
|
|
80
|
+
token: ${{ secrets.RELEASE_TOKEN }}
|
|
81
|
+
|
|
82
|
+
- uses: actions/setup-python@v5
|
|
83
|
+
with:
|
|
84
|
+
python-version: "3.11"
|
|
85
|
+
|
|
86
|
+
- name: Install build tools
|
|
87
|
+
run: pip install hatch pdoc
|
|
88
|
+
|
|
89
|
+
- name: Bump patch version
|
|
90
|
+
id: bump
|
|
91
|
+
run: |
|
|
92
|
+
python3 - << 'PYEOF'
|
|
93
|
+
import re, os
|
|
94
|
+
|
|
95
|
+
# Read current version from pyproject.toml
|
|
96
|
+
with open("pyproject.toml") as f:
|
|
97
|
+
content = f.read()
|
|
98
|
+
m = re.search(r'^version\s*=\s*"([^"]+)"', content, re.MULTILINE)
|
|
99
|
+
current = m.group(1)
|
|
100
|
+
major, minor, patch = current.split(".")
|
|
101
|
+
new = f"{major}.{minor}.{int(patch)+1}"
|
|
102
|
+
|
|
103
|
+
# Update pyproject.toml
|
|
104
|
+
new_content = re.sub(
|
|
105
|
+
r'^(version\s*=\s*")[^"]+(")',
|
|
106
|
+
rf'\g<1>{new}\g<2>',
|
|
107
|
+
content, flags=re.MULTILINE
|
|
108
|
+
)
|
|
109
|
+
with open("pyproject.toml", "w") as f:
|
|
110
|
+
f.write(new_content)
|
|
111
|
+
|
|
112
|
+
# Update __init__.py
|
|
113
|
+
with open("dashdq/__init__.py") as f:
|
|
114
|
+
init = f.read()
|
|
115
|
+
init = re.sub(r'__version__\s*=\s*"[^"]+"', f'__version__ = "{new}"', init)
|
|
116
|
+
with open("dashdq/__init__.py", "w") as f:
|
|
117
|
+
f.write(init)
|
|
118
|
+
|
|
119
|
+
# Write outputs
|
|
120
|
+
with open(os.environ["GITHUB_OUTPUT"], "a") as f:
|
|
121
|
+
f.write(f"version={new}\n")
|
|
122
|
+
f.write(f"prev_version={current}\n")
|
|
123
|
+
print(f"Bumped {current} → {new}")
|
|
124
|
+
PYEOF
|
|
125
|
+
|
|
126
|
+
- name: Regenerate docs into repo
|
|
127
|
+
run: |
|
|
128
|
+
pip install -e ".[dev]"
|
|
129
|
+
pdoc dashdq --output-dir docs/api --docformat google
|
|
130
|
+
|
|
131
|
+
- name: Build wheel + sdist
|
|
132
|
+
run: hatch build
|
|
133
|
+
|
|
134
|
+
- name: Write release notes
|
|
135
|
+
env:
|
|
136
|
+
VERSION: ${{ steps.bump.outputs.version }}
|
|
137
|
+
PREV_VERSION: ${{ steps.bump.outputs.prev_version }}
|
|
138
|
+
RELEASE_NOTE: ${{ github.event.inputs.release_note }}
|
|
139
|
+
run: |
|
|
140
|
+
cat > RELEASE_NOTES.md << EOF
|
|
141
|
+
## DashDQ v${VERSION}
|
|
142
|
+
|
|
143
|
+
**Released:** $(date -u '+%Y-%m-%d')
|
|
144
|
+
**Previous:** v${PREV_VERSION}
|
|
145
|
+
|
|
146
|
+
$( [ -n "${RELEASE_NOTE}" ] && echo "### Notes" && echo "${RELEASE_NOTE}" || true )
|
|
147
|
+
|
|
148
|
+
### What's included
|
|
149
|
+
- All tests passing across Python 3.9, 3.10, 3.11, 3.12
|
|
150
|
+
- API documentation regenerated (see \`docs/api/\`)
|
|
151
|
+
- Published to PyPI and Databricks Marketplace
|
|
152
|
+
|
|
153
|
+
### Install
|
|
154
|
+
\`\`\`bash
|
|
155
|
+
pip install dash-dq==${VERSION}
|
|
156
|
+
\`\`\`
|
|
157
|
+
|
|
158
|
+
### Quick Start (Databricks notebook)
|
|
159
|
+
\`\`\`python
|
|
160
|
+
%pip install dash-dq==${VERSION}
|
|
161
|
+
import dashdq
|
|
162
|
+
dashdq.launch()
|
|
163
|
+
\`\`\`
|
|
164
|
+
EOF
|
|
165
|
+
|
|
166
|
+
- name: Commit version bump + docs
|
|
167
|
+
env:
|
|
168
|
+
VERSION: ${{ steps.bump.outputs.version }}
|
|
169
|
+
RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
|
170
|
+
run: |
|
|
171
|
+
git config user.name "Darshan Shah"
|
|
172
|
+
git config user.email "darshan.innovation@gmail.com"
|
|
173
|
+
git remote set-url origin "https://${RELEASE_TOKEN}@github.com/dash-libs/dash-dq.git"
|
|
174
|
+
git add .
|
|
175
|
+
git commit -m "release: v${VERSION} — tests passed, docs updated"
|
|
176
|
+
git tag "v${VERSION}"
|
|
177
|
+
git push origin HEAD:main --tags
|
|
178
|
+
|
|
179
|
+
- name: Create GitHub Release
|
|
180
|
+
uses: softprops/action-gh-release@v2
|
|
181
|
+
with:
|
|
182
|
+
tag_name: "v${{ steps.bump.outputs.version }}"
|
|
183
|
+
body_path: RELEASE_NOTES.md
|
|
184
|
+
files: dist/*
|
|
185
|
+
|
|
186
|
+
- name: Upload dist artifact for PyPI job
|
|
187
|
+
uses: actions/upload-artifact@v4
|
|
188
|
+
with:
|
|
189
|
+
name: dist
|
|
190
|
+
path: dist/
|
|
191
|
+
|
|
192
|
+
# ── Publish to PyPI (Trusted Publisher / OIDC — no token needed) ─────────
|
|
193
|
+
publish-pypi:
|
|
194
|
+
name: Publish to PyPI
|
|
195
|
+
runs-on: ubuntu-latest
|
|
196
|
+
needs: release
|
|
197
|
+
permissions:
|
|
198
|
+
id-token: write # required for OIDC trusted publisher
|
|
199
|
+
environment:
|
|
200
|
+
name: pypi
|
|
201
|
+
url: https://pypi.org/project/dash-dq
|
|
202
|
+
steps:
|
|
203
|
+
- name: Download dist
|
|
204
|
+
uses: actions/download-artifact@v4
|
|
205
|
+
with:
|
|
206
|
+
name: dist
|
|
207
|
+
path: dist/
|
|
208
|
+
|
|
209
|
+
- name: Publish to PyPI
|
|
210
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
211
|
+
|
|
212
|
+
# ── Package for Databricks Marketplace ───────────────────────────────────
|
|
213
|
+
publish-databricks:
|
|
214
|
+
name: Package for Databricks Marketplace
|
|
215
|
+
runs-on: ubuntu-latest
|
|
216
|
+
needs: release
|
|
217
|
+
steps:
|
|
218
|
+
- uses: actions/checkout@v4
|
|
219
|
+
with:
|
|
220
|
+
ref: "v${{ needs.release.outputs.version }}"
|
|
221
|
+
|
|
222
|
+
- name: Download dist
|
|
223
|
+
uses: actions/download-artifact@v4
|
|
224
|
+
with:
|
|
225
|
+
name: dist
|
|
226
|
+
path: dist/
|
|
227
|
+
|
|
228
|
+
- name: Build Marketplace bundle
|
|
229
|
+
env:
|
|
230
|
+
VERSION: ${{ needs.release.outputs.version }}
|
|
231
|
+
run: |
|
|
232
|
+
mkdir -p marketplace-bundle/files
|
|
233
|
+
|
|
234
|
+
# Copy wheel
|
|
235
|
+
cp dist/*.whl marketplace-bundle/files/
|
|
236
|
+
|
|
237
|
+
# Generate companion notebook
|
|
238
|
+
cat > marketplace-bundle/files/DashDQ_Quickstart.py << NBEOF
|
|
239
|
+
# Databricks notebook source
|
|
240
|
+
# MAGIC %md
|
|
241
|
+
# MAGIC # DashDQ v${VERSION} — Data Quality for Databricks
|
|
242
|
+
# MAGIC Install and launch the interactive UI.
|
|
243
|
+
|
|
244
|
+
# COMMAND ----------
|
|
245
|
+
# MAGIC %pip install dash-dq==${VERSION}
|
|
246
|
+
|
|
247
|
+
# COMMAND ----------
|
|
248
|
+
dbutils.library.restartPython()
|
|
249
|
+
|
|
250
|
+
# COMMAND ----------
|
|
251
|
+
import dashdq
|
|
252
|
+
dashdq.launch()
|
|
253
|
+
NBEOF
|
|
254
|
+
|
|
255
|
+
# Generate listing metadata
|
|
256
|
+
cat > marketplace-bundle/listing.json << LEOF
|
|
257
|
+
{
|
|
258
|
+
"listing_name": "DashDQ — Data Quality",
|
|
259
|
+
"version": "${VERSION}",
|
|
260
|
+
"short_description": "Interactive data quality checks for business users on Databricks",
|
|
261
|
+
"long_description": "DashDQ provides an ipywidgets UI inside Databricks notebooks to run data quality checks on DataFrames, Unity Catalog tables, and SQL queries. No coding required for business users.",
|
|
262
|
+
"categories": ["Data Quality", "Data Engineering"],
|
|
263
|
+
"tags": ["data-quality", "databricks", "unity-catalog", "pyspark"],
|
|
264
|
+
"provider": "dash-libs",
|
|
265
|
+
"documentation_url": "https://github.com/dash-libs/dash-dq",
|
|
266
|
+
"source_url": "https://github.com/dash-libs/dash-dq",
|
|
267
|
+
"pypi_package": "dash-dq==${VERSION}"
|
|
268
|
+
}
|
|
269
|
+
LEOF
|
|
270
|
+
|
|
271
|
+
# Zip the bundle
|
|
272
|
+
cd marketplace-bundle && zip -r ../dashdq-marketplace-${VERSION}.zip .
|
|
273
|
+
echo "Bundle created: dashdq-marketplace-${VERSION}.zip"
|
|
274
|
+
|
|
275
|
+
- name: Upload Marketplace bundle artifact
|
|
276
|
+
uses: actions/upload-artifact@v4
|
|
277
|
+
with:
|
|
278
|
+
name: marketplace-bundle
|
|
279
|
+
path: dashdq-marketplace-*.zip
|
|
280
|
+
retention-days: 90
|
dash_dq-0.1.1/.gitignore
ADDED
dash_dq-0.1.1/CLAUDE.md
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# CLAUDE.md — dash-dq
|
|
2
|
+
|
|
3
|
+
Part of the **Dashlibs** suite. See ~/dashlibs for the full context.
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
Data quality checks on Databricks — DataFrames, UC tables, SQL queries.
|
|
7
|
+
Business users use `dashdq.launch()` for a widget UI. Engineers use `DQSuite` directly.
|
|
8
|
+
|
|
9
|
+
## Structure
|
|
10
|
+
- `dashdq/ui.py` — ipywidgets UI, `launch()` entrypoint
|
|
11
|
+
- `dashdq/checks.py` — individual check functions, each returns `CheckResult`
|
|
12
|
+
- `dashdq/suite.py` — `DQSuite` (fluent API) and `DQReport`
|
|
13
|
+
- `tests/` — pytest, no Spark dependency for unit tests
|
|
14
|
+
|
|
15
|
+
## Key Design Rules
|
|
16
|
+
- New checks go in `checks.py` as standalone functions returning `CheckResult`
|
|
17
|
+
- `DQSuite` maps rule dicts → check functions; the UI builds those dicts
|
|
18
|
+
- `DQReport.save()` appends to a Delta table — always use `mode("append")`
|
|
19
|
+
- Never import Spark at module level — always inside functions
|
|
20
|
+
|
|
21
|
+
## CI
|
|
22
|
+
- `ci.yml` — runs on every PR: lint (ruff) → test (py3.9–3.12) → build
|
|
23
|
+
- `daily.yml` — runs at 06:00 UTC daily: tests + appends to `.health/log.txt`
|
|
24
|
+
- `release.yml` — runs Monday 09:00 UTC: bumps patch version, tags, releases
|
|
25
|
+
|
|
26
|
+
## Adding a New Check
|
|
27
|
+
1. Add function to `checks.py` returning `CheckResult`
|
|
28
|
+
2. Add `expect_<name>` method to `DQSuite`
|
|
29
|
+
3. Add rule type handling in `DQSuite.run()`
|
|
30
|
+
4. Add dropdown option to `ui.py` and `_build_rule()`
|
|
31
|
+
5. Add test in `tests/test_suite.py`
|