duckpad 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 (107) hide show
  1. duckpad-0.1.0/.agents/skills/repository-conventions/SKILL.md +54 -0
  2. duckpad-0.1.0/.dockerignore +20 -0
  3. duckpad-0.1.0/.github/workflows/ci.yml +37 -0
  4. duckpad-0.1.0/.github/workflows/release.yml +119 -0
  5. duckpad-0.1.0/.gitignore +19 -0
  6. duckpad-0.1.0/AGENTS.md +24 -0
  7. duckpad-0.1.0/Dockerfile +33 -0
  8. duckpad-0.1.0/Dockerfile.duckdb +13 -0
  9. duckpad-0.1.0/LICENSE +21 -0
  10. duckpad-0.1.0/PKG-INFO +123 -0
  11. duckpad-0.1.0/README.md +93 -0
  12. duckpad-0.1.0/SPEC.md +308 -0
  13. duckpad-0.1.0/cliff.toml +60 -0
  14. duckpad-0.1.0/docs/ARCHITECTURE.md +53 -0
  15. duckpad-0.1.0/docs/AUTHORING.md +62 -0
  16. duckpad-0.1.0/docs/CONNECTORS.md +69 -0
  17. duckpad-0.1.0/docs/EXAMPLE.md +33 -0
  18. duckpad-0.1.0/docs/EXECUTION_SERVICE.md +27 -0
  19. duckpad-0.1.0/docs/IMPLEMENTATION.md +23 -0
  20. duckpad-0.1.0/docs/LINEAGE.md +49 -0
  21. duckpad-0.1.0/docs/MULTICA.md +95 -0
  22. duckpad-0.1.0/docs/RELEASING.md +107 -0
  23. duckpad-0.1.0/docs/VALIDATION.md +46 -0
  24. duckpad-0.1.0/docs/images/lineage.png +0 -0
  25. duckpad-0.1.0/docs/images/workspace.png +0 -0
  26. duckpad-0.1.0/docs/validation/benchmark.json +233 -0
  27. duckpad-0.1.0/docs/validation/checks.json +22 -0
  28. duckpad-0.1.0/docs/validation/jobs.json +31 -0
  29. duckpad-0.1.0/docs/validation/oracle.json +42 -0
  30. duckpad-0.1.0/docs/validation/s3.json +19 -0
  31. duckpad-0.1.0/docs/validation/wheel.json +12 -0
  32. duckpad-0.1.0/frontend/e2e/dashboard.spec.ts +206 -0
  33. duckpad-0.1.0/frontend/e2e/preferences.spec.ts +132 -0
  34. duckpad-0.1.0/frontend/e2e/resources.spec.ts +211 -0
  35. duckpad-0.1.0/frontend/e2e/workspace.spec.ts +1004 -0
  36. duckpad-0.1.0/frontend/index.html +1 -0
  37. duckpad-0.1.0/frontend/package-lock.json +2233 -0
  38. duckpad-0.1.0/frontend/package.json +29 -0
  39. duckpad-0.1.0/frontend/playwright.config.ts +41 -0
  40. duckpad-0.1.0/frontend/src/AccountMenu.tsx +160 -0
  41. duckpad-0.1.0/frontend/src/App.tsx +1642 -0
  42. duckpad-0.1.0/frontend/src/Canvas.tsx +467 -0
  43. duckpad-0.1.0/frontend/src/Editor.tsx +48 -0
  44. duckpad-0.1.0/frontend/src/Inspector.tsx +579 -0
  45. duckpad-0.1.0/frontend/src/LineagePanel.tsx +297 -0
  46. duckpad-0.1.0/frontend/src/Panels.tsx +785 -0
  47. duckpad-0.1.0/frontend/src/Preview.tsx +317 -0
  48. duckpad-0.1.0/frontend/src/ProjectDashboard.tsx +91 -0
  49. duckpad-0.1.0/frontend/src/QueryBuilder.tsx +235 -0
  50. duckpad-0.1.0/frontend/src/ResourceMonitor.tsx +225 -0
  51. duckpad-0.1.0/frontend/src/WorkspacePanels.tsx +204 -0
  52. duckpad-0.1.0/frontend/src/i18n.tsx +35 -0
  53. duckpad-0.1.0/frontend/src/locales/en.json +279 -0
  54. duckpad-0.1.0/frontend/src/locales/fr.json +279 -0
  55. duckpad-0.1.0/frontend/src/main.tsx +9 -0
  56. duckpad-0.1.0/frontend/src/styles.css +2890 -0
  57. duckpad-0.1.0/frontend/src/types.ts +89 -0
  58. duckpad-0.1.0/frontend/src/vite-env.d.ts +1 -0
  59. duckpad-0.1.0/frontend/tsconfig.json +16 -0
  60. duckpad-0.1.0/frontend/vite.config.ts +7 -0
  61. duckpad-0.1.0/pyproject.toml +45 -0
  62. duckpad-0.1.0/scripts/benchmark.py +195 -0
  63. duckpad-0.1.0/scripts/build_hook.py +19 -0
  64. duckpad-0.1.0/scripts/e2e_server.py +17 -0
  65. duckpad-0.1.0/scripts/integration.py +297 -0
  66. duckpad-0.1.0/scripts/preview.sh +53 -0
  67. duckpad-0.1.0/scripts/prototype_jobs.py +159 -0
  68. duckpad-0.1.0/scripts/provision-runtime.sh +41 -0
  69. duckpad-0.1.0/scripts/release.py +79 -0
  70. duckpad-0.1.0/scripts/setup.sh +26 -0
  71. duckpad-0.1.0/scripts/smoke_wheel.py +108 -0
  72. duckpad-0.1.0/scripts/verify_preview.py +76 -0
  73. duckpad-0.1.0/src/duckpad/__init__.py +3 -0
  74. duckpad-0.1.0/src/duckpad/app.py +353 -0
  75. duckpad-0.1.0/src/duckpad/auth.py +47 -0
  76. duckpad-0.1.0/src/duckpad/catalog.py +278 -0
  77. duckpad-0.1.0/src/duckpad/cli.py +57 -0
  78. duckpad-0.1.0/src/duckpad/components.py +308 -0
  79. duckpad-0.1.0/src/duckpad/engine.py +663 -0
  80. duckpad-0.1.0/src/duckpad/example.py +282 -0
  81. duckpad-0.1.0/src/duckpad/lineage.py +761 -0
  82. duckpad-0.1.0/src/duckpad/materialize.py +126 -0
  83. duckpad-0.1.0/src/duckpad/projects.py +522 -0
  84. duckpad-0.1.0/src/duckpad/resources.py +103 -0
  85. duckpad-0.1.0/src/duckpad/static/assets/Editor-DyX1CsEw.css +1 -0
  86. duckpad-0.1.0/src/duckpad/static/assets/Editor-t9xBSzyU.js +679 -0
  87. duckpad-0.1.0/src/duckpad/static/assets/editor.worker-BCzxt1at.js +12 -0
  88. duckpad-0.1.0/src/duckpad/static/assets/index-CHSQY8z7.css +1 -0
  89. duckpad-0.1.0/src/duckpad/static/assets/index-GIKY3NsH.js +325 -0
  90. duckpad-0.1.0/src/duckpad/static/assets/json.worker-B7c_PmGb.js +49 -0
  91. duckpad-0.1.0/src/duckpad/static/assets/jsonMode-BbQxTeWp.js +15 -0
  92. duckpad-0.1.0/src/duckpad/static/assets/sql-CCSDG5nI.js +6 -0
  93. duckpad-0.1.0/src/duckpad/static/index.html +3 -0
  94. duckpad-0.1.0/src/duckpad/store.py +48 -0
  95. duckpad-0.1.0/src/duckpad/templates.py +375 -0
  96. duckpad-0.1.0/src/duckpad/util.py +82 -0
  97. duckpad-0.1.0/tests/conftest.py +69 -0
  98. duckpad-0.1.0/tests/test_cancellation.py +166 -0
  99. duckpad-0.1.0/tests/test_catalog.py +104 -0
  100. duckpad-0.1.0/tests/test_execution.py +121 -0
  101. duckpad-0.1.0/tests/test_lineage.py +218 -0
  102. duckpad-0.1.0/tests/test_native_semantics.py +36 -0
  103. duckpad-0.1.0/tests/test_preview_auth.py +18 -0
  104. duckpad-0.1.0/tests/test_projects.py +226 -0
  105. duckpad-0.1.0/tests/test_release.py +126 -0
  106. duckpad-0.1.0/tests/test_resources.py +159 -0
  107. duckpad-0.1.0/uv.lock +2240 -0
@@ -0,0 +1,54 @@
1
+ ---
2
+ name: repository-conventions
3
+ description: Apply this repository's English writing rules, UI translation exception, and Conventional Commits rules whenever creating or editing files, reviewing changes, or preparing commit messages.
4
+ ---
5
+
6
+ # Repository Conventions
7
+
8
+ ## Write repository content in English
9
+
10
+ - Write all new or modified repository content in English, even when the user
11
+ gives instructions in French, except for the UI translation resources below.
12
+ - Use English for documentation, comments, identifiers, file names, test names,
13
+ example text, default user-facing strings, log messages, and error messages.
14
+ - Allow French only in localized UI values stored in dedicated translation
15
+ resource files, including translations of user-facing error messages. Keep
16
+ translation keys, file names, and comments in English. Use translation keys
17
+ from application code instead of embedding French strings there.
18
+ - Translate French wording into English before adding it elsewhere in the
19
+ repository.
20
+ - Keep conversational replies in the user's preferred language.
21
+
22
+ ## Use Conventional Commits
23
+
24
+ Every commit message must follow this structure:
25
+
26
+ ```text
27
+ <type>[optional scope][optional !]: <English summary>
28
+
29
+ [optional English body]
30
+
31
+ [optional footers]
32
+ ```
33
+
34
+ - Use a lowercase type that describes the change: `feat`, `fix`, `docs`, `style`,
35
+ `refactor`, `perf`, `test`, `build`, `ci`, `chore`, or `revert`.
36
+ - Add a short English scope when it helps identify the affected component.
37
+ - Write a concise English summary in the imperative, such as `add`, `fix`, or
38
+ `update`. Keep body text and footer descriptions in English as well.
39
+ - Mark breaking changes with `!` before the colon or a
40
+ `BREAKING CHANGE: <English explanation>` footer.
41
+ - Apply the same format to merge, squash, revert, and amended commit messages;
42
+ replace generated messages when necessary.
43
+
44
+ Examples:
45
+
46
+ ```text
47
+ docs(agents): add repository conventions
48
+ fix(editor): preserve selection when saving
49
+ feat(api)!: require authentication for note updates
50
+ ```
51
+
52
+ Before finishing a change, verify that any French text is limited to localized
53
+ UI values in dedicated translation resources, and check any proposed commit
54
+ message against the format above.
@@ -0,0 +1,20 @@
1
+ .git
2
+ .agents
3
+ .multica
4
+ .venv
5
+ .duckpad-dev
6
+ .env
7
+ .env.*
8
+ **/__pycache__
9
+ **/node_modules
10
+ **/*.tsbuildinfo
11
+ .pytest_cache
12
+ .ruff_cache
13
+ dist
14
+ src/duckpad/static
15
+ test-results
16
+ playwright-report
17
+ frontend/test-results
18
+ frontend/playwright-report
19
+ docs
20
+ tests
@@ -0,0 +1,37 @@
1
+ name: Validate Duckpad
2
+ on:
3
+ push:
4
+ pull_request:
5
+ permissions:
6
+ contents: read
7
+ jobs:
8
+ acceptance:
9
+ runs-on: ubuntu-latest
10
+ strategy:
11
+ matrix:
12
+ python: ['3.11', '3.13']
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+ - uses: actions/setup-python@v5
16
+ with:
17
+ python-version: ${{ matrix.python }}
18
+ - uses: actions/setup-node@v4
19
+ with:
20
+ node-version: '22'
21
+ cache: npm
22
+ cache-dependency-path: frontend/package-lock.json
23
+ - uses: astral-sh/setup-uv@v6
24
+ - run: uv sync --extra dev --locked
25
+ - run: uv run ruff check src tests scripts
26
+ - run: uv run ruff format --check src tests scripts
27
+ - run: uv run pytest -q
28
+ - run: npm ci --prefix frontend
29
+ - run: npm run build --prefix frontend
30
+ - run: npm exec --prefix frontend -- playwright install --with-deps chromium
31
+ - run: npm run test:e2e --prefix frontend
32
+ - run: uv build
33
+ - uses: actions/upload-artifact@v4
34
+ if: failure()
35
+ with:
36
+ name: browser-diagnostics-${{ matrix.python }}
37
+ path: frontend/test-results/
@@ -0,0 +1,119 @@
1
+ name: Release Duckpad
2
+
3
+ on:
4
+ push:
5
+ tags: ['v*']
6
+
7
+ permissions:
8
+ contents: read
9
+
10
+ concurrency:
11
+ group: release-${{ github.ref }}
12
+ cancel-in-progress: false
13
+
14
+ jobs:
15
+ build:
16
+ name: Validate and build release
17
+ runs-on: ubuntu-latest
18
+ outputs:
19
+ version: ${{ steps.release.outputs.version }}
20
+ prerelease: ${{ steps.release.outputs.prerelease }}
21
+ steps:
22
+ - uses: actions/checkout@v4
23
+ with:
24
+ fetch-depth: 0
25
+ persist-credentials: false
26
+ - uses: actions/setup-python@v5
27
+ with:
28
+ python-version: '3.12'
29
+ - uses: actions/setup-node@v4
30
+ with:
31
+ node-version: '22'
32
+ cache: npm
33
+ cache-dependency-path: frontend/package-lock.json
34
+ - uses: astral-sh/setup-uv@v6
35
+ - run: uv sync --extra dev --locked
36
+ - name: Validate tag and generate release notes
37
+ id: release
38
+ env:
39
+ RELEASE_TAG: ${{ github.ref_name }}
40
+ RELEASE_REPOSITORY: ${{ github.repository }}
41
+ run: uv run python scripts/release.py "$RELEASE_TAG" --repository "$RELEASE_REPOSITORY" --output release-notes.md
42
+ - run: uv run ruff check src tests scripts
43
+ - run: uv run ruff format --check src tests scripts
44
+ - run: uv run pytest -q
45
+ - run: npm ci --prefix frontend
46
+ - run: npm run build --prefix frontend
47
+ - run: npm exec --prefix frontend -- playwright install --with-deps chromium
48
+ - run: npm run test:e2e --prefix frontend
49
+ # uv builds the wheel from the sdist, checking that the source archive is complete.
50
+ - run: uv build
51
+ - run: uv tool run --from twine==7.0.0 twine check --strict dist/*
52
+ - name: Smoke test the installed wheel outside the checkout
53
+ run: |
54
+ uv venv /tmp/duckpad-release-smoke
55
+ uv pip install --python /tmp/duckpad-release-smoke/bin/python dist/*.whl
56
+ uv run python scripts/smoke_wheel.py --python /tmp/duckpad-release-smoke/bin/python
57
+ - name: Calculate distribution checksums
58
+ working-directory: dist
59
+ run: sha256sum *.whl *.tar.gz > SHA256SUMS
60
+ - uses: actions/upload-artifact@v4
61
+ with:
62
+ name: release-bundle
63
+ path: |
64
+ dist/
65
+ release-notes.md
66
+ if-no-files-found: error
67
+ - uses: actions/upload-artifact@v4
68
+ if: failure()
69
+ with:
70
+ name: release-browser-diagnostics
71
+ path: frontend/test-results/
72
+
73
+ publish-pypi:
74
+ name: Publish to PyPI
75
+ needs: build
76
+ runs-on: ubuntu-latest
77
+ environment:
78
+ name: pypi
79
+ url: https://pypi.org/project/duckpad/${{ needs.build.outputs.version }}/
80
+ permissions:
81
+ id-token: write
82
+ steps:
83
+ - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
84
+ with:
85
+ name: release-bundle
86
+ - name: Verify and stage distributions
87
+ run: |
88
+ (cd dist && sha256sum --check SHA256SUMS)
89
+ mkdir packages
90
+ cp dist/*.whl dist/*.tar.gz packages/
91
+ - name: Publish with Trusted Publishing
92
+ uses: pypa/gh-action-pypi-publish@7245906fb61fa33a13554f9d5fb856fe61758086 # release/v1
93
+ with:
94
+ packages-dir: packages/
95
+
96
+ publish-github:
97
+ name: Publish GitHub release
98
+ needs: [build, publish-pypi]
99
+ runs-on: ubuntu-latest
100
+ permissions:
101
+ contents: write
102
+ steps:
103
+ - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
104
+ with:
105
+ name: release-bundle
106
+ - name: Publish notes and the exact PyPI artifacts
107
+ env:
108
+ GH_TOKEN: ${{ github.token }}
109
+ GH_REPO: ${{ github.repository }}
110
+ RELEASE_TAG: ${{ github.ref_name }}
111
+ PRERELEASE: ${{ needs.build.outputs.prerelease }}
112
+ run: |
113
+ (cd dist && sha256sum --check SHA256SUMS)
114
+ flags=()
115
+ if [[ "$PRERELEASE" == true ]]; then
116
+ flags+=(--prerelease --latest=false)
117
+ fi
118
+ gh release create "$RELEASE_TAG" dist/*.whl dist/*.tar.gz dist/SHA256SUMS \
119
+ --verify-tag --title "Duckpad $RELEASE_TAG" --notes-file release-notes.md "${flags[@]}"
@@ -0,0 +1,19 @@
1
+ .venv/
2
+ __pycache__/
3
+ *.pyc
4
+ .pytest_cache/
5
+ .ruff_cache/
6
+ node_modules/
7
+ dist/
8
+ src/duckpad/static/
9
+ .duckpad-dev/
10
+ test-results/
11
+ playwright-report/
12
+ *.egg-info/
13
+ .coverage
14
+ release-notes.md
15
+ *.tsbuildinfo
16
+ .multica/
17
+ .env
18
+ .env.*
19
+ !.env.example
@@ -0,0 +1,24 @@
1
+ # Repository Instructions
2
+
3
+ Before modifying files or preparing commits in this repository, read and follow
4
+ [the repository-conventions skill](.agents/skills/repository-conventions/SKILL.md).
5
+ Apply it to every change, even when it is not explicitly invoked.
6
+
7
+ - Write repository content in English, except localized UI values in dedicated
8
+ translation resource files, where French is allowed. Keep translation keys,
9
+ file names, code, comments, and documentation in English.
10
+ - Use Conventional Commits for every commit message, written in English.
11
+
12
+ ## Multica development
13
+
14
+ Follow [the Multica workflow](docs/MULTICA.md) for issues handled through Multica.
15
+ Use a dedicated branch and pull request for every issue, deploy and verify its
16
+ preview, then wait for the designated human reviewer's explicit approval before merging into `main` and
17
+ publishing the merge to GitHub. Never interpret ticket creation or a successful
18
+ check as merge approval. Use `bash scripts/preview.sh` for Duckpad previews.
19
+
20
+ Keep private infrastructure details outside this public repository. Never include
21
+ personal domains, preview URLs, server names, deployment identifiers, or credentials
22
+ in tracked files, commits, GitHub pull requests, or public build output. Share
23
+ preview URLs only in the private Multica issue; retrieve deployment configuration
24
+ from the operator's private environment. Do not include credentials in tickets.
@@ -0,0 +1,33 @@
1
+ FROM node:22-bookworm-slim AS frontend
2
+ WORKDIR /build/frontend
3
+ COPY frontend/package.json frontend/package-lock.json ./
4
+ RUN npm ci
5
+ COPY frontend/ ./
6
+ RUN npm run build
7
+
8
+ # Prepared once on the preview server by scripts/provision-runtime.sh.
9
+ FROM duckpad-python:3.12-duckdb2.0.0 AS backend
10
+ WORKDIR /app
11
+ ENV UV_LINK_MODE=copy UV_PYTHON_DOWNLOADS=never
12
+ COPY pyproject.toml uv.lock README.md LICENSE .gitignore ./
13
+ RUN uv sync --locked --no-dev --no-install-project --no-build-package duckdb \
14
+ && .venv/bin/python -c "import duckdb; assert duckdb.__version__ == '2.0.0'"
15
+ COPY scripts/build_hook.py scripts/build_hook.py
16
+ COPY src/ src/
17
+ COPY --from=frontend /build/src/duckpad/static/ src/duckpad/static/
18
+ RUN uv sync --locked --no-dev --no-editable --no-build-package duckdb
19
+
20
+ FROM python:3.12-slim-bookworm AS runtime
21
+ RUN apt-get update && apt-get install -y --no-install-recommends git ca-certificates libstdc++6 \
22
+ && rm -rf /var/lib/apt/lists/* \
23
+ && groupadd --gid 10001 duckpad \
24
+ && useradd --uid 10001 --gid duckpad --home-dir /data --create-home duckpad
25
+ WORKDIR /app
26
+ COPY --from=backend /app/.venv/ /app/.venv/
27
+ # Public previews use HTTPS even though the private proxy hop uses HTTP.
28
+ ENV PATH="/app/.venv/bin:$PATH" PYTHONUNBUFFERED=1 DUCKPAD_SECURE_COOKIES=1
29
+ USER duckpad
30
+ EXPOSE 8765
31
+ HEALTHCHECK --interval=15s --timeout=5s --start-period=20s --retries=3 \
32
+ CMD python -c "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8765/', timeout=4)"
33
+ CMD ["duckpad", "start", "--home", "/data/duckpad", "--host", "0.0.0.0", "--port", "8765", "--no-browser"]
@@ -0,0 +1,13 @@
1
+ # Build context: the validated wheel directory, not the repository root.
2
+ FROM python:3.12-slim-bookworm
3
+ # Coolify's cleanup skips tagged images carrying this label.
4
+ LABEL coolify.managed="true" org.opencontainers.image.title="Duckpad portable DuckDB 2.0 runtime"
5
+ COPY --from=ghcr.io/astral-sh/uv:0.9.5 /uv /usr/local/bin/uv
6
+ RUN apt-get update && apt-get install -y --no-install-recommends libstdc++6 \
7
+ && rm -rf /var/lib/apt/lists/*
8
+ COPY *.whl /tmp/duckdb-wheels/
9
+ RUN uv venv /app/.venv \
10
+ && uv pip install --python /app/.venv/bin/python --no-index \
11
+ --find-links /tmp/duckdb-wheels duckdb==2.0.0 \
12
+ && /app/.venv/bin/python -c "import duckdb; assert duckdb.__version__ == '2.0.0'; assert duckdb.sql('select 42').fetchall() == [(42,)]" \
13
+ && rm -rf /tmp/duckdb-wheels
duckpad-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Hugues
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.
duckpad-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,123 @@
1
+ Metadata-Version: 2.5
2
+ Name: duckpad
3
+ Version: 0.1.0
4
+ Summary: A local SQL canvas with reproducible execution and cell lineage
5
+ License-Expression: MIT
6
+ License-File: LICENSE
7
+ Requires-Python: >=3.11
8
+ Requires-Dist: duckdb>=2.0
9
+ Requires-Dist: fastapi>=0.115
10
+ Requires-Dist: filelock>=3.18
11
+ Requires-Dist: psutil>=7.2
12
+ Requires-Dist: pydantic>=2.10
13
+ Requires-Dist: python-multipart>=0.0.20
14
+ Requires-Dist: sqlglot>=27
15
+ Requires-Dist: uvicorn>=0.34
16
+ Provides-Extra: dev
17
+ Requires-Dist: apscheduler<4,>=3.11; extra == 'dev'
18
+ Requires-Dist: build>=1.2; extra == 'dev'
19
+ Requires-Dist: git-cliff==2.14.2; extra == 'dev'
20
+ Requires-Dist: httpx>=0.28; extra == 'dev'
21
+ Requires-Dist: huey>=2.5; extra == 'dev'
22
+ Requires-Dist: pytest>=8; extra == 'dev'
23
+ Requires-Dist: ruff>=0.11; extra == 'dev'
24
+ Requires-Dist: sqlalchemy>=2; extra == 'dev'
25
+ Provides-Extra: integration
26
+ Requires-Dist: boto3>=1.38; extra == 'integration'
27
+ Requires-Dist: moto[server]>=5; extra == 'integration'
28
+ Requires-Dist: oracledb>=3; extra == 'integration'
29
+ Description-Content-Type: text/markdown
30
+
31
+ # Duckpad
32
+
33
+ Build local DuckDB pipelines on a visual canvas, inspect their results, and explain individual values back to their source cells. Duckpad combines a React/TypeScript interface with a Python/FastAPI execution service.
34
+
35
+ ## Start
36
+
37
+ Requires **Python 3.11+ and Git** on `PATH`. Release wheels include the frontend, Monaco and its workers; Node.js is not needed to run the installed application.
38
+
39
+ ```sh
40
+ pip install ./dist/duckpad-0.1.0-py3-none-any.whl
41
+ duckpad start
42
+ ```
43
+
44
+ The distribution is named `duckpad`. Version tags publish the package to PyPI and create a GitHub release with Conventional Commit notes and downloadable distributions. After the first release, install it with `pip install duckpad`. See the [release guide](docs/RELEASING.md) for one-time publishing setup and tagging instructions.
45
+
46
+ Open the localhost address printed in the terminal. Sign in as `admin` using the password printed **once** on the first launch. The same password remains valid after a restart. The default instance directory is `$XDG_DATA_HOME/duckpad`, or `~/.local/share/duckpad`. Authentication, connection settings and execution history are kept there, outside project repositories.
47
+
48
+ ```sh
49
+ duckpad start --home /path/to/my-instance --port 8765 --no-browser
50
+ ```
51
+
52
+ Only one backend may own an instance directory at a time. Use separate `--home` directories for independent instances. The default address is `127.0.0.1`.
53
+
54
+ ## Try the complete example
55
+
56
+ Choose **Open example project** and **Run pipeline**. The Northstar example creates CSV and Parquet inputs, joins customers to orders, computes ordered outputs, uses nested reusable components twice with separate parameters, computes aggregates, distinct counts, set operations and window ranks, and exports two CSV reports. Its `dev` and `prod` data are deliberately different.
57
+
58
+ Select **Regional revenue**, choose the `report` output, then click a revenue cell. Follow a contribution into the nested aggregate and page through its source amounts. No external accounts are required for this example. See the [example tour](docs/EXAMPLE.md).
59
+
60
+ ![Northstar pipeline and preview](docs/images/workspace.png)
61
+
62
+ ## Included workflows
63
+
64
+ - Drag templates onto the canvas, connect ports, configure typed parameters, and edit shared SQL definitions in Monaco.
65
+ - Use guided filter, join-key and aggregate forms, or edit their generated SQL expressions.
66
+ - Preview, filter and sort results; explain valid cells with five contributions per page and complete counts.
67
+ - Group nodes into nested components, expose parameters, and import independent copies between projects.
68
+ - Save automatically to Git, inspect diffs, open isolated branches or historical revisions, and explicitly merge changes.
69
+ - Detect concurrent UI/file edits and resolve recoverable conflicts without losing either proposal.
70
+ - Recompute manually, stop active SQL, retain stale previews after failure, and inspect durable execution history.
71
+ - Configure reusable connections and environments outside project Git, with local, S3 and Oracle presets.
72
+ - Switch English/French and light/dark themes without changing the project.
73
+ - Monitor Duckpad server CPU and RAM as percentages with subtle background bars;
74
+ click for two minutes of history and RAM used / total in MiB or GiB. Samples
75
+ refresh every two seconds while the workspace is open; history resets on reload
76
+ or sign-out. Process memory comes from [psutil](https://psutil.io/platform/),
77
+ supporting Linux, macOS, and Windows. CPU includes all server threads, normalized
78
+ to the available CPU capacity (100% means fully used); RAM is current resident
79
+ memory divided by total capacity. CPU affinity and visible Linux cgroup v1/v2
80
+ limits constrain those capacities; otherwise system totals apply. Measurements
81
+ cover the Duckpad server process. Missing measurements are shown as unavailable.
82
+
83
+ Language defaults to the first supported language in your browser preferences
84
+ (English or French, with English as the fallback), and the theme defaults to your
85
+ system color scheme. Manual choices are saved in this browser and take priority
86
+ on subsequent visits.
87
+
88
+ Results live in memory per worktree and environment. After a backend restart, history remains available but previews and lineage require another manual run. Editing or changing an external source does not launch a run automatically.
89
+
90
+ ## Develop and verify
91
+
92
+ ```sh
93
+ bash scripts/setup.sh
94
+ uv run duckpad start --home .duckpad-dev --no-browser
95
+ ```
96
+
97
+ For frontend development, `npm run dev --prefix frontend` proxies `/api` to the backend on port 8765.
98
+
99
+ ```sh
100
+ uv run ruff check src tests scripts
101
+ uv run ruff format --check src tests scripts
102
+ uv run pytest -q
103
+ npm run check --prefix frontend
104
+ npm exec --prefix frontend -- playwright install chromium
105
+ npm run build --prefix frontend
106
+ npm run test:e2e --prefix frontend
107
+ uv build
108
+ ```
109
+
110
+ The Playwright suite starts a disposable instance on port 8766. `DUCKPAD_CHROMIUM_EXECUTABLE` can point to an already installed Chromium executable. Building a release without compiled assets fails with an actionable message; editable installation permits building them afterward.
111
+
112
+ ## Documentation
113
+
114
+ - [Release automation and publishing](docs/RELEASING.md)
115
+ - [Multica issue workflow and preview deployment](docs/MULTICA.md)
116
+ - [Architecture and execution invariants](docs/ARCHITECTURE.md)
117
+ - [Project files, templates and components](docs/AUTHORING.md)
118
+ - [Lineage coverage and limitations](docs/LINEAGE.md)
119
+ - [Connector setup and validated compatibility](docs/CONNECTORS.md)
120
+ - [Execution-service prototype and scheduling decision](docs/EXECUTION_SERVICE.md)
121
+ - [Validation results and performance reference](docs/VALIDATION.md)
122
+
123
+ The required dependency is `duckdb>=2.0`; the recorded validation uses **DuckDB 2.0.0 on Linux x86_64**. Oracle needs a matching OraDuck extension and Oracle Instant Client. S3 validation uses a local S3 emulator; live AWS IAM, TLS and deployment-specific behavior need their own integration checks. Details and reproducible commands are in the connector guide.
@@ -0,0 +1,93 @@
1
+ # Duckpad
2
+
3
+ Build local DuckDB pipelines on a visual canvas, inspect their results, and explain individual values back to their source cells. Duckpad combines a React/TypeScript interface with a Python/FastAPI execution service.
4
+
5
+ ## Start
6
+
7
+ Requires **Python 3.11+ and Git** on `PATH`. Release wheels include the frontend, Monaco and its workers; Node.js is not needed to run the installed application.
8
+
9
+ ```sh
10
+ pip install ./dist/duckpad-0.1.0-py3-none-any.whl
11
+ duckpad start
12
+ ```
13
+
14
+ The distribution is named `duckpad`. Version tags publish the package to PyPI and create a GitHub release with Conventional Commit notes and downloadable distributions. After the first release, install it with `pip install duckpad`. See the [release guide](docs/RELEASING.md) for one-time publishing setup and tagging instructions.
15
+
16
+ Open the localhost address printed in the terminal. Sign in as `admin` using the password printed **once** on the first launch. The same password remains valid after a restart. The default instance directory is `$XDG_DATA_HOME/duckpad`, or `~/.local/share/duckpad`. Authentication, connection settings and execution history are kept there, outside project repositories.
17
+
18
+ ```sh
19
+ duckpad start --home /path/to/my-instance --port 8765 --no-browser
20
+ ```
21
+
22
+ Only one backend may own an instance directory at a time. Use separate `--home` directories for independent instances. The default address is `127.0.0.1`.
23
+
24
+ ## Try the complete example
25
+
26
+ Choose **Open example project** and **Run pipeline**. The Northstar example creates CSV and Parquet inputs, joins customers to orders, computes ordered outputs, uses nested reusable components twice with separate parameters, computes aggregates, distinct counts, set operations and window ranks, and exports two CSV reports. Its `dev` and `prod` data are deliberately different.
27
+
28
+ Select **Regional revenue**, choose the `report` output, then click a revenue cell. Follow a contribution into the nested aggregate and page through its source amounts. No external accounts are required for this example. See the [example tour](docs/EXAMPLE.md).
29
+
30
+ ![Northstar pipeline and preview](docs/images/workspace.png)
31
+
32
+ ## Included workflows
33
+
34
+ - Drag templates onto the canvas, connect ports, configure typed parameters, and edit shared SQL definitions in Monaco.
35
+ - Use guided filter, join-key and aggregate forms, or edit their generated SQL expressions.
36
+ - Preview, filter and sort results; explain valid cells with five contributions per page and complete counts.
37
+ - Group nodes into nested components, expose parameters, and import independent copies between projects.
38
+ - Save automatically to Git, inspect diffs, open isolated branches or historical revisions, and explicitly merge changes.
39
+ - Detect concurrent UI/file edits and resolve recoverable conflicts without losing either proposal.
40
+ - Recompute manually, stop active SQL, retain stale previews after failure, and inspect durable execution history.
41
+ - Configure reusable connections and environments outside project Git, with local, S3 and Oracle presets.
42
+ - Switch English/French and light/dark themes without changing the project.
43
+ - Monitor Duckpad server CPU and RAM as percentages with subtle background bars;
44
+ click for two minutes of history and RAM used / total in MiB or GiB. Samples
45
+ refresh every two seconds while the workspace is open; history resets on reload
46
+ or sign-out. Process memory comes from [psutil](https://psutil.io/platform/),
47
+ supporting Linux, macOS, and Windows. CPU includes all server threads, normalized
48
+ to the available CPU capacity (100% means fully used); RAM is current resident
49
+ memory divided by total capacity. CPU affinity and visible Linux cgroup v1/v2
50
+ limits constrain those capacities; otherwise system totals apply. Measurements
51
+ cover the Duckpad server process. Missing measurements are shown as unavailable.
52
+
53
+ Language defaults to the first supported language in your browser preferences
54
+ (English or French, with English as the fallback), and the theme defaults to your
55
+ system color scheme. Manual choices are saved in this browser and take priority
56
+ on subsequent visits.
57
+
58
+ Results live in memory per worktree and environment. After a backend restart, history remains available but previews and lineage require another manual run. Editing or changing an external source does not launch a run automatically.
59
+
60
+ ## Develop and verify
61
+
62
+ ```sh
63
+ bash scripts/setup.sh
64
+ uv run duckpad start --home .duckpad-dev --no-browser
65
+ ```
66
+
67
+ For frontend development, `npm run dev --prefix frontend` proxies `/api` to the backend on port 8765.
68
+
69
+ ```sh
70
+ uv run ruff check src tests scripts
71
+ uv run ruff format --check src tests scripts
72
+ uv run pytest -q
73
+ npm run check --prefix frontend
74
+ npm exec --prefix frontend -- playwright install chromium
75
+ npm run build --prefix frontend
76
+ npm run test:e2e --prefix frontend
77
+ uv build
78
+ ```
79
+
80
+ The Playwright suite starts a disposable instance on port 8766. `DUCKPAD_CHROMIUM_EXECUTABLE` can point to an already installed Chromium executable. Building a release without compiled assets fails with an actionable message; editable installation permits building them afterward.
81
+
82
+ ## Documentation
83
+
84
+ - [Release automation and publishing](docs/RELEASING.md)
85
+ - [Multica issue workflow and preview deployment](docs/MULTICA.md)
86
+ - [Architecture and execution invariants](docs/ARCHITECTURE.md)
87
+ - [Project files, templates and components](docs/AUTHORING.md)
88
+ - [Lineage coverage and limitations](docs/LINEAGE.md)
89
+ - [Connector setup and validated compatibility](docs/CONNECTORS.md)
90
+ - [Execution-service prototype and scheduling decision](docs/EXECUTION_SERVICE.md)
91
+ - [Validation results and performance reference](docs/VALIDATION.md)
92
+
93
+ The required dependency is `duckdb>=2.0`; the recorded validation uses **DuckDB 2.0.0 on Linux x86_64**. Oracle needs a matching OraDuck extension and Oracle Instant Client. S3 validation uses a local S3 emulator; live AWS IAM, TLS and deployment-specific behavior need their own integration checks. Details and reproducible commands are in the connector guide.