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.
@@ -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
@@ -0,0 +1,9 @@
1
+ __pycache__/
2
+ *.pyc
3
+ *.egg-info/
4
+ dist/
5
+ build/
6
+ .coverage
7
+ coverage.xml
8
+ .pytest_cache/
9
+ .ruff_cache/
@@ -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`