queryview 0.0.6__tar.gz → 0.0.7__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.
- queryview-0.0.7/CONTRIBUTING.md +124 -0
- {queryview-0.0.6 → queryview-0.0.7}/PKG-INFO +62 -110
- {queryview-0.0.6 → queryview-0.0.7}/README.md +60 -108
- queryview-0.0.7/backend/queryview/static/assets/index-Cysz_FnM.js +46 -0
- queryview-0.0.7/backend/queryview/static/assets/index-h_3ZdSNd.css +2 -0
- {queryview-0.0.6 → queryview-0.0.7}/backend/queryview/static/index.html +2 -2
- {queryview-0.0.6 → queryview-0.0.7}/docs/connect.md +12 -5
- {queryview-0.0.6 → queryview-0.0.7}/docs/explorer.md +22 -9
- {queryview-0.0.6 → queryview-0.0.7}/docs/query.md +31 -4
- {queryview-0.0.6 → queryview-0.0.7}/docs/queryview.md +17 -1
- {queryview-0.0.6 → queryview-0.0.7}/e2e/conftest.py +56 -7
- {queryview-0.0.6 → queryview-0.0.7}/e2e/test_app.py +45 -4
- {queryview-0.0.6 → queryview-0.0.7}/e2e/test_dashboard.py +3 -10
- {queryview-0.0.6 → queryview-0.0.7}/e2e/test_drivers.py +5 -10
- queryview-0.0.7/e2e/test_explorer.py +202 -0
- queryview-0.0.7/e2e/test_popovers.py +49 -0
- {queryview-0.0.6 → queryview-0.0.7}/e2e/test_query.py +69 -11
- {queryview-0.0.6 → queryview-0.0.7}/e2e/test_remote.py +3 -11
- {queryview-0.0.6 → queryview-0.0.7}/frontend/src/app/App.tsx +120 -33
- {queryview-0.0.6 → queryview-0.0.7}/frontend/src/app/ExplorerView.tsx +186 -42
- {queryview-0.0.6 → queryview-0.0.7}/frontend/src/app/QueryView.tsx +24 -92
- {queryview-0.0.6 → queryview-0.0.7}/frontend/src/app/controls/GitSyncControls.tsx +0 -0
- queryview-0.0.7/frontend/src/app/controls/Spinner.tsx +34 -0
- {queryview-0.0.6 → queryview-0.0.7}/frontend/src/app/controls/WorkspaceSwitcher.tsx +5 -1
- queryview-0.0.7/frontend/src/app/controls/useDismiss.ts +28 -0
- queryview-0.0.7/frontend/src/app/explorerSettings.test.ts +61 -0
- queryview-0.0.7/frontend/src/app/explorerSettings.ts +27 -0
- queryview-0.0.7/frontend/src/app/testStorage.ts +25 -0
- queryview-0.0.7/frontend/src/app/viewSettings.test.ts +65 -0
- queryview-0.0.7/frontend/src/app/viewSettings.ts +31 -0
- {queryview-0.0.6 → queryview-0.0.7}/frontend/src/app/workspace.test.ts +1 -8
- queryview-0.0.7/frontend/src/core/cells/CellDataModal.tsx +125 -0
- queryview-0.0.7/frontend/src/core/cells/structured.test.ts +63 -0
- queryview-0.0.7/frontend/src/core/cells/structured.ts +51 -0
- queryview-0.0.7/frontend/src/core/cells/structuredTree.test.ts +85 -0
- queryview-0.0.7/frontend/src/core/cells/structuredTree.ts +58 -0
- queryview-0.0.7/frontend/src/core/results/ResultsTable.tsx +131 -0
- queryview-0.0.7/frontend/src/core/results/cellWidth.test.ts +21 -0
- queryview-0.0.7/frontend/src/core/results/cellWidth.ts +21 -0
- {queryview-0.0.6 → queryview-0.0.7}/frontend/src/index.css +20 -0
- {queryview-0.0.6 → queryview-0.0.7}/pyproject.toml +1 -1
- queryview-0.0.6/backend/queryview/static/assets/index-Ba8F6rEq.css +0 -2
- queryview-0.0.6/backend/queryview/static/assets/index-DX2c3Adh.js +0 -44
- queryview-0.0.6/e2e/test_explorer.py +0 -66
- queryview-0.0.6/frontend/src/core/results/ResultsTable.tsx +0 -56
- {queryview-0.0.6 → queryview-0.0.7}/.claude/settings.json +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/.github/actions/start-git-daemon/action.yaml +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/.github/workflows/ci.yml +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/.github/workflows/publish.yaml +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/.gitignore +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/.mcp.json +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/.pre-commit-config.yaml +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/CLAUDE.md +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/LICENSE +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/backend/alembic.ini +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/backend/queryview/__init__.py +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/backend/queryview/conftest.py +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/backend/queryview/connect.py +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/backend/queryview/dashboard_queries.py +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/backend/queryview/dashboards.py +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/backend/queryview/drivers/__init__.py +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/backend/queryview/drivers/base.py +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/backend/queryview/drivers/clickhouse.py +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/backend/queryview/drivers/duckdb.py +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/backend/queryview/drivers/postgres.py +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/backend/queryview/drivers/test_base.py +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/backend/queryview/drivers/test_clickhouse.py +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/backend/queryview/drivers/test_contract.py +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/backend/queryview/drivers/test_duckdb.py +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/backend/queryview/drivers/test_postgres.py +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/backend/queryview/gitsync.py +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/backend/queryview/main.py +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/backend/queryview/mcp_server.py +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/backend/queryview/migrations/env.py +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/backend/queryview/migrations/script.py.mako +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/backend/queryview/migrations/versions/9a536b7c0328_initial_schema.py +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/backend/queryview/migrations/versions/a1b2c3d4e5f6_connection_config_blob.py +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/backend/queryview/migrations/versions/b2c3d4e5f6a7_predefined_presentation.py +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/backend/queryview/migrations/versions/c7d8e9f0a1b2_workspaces.py +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/backend/queryview/queries.py +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/backend/queryview/remote.py +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/backend/queryview/static/favicon.svg +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/backend/queryview/test_api_db.py +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/backend/queryview/test_api_export_import.py +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/backend/queryview/test_api_gitsync.py +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/backend/queryview/test_api_workspaces.py +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/backend/queryview/test_connect_flow.py +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/backend/queryview/test_connect_store.py +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/backend/queryview/test_dashboard_queries.py +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/backend/queryview/test_dashboards.py +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/backend/queryview/test_data_dir.py +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/backend/queryview/test_gitsync.py +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/backend/queryview/test_main.py +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/backend/queryview/test_mcp_gitsync.py +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/backend/queryview/test_mcp_mount.py +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/backend/queryview/test_migrations.py +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/backend/queryview/test_queries.py +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/backend/queryview/test_remote.py +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/backend/queryview/test_validation.py +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/backend/queryview/test_workspaces.py +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/backend/queryview/test_yamlio.py +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/backend/queryview/validation.py +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/backend/queryview/workspaces.py +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/backend/queryview/yamlio.py +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/docker/Dockerfile +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/docs/api.md +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/docs/dashboard.md +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/docs/export-import.md +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/docs/future.md +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/docs/gitsync.md +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/docs/remote.md +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/docs/workspace.md +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/e2e/test_export_import.py +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/e2e/test_gitsync.py +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/e2e/test_workspaces.py +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/frontend/.gitignore +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/frontend/README.md +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/frontend/eslint.config.js +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/frontend/index.html +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/frontend/package.json +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/frontend/public/favicon.svg +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/frontend/src/app/DashboardView.tsx +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/frontend/src/app/compactNumber.test.ts +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/frontend/src/app/compactNumber.ts +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/frontend/src/app/connection.ts +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/frontend/src/app/controls/ExportImportControls.tsx +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/frontend/src/app/controls/Toast.tsx +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/frontend/src/app/databaseFilter.test.ts +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/frontend/src/app/databaseFilter.ts +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/frontend/src/app/drivers.ts +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/frontend/src/app/gitsync.test.ts +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/frontend/src/app/gitsync.ts +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/frontend/src/app/promptSuggestions.test.ts +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/frontend/src/app/promptSuggestions.ts +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/frontend/src/app/sessionLock.test.ts +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/frontend/src/app/sessionLock.ts +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/frontend/src/app/workspace.ts +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/frontend/src/app/yamlio.test.ts +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/frontend/src/app/yamlio.ts +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/frontend/src/core/cells/CellViewModal.tsx +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/frontend/src/core/cells/ComplexCell.tsx +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/frontend/src/core/cells/cellView.test.ts +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/frontend/src/core/cells/cellView.ts +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/frontend/src/core/cells/cellViewYaml.test.ts +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/frontend/src/core/cells/cellViewYaml.tsx +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/frontend/src/core/cells/complexCells.test.ts +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/frontend/src/core/cells/complexCells.ts +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/frontend/src/core/dashboard/DashboardFrame.tsx +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/frontend/src/core/dashboard/srcDoc.test.ts +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/frontend/src/core/dashboard/srcDoc.ts +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/frontend/src/core/index.ts +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/frontend/src/core/params/queryParams.test.ts +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/frontend/src/core/params/queryParams.ts +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/frontend/src/core/presentation/FieldPickers.tsx +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/frontend/src/core/presentation/presentation.test.ts +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/frontend/src/core/presentation/presentation.ts +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/frontend/src/core/results/rows.test.ts +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/frontend/src/core/results/rows.ts +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/frontend/src/main.tsx +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/frontend/tsconfig.app.json +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/frontend/tsconfig.json +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/frontend/tsconfig.node.json +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/frontend/vite.config.ts +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/package-lock.json +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/package.json +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/pyrightconfig.json +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/scripts/dev.sh +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/scripts/setup.sh +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/scripts/setup_browser.sh +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/scripts/setup_clickhouse.sh +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/scripts/setup_postgres.sh +0 -0
- {queryview-0.0.6 → queryview-0.0.7}/uv.lock +0 -0
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# Contributing to QueryView
|
|
2
|
+
|
|
3
|
+
QueryView is a **Python** backend (**FastAPI + SQLModel**) serving `/api/*`, a
|
|
4
|
+
**Vite + React + TypeScript** SPA with **Tailwind CSS**, and a
|
|
5
|
+
**[Playwright](https://playwright.dev)** end-to-end suite. This page covers
|
|
6
|
+
working on it; [README.md](README.md) covers running it.
|
|
7
|
+
|
|
8
|
+
## Layout
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
.
|
|
12
|
+
├── backend/ # Python FastAPI + SQLModel app exposing /api/* (queryview package)
|
|
13
|
+
├── frontend/ # Vite + React + TS + Tailwind v4 SPA (npm workspace)
|
|
14
|
+
├── e2e/ # Playwright (pytest) browser tests
|
|
15
|
+
├── docs/ # Feature and API documentation
|
|
16
|
+
├── pyproject.toml # Backend deps + console script + e2e `test` group (uv)
|
|
17
|
+
└── package.json # npm workspace root: dev orchestration + frontend build
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Prerequisites
|
|
21
|
+
|
|
22
|
+
- [uv](https://docs.astral.sh/uv/) — runs the Python backend and the Playwright
|
|
23
|
+
(pytest) e2e suite (it manages the Python toolchain and dependencies for you).
|
|
24
|
+
- [Node.js](https://nodejs.org) 20+ (with npm) — runs the root tasks and the
|
|
25
|
+
Vite frontend.
|
|
26
|
+
|
|
27
|
+
npm runs the frontend and the root task scripts; uv handles the backend's and
|
|
28
|
+
e2e suite's Python virtualenv and dependencies.
|
|
29
|
+
|
|
30
|
+
## Install
|
|
31
|
+
|
|
32
|
+
Install the backend's Python dependencies (uv reads the root `pyproject.toml`;
|
|
33
|
+
the package lives in `backend/queryview`):
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
uv sync
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Install the JavaScript dependencies for the frontend workspace:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
npm install
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Install the e2e tooling (the `test` dependency group) and fetch the Playwright
|
|
46
|
+
browser:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
uv sync --group test
|
|
50
|
+
uv run --group test playwright install chromium
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Run dev servers
|
|
54
|
+
|
|
55
|
+
Run backend and frontend together:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
npm run dev
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Or individually:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
npm run backend # uvicorn --reload on http://localhost:8000
|
|
65
|
+
npm run frontend # http://localhost:5173
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
The Vite dev server proxies `/api/*` to the FastAPI backend, so the SPA can call the API on the same origin.
|
|
69
|
+
|
|
70
|
+
## Build & preview production
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
npm run build # produces frontend/dist/
|
|
74
|
+
npm run start # SERVE_STATIC=1, FastAPI serves dist/ + /api on :8000
|
|
75
|
+
npm run preview # build && start in one shot
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
In production there is no Vite — the FastAPI backend serves the bundled SPA from `frontend/dist/` and falls back to `index.html` for any unknown non-`/api` path so client-side routing works. Override the dist location with `STATIC_ROOT=/path/to/dist`.
|
|
79
|
+
|
|
80
|
+
## Tests
|
|
81
|
+
|
|
82
|
+
Backend unit tests live beside the code they test inside `backend/queryview`,
|
|
83
|
+
and ship in the wheel:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
uv run --group test pytest backend/queryview
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
The e2e suite is [pytest-playwright](https://playwright.dev/python/docs/test-runners),
|
|
90
|
+
installed via the `test` dependency group and run through `uv`. Start the dev
|
|
91
|
+
servers (`npm run dev`) in one terminal, then in another:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
uv run --group test pytest
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Override the target URL with `BASE_URL=http://localhost:4173 uv run --group test pytest` (e.g. to test a built preview). To run the full suite against a real ClickHouse the way CI does, use `scripts/setup.sh`.
|
|
98
|
+
|
|
99
|
+
## Lint & type-check
|
|
100
|
+
|
|
101
|
+
[pre-commit](https://pre-commit.com) runs ruff (lint + format) and pyright, the
|
|
102
|
+
same checks CI's `lint` job runs. Pyright resolves imports from the project's
|
|
103
|
+
`.venv`, so sync first:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
uv sync --group dev
|
|
107
|
+
uv run pre-commit install # once, to run on every commit
|
|
108
|
+
uv run pre-commit run --all-files
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Release to PyPI
|
|
112
|
+
|
|
113
|
+
The **Publish to PyPI** workflow (`.github/workflows/publish.yaml`, manual
|
|
114
|
+
dispatch with a `vX.Y.Z` tag input) builds the SPA into the wheel
|
|
115
|
+
(`queryview/static/`), then gates the release on the installed wheel: an HTTP
|
|
116
|
+
smoke test, the packaged backend test suite (`pytest --pyargs queryview`), and
|
|
117
|
+
the Playwright e2e suite driving the packaged server (skippable via the
|
|
118
|
+
`skip-e2e` input for emergencies). It then publishes
|
|
119
|
+
[`queryview`](https://pypi.org/project/queryview/) via PyPI trusted publishing,
|
|
120
|
+
pushes the tag, and creates the GitHub release. The package version comes
|
|
121
|
+
from the tag (no version bump in `pyproject.toml`).
|
|
122
|
+
|
|
123
|
+
An installed wheel serves the bundled UI by default — see the
|
|
124
|
+
[quick start](README.md#quick-start).
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: queryview
|
|
3
|
-
Version: 0.0.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 0.0.7
|
|
4
|
+
Summary: Local SQL workbench for ClickHouse, Postgres and DuckDB, with a built-in MCP server for AI agents
|
|
5
5
|
Project-URL: Homepage, https://github.com/kolodkin/queryview
|
|
6
6
|
Project-URL: Repository, https://github.com/kolodkin/queryview
|
|
7
7
|
Project-URL: Issues, https://github.com/kolodkin/queryview/issues
|
|
@@ -24,7 +24,18 @@ Description-Content-Type: text/markdown
|
|
|
24
24
|
|
|
25
25
|
# QueryView
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
A local SQL workbench for **ClickHouse**, **Postgres** and **DuckDB** — and a
|
|
28
|
+
place to let an AI agent do the querying for you.
|
|
29
|
+
|
|
30
|
+
Everything happens at one prompt: type `connect prod` to open a database,
|
|
31
|
+
`query` to run SQL, `explorer` to click through tables, `dashboard` to open a
|
|
32
|
+
saved dashboard. Saved queries and dashboards live in workspaces that can back
|
|
33
|
+
themselves up to a git remote. A built-in MCP server lets an agent run
|
|
34
|
+
read-only queries, push a query or a whole dashboard into your open browser tab,
|
|
35
|
+
and snapshot your work to git.
|
|
36
|
+
|
|
37
|
+
QueryView is a **single-user tool that runs on your own machine**. It has no
|
|
38
|
+
login and assumes it is reachable only from localhost — don't expose its port.
|
|
28
39
|
|
|
29
40
|
## Quick start
|
|
30
41
|
|
|
@@ -54,6 +65,29 @@ The command above keeps its state inside the container, so connections and
|
|
|
54
65
|
workspaces are lost when the container is removed. See
|
|
55
66
|
[Run with Docker](#run-with-docker) for a persistent setup.
|
|
56
67
|
|
|
68
|
+
## What you can do
|
|
69
|
+
|
|
70
|
+
Open http://localhost:8000 and type into the prompt:
|
|
71
|
+
|
|
72
|
+
| Command | What happens |
|
|
73
|
+
|---|---|
|
|
74
|
+
| `new clickhouse` / `new postgres` / `new duckdb` | Create a connection — host, port and credentials, or a file path for DuckDB. Passwords are encrypted at rest. |
|
|
75
|
+
| `connect <name>` | Open a saved connection and pick a database — that opens the explorer. The last one reconnects automatically next time. |
|
|
76
|
+
| `query` | Run SQL: paginated results, column picker, save/load reusable queries, download the page as CSV. |
|
|
77
|
+
| `explorer` | Browse tables without typing SQL — a sidebar of tables with row/size estimates, click to page through rows. |
|
|
78
|
+
| `dashboard [name]` | Open a saved dashboard: an HTML layout that re-runs its queries against live data every time you open it. |
|
|
79
|
+
|
|
80
|
+
Beyond the prompt:
|
|
81
|
+
|
|
82
|
+
- **Workspaces** group your saved queries and dashboards, and each can sync to
|
|
83
|
+
its own git remote for backup, history and restore —
|
|
84
|
+
[workspace.md](docs/workspace.md), [gitsync.md](docs/gitsync.md).
|
|
85
|
+
- **YAML export/import** moves a single query, a dashboard, or a whole
|
|
86
|
+
workspace between instances with no git involved —
|
|
87
|
+
[export-import.md](docs/export-import.md).
|
|
88
|
+
- **MCP** lets an agent query your databases and author dashboards — see
|
|
89
|
+
[below](#mcp-server).
|
|
90
|
+
|
|
57
91
|
## Run with Docker
|
|
58
92
|
|
|
59
93
|
The image runs as the non-root user `queryview` (UID 1000) and sets
|
|
@@ -114,105 +148,6 @@ docker run -d --name queryview \
|
|
|
114
148
|
ghcr.io/kolodkin/queryview:latest
|
|
115
149
|
```
|
|
116
150
|
|
|
117
|
-
## Layout
|
|
118
|
-
|
|
119
|
-
```
|
|
120
|
-
.
|
|
121
|
-
├── backend/ # Python FastAPI + SQLModel app exposing /api/* (queryview package)
|
|
122
|
-
├── frontend/ # Vite + React + TS + Tailwind v4 SPA (npm workspace)
|
|
123
|
-
├── e2e/ # Playwright (pytest) browser tests
|
|
124
|
-
├── pyproject.toml # Backend deps + console script + e2e `test` group (uv)
|
|
125
|
-
└── package.json # npm workspace root: dev orchestration + frontend build
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
## Prerequisites
|
|
129
|
-
|
|
130
|
-
- [uv](https://docs.astral.sh/uv/) — runs the Python backend and the Playwright
|
|
131
|
-
(pytest) e2e suite (it manages the Python toolchain and dependencies for you).
|
|
132
|
-
- [Node.js](https://nodejs.org) 20+ (with npm) — runs the root tasks and the
|
|
133
|
-
Vite frontend.
|
|
134
|
-
|
|
135
|
-
npm runs the frontend and the root task scripts; uv handles the backend's and
|
|
136
|
-
e2e suite's Python virtualenv and dependencies.
|
|
137
|
-
|
|
138
|
-
## Install
|
|
139
|
-
|
|
140
|
-
Install the backend's Python dependencies (uv reads the root `pyproject.toml`;
|
|
141
|
-
the package lives in `backend/queryview`):
|
|
142
|
-
|
|
143
|
-
```bash
|
|
144
|
-
uv sync
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
Install the JavaScript dependencies for the frontend workspace:
|
|
148
|
-
|
|
149
|
-
```bash
|
|
150
|
-
npm install
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
Install the e2e tooling (the `test` dependency group) and fetch the Playwright
|
|
154
|
-
browser:
|
|
155
|
-
|
|
156
|
-
```bash
|
|
157
|
-
uv sync --group test
|
|
158
|
-
uv run --group test playwright install chromium
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
## Run dev servers
|
|
162
|
-
|
|
163
|
-
Run backend and frontend together:
|
|
164
|
-
|
|
165
|
-
```bash
|
|
166
|
-
npm run dev
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
Or individually:
|
|
170
|
-
|
|
171
|
-
```bash
|
|
172
|
-
npm run backend # uvicorn --reload on http://localhost:8000
|
|
173
|
-
npm run frontend # http://localhost:5173
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
The Vite dev server proxies `/api/*` to the FastAPI backend, so the SPA can call the API on the same origin.
|
|
177
|
-
|
|
178
|
-
## Build & preview production
|
|
179
|
-
|
|
180
|
-
```bash
|
|
181
|
-
npm run build # produces frontend/dist/
|
|
182
|
-
npm run start # SERVE_STATIC=1, FastAPI serves dist/ + /api on :8000
|
|
183
|
-
npm run preview # build && start in one shot
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
In production there is no Vite — the FastAPI backend serves the bundled SPA from `frontend/dist/` and falls back to `index.html` for any unknown non-`/api` path so client-side routing works. Override the dist location with `STATIC_ROOT=/path/to/dist`.
|
|
187
|
-
|
|
188
|
-
## End-to-end tests
|
|
189
|
-
|
|
190
|
-
The e2e suite is [pytest-playwright](https://playwright.dev/python/docs/test-runners),
|
|
191
|
-
installed via the `test` dependency group and run through `uv`.
|
|
192
|
-
|
|
193
|
-
Start the dev servers (`npm run dev`) in one terminal, then in another:
|
|
194
|
-
|
|
195
|
-
```bash
|
|
196
|
-
uv run --group test pytest
|
|
197
|
-
```
|
|
198
|
-
|
|
199
|
-
Override the target URL with `BASE_URL=http://localhost:4173 uv run --group test pytest` (e.g. to test a built preview). To run the full suite against a real ClickHouse the way CI does, use `scripts/setup.sh`.
|
|
200
|
-
|
|
201
|
-
## Release to PyPI
|
|
202
|
-
|
|
203
|
-
The **Publish to PyPI** workflow (`.github/workflows/publish.yaml`, manual
|
|
204
|
-
dispatch with a `vX.Y.Z` tag input) builds the SPA into the wheel
|
|
205
|
-
(`queryview/static/`), then gates the release on the installed wheel: an HTTP
|
|
206
|
-
smoke test, the packaged backend test suite (`pytest --pyargs queryview`), and
|
|
207
|
-
the Playwright e2e suite driving the packaged server (skippable via the
|
|
208
|
-
`skip-e2e` input for emergencies). It then publishes
|
|
209
|
-
[`queryview`](https://pypi.org/project/queryview/) via PyPI trusted publishing,
|
|
210
|
-
pushes the tag, and creates the GitHub release. The package version comes
|
|
211
|
-
from the tag (no version bump in `pyproject.toml`).
|
|
212
|
-
|
|
213
|
-
An installed wheel serves the bundled UI by default — see
|
|
214
|
-
[Quick start](#quick-start).
|
|
215
|
-
|
|
216
151
|
## MCP server
|
|
217
152
|
|
|
218
153
|
The backend mounts a FastMCP server (Streamable HTTP) at
|
|
@@ -252,15 +187,32 @@ git backups). The push tools target an **armed** browser session: enable
|
|
|
252
187
|
the session id it shows. See [docs/remote.md](docs/remote.md) for the full
|
|
253
188
|
protocol.
|
|
254
189
|
|
|
255
|
-
##
|
|
256
|
-
|
|
257
|
-
See [docs/api.md](docs/api.md) for the full endpoint reference.
|
|
258
|
-
|
|
259
|
-
The single-page prompt UI is described in [docs/queryview.md](docs/queryview.md);
|
|
260
|
-
connecting (`new <type>` / `connect <name>`), SQLite persistence, and session
|
|
261
|
-
auto-connect are specified in [docs/connect.md](docs/connect.md).
|
|
190
|
+
## Where your data lives
|
|
262
191
|
|
|
263
192
|
All state lives in one data directory, `~/.queryview` on every OS, relocated
|
|
264
193
|
with `DATA_DIR`. Inside are the SQLite store `db.sqlite`, the local
|
|
265
194
|
password-encryption key `encryption.key`, and the workspace git-sync clones
|
|
266
|
-
under `gitsync/`.
|
|
195
|
+
under `gitsync/`. Back that directory up — or give each workspace a git remote
|
|
196
|
+
and let [git sync](docs/gitsync.md) do it.
|
|
197
|
+
|
|
198
|
+
## Documentation
|
|
199
|
+
|
|
200
|
+
- [queryview.md](docs/queryview.md) — the single-prompt page.
|
|
201
|
+
- [connect.md](docs/connect.md) — connections, drivers, sessions, storage.
|
|
202
|
+
- [query.md](docs/query.md) — the query panel: pagination, predefined queries, CSV.
|
|
203
|
+
- [explorer.md](docs/explorer.md) — the table navigator.
|
|
204
|
+
- [dashboard.md](docs/dashboard.md) — dashboards and how agents author them.
|
|
205
|
+
- [workspace.md](docs/workspace.md) — workspaces.
|
|
206
|
+
- [gitsync.md](docs/gitsync.md) — git backup, history and restore.
|
|
207
|
+
- [export-import.md](docs/export-import.md) — YAML export and import.
|
|
208
|
+
- [remote.md](docs/remote.md) — the remote-control protocol behind the MCP push tools.
|
|
209
|
+
- [api.md](docs/api.md) — the full HTTP endpoint reference.
|
|
210
|
+
|
|
211
|
+
## Contributing
|
|
212
|
+
|
|
213
|
+
Development setup, tests and the release process are in
|
|
214
|
+
[CONTRIBUTING.md](CONTRIBUTING.md).
|
|
215
|
+
|
|
216
|
+
## License
|
|
217
|
+
|
|
218
|
+
[MIT](LICENSE).
|
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
# QueryView
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A local SQL workbench for **ClickHouse**, **Postgres** and **DuckDB** — and a
|
|
4
|
+
place to let an AI agent do the querying for you.
|
|
5
|
+
|
|
6
|
+
Everything happens at one prompt: type `connect prod` to open a database,
|
|
7
|
+
`query` to run SQL, `explorer` to click through tables, `dashboard` to open a
|
|
8
|
+
saved dashboard. Saved queries and dashboards live in workspaces that can back
|
|
9
|
+
themselves up to a git remote. A built-in MCP server lets an agent run
|
|
10
|
+
read-only queries, push a query or a whole dashboard into your open browser tab,
|
|
11
|
+
and snapshot your work to git.
|
|
12
|
+
|
|
13
|
+
QueryView is a **single-user tool that runs on your own machine**. It has no
|
|
14
|
+
login and assumes it is reachable only from localhost — don't expose its port.
|
|
4
15
|
|
|
5
16
|
## Quick start
|
|
6
17
|
|
|
@@ -30,6 +41,29 @@ The command above keeps its state inside the container, so connections and
|
|
|
30
41
|
workspaces are lost when the container is removed. See
|
|
31
42
|
[Run with Docker](#run-with-docker) for a persistent setup.
|
|
32
43
|
|
|
44
|
+
## What you can do
|
|
45
|
+
|
|
46
|
+
Open http://localhost:8000 and type into the prompt:
|
|
47
|
+
|
|
48
|
+
| Command | What happens |
|
|
49
|
+
|---|---|
|
|
50
|
+
| `new clickhouse` / `new postgres` / `new duckdb` | Create a connection — host, port and credentials, or a file path for DuckDB. Passwords are encrypted at rest. |
|
|
51
|
+
| `connect <name>` | Open a saved connection and pick a database — that opens the explorer. The last one reconnects automatically next time. |
|
|
52
|
+
| `query` | Run SQL: paginated results, column picker, save/load reusable queries, download the page as CSV. |
|
|
53
|
+
| `explorer` | Browse tables without typing SQL — a sidebar of tables with row/size estimates, click to page through rows. |
|
|
54
|
+
| `dashboard [name]` | Open a saved dashboard: an HTML layout that re-runs its queries against live data every time you open it. |
|
|
55
|
+
|
|
56
|
+
Beyond the prompt:
|
|
57
|
+
|
|
58
|
+
- **Workspaces** group your saved queries and dashboards, and each can sync to
|
|
59
|
+
its own git remote for backup, history and restore —
|
|
60
|
+
[workspace.md](docs/workspace.md), [gitsync.md](docs/gitsync.md).
|
|
61
|
+
- **YAML export/import** moves a single query, a dashboard, or a whole
|
|
62
|
+
workspace between instances with no git involved —
|
|
63
|
+
[export-import.md](docs/export-import.md).
|
|
64
|
+
- **MCP** lets an agent query your databases and author dashboards — see
|
|
65
|
+
[below](#mcp-server).
|
|
66
|
+
|
|
33
67
|
## Run with Docker
|
|
34
68
|
|
|
35
69
|
The image runs as the non-root user `queryview` (UID 1000) and sets
|
|
@@ -90,105 +124,6 @@ docker run -d --name queryview \
|
|
|
90
124
|
ghcr.io/kolodkin/queryview:latest
|
|
91
125
|
```
|
|
92
126
|
|
|
93
|
-
## Layout
|
|
94
|
-
|
|
95
|
-
```
|
|
96
|
-
.
|
|
97
|
-
├── backend/ # Python FastAPI + SQLModel app exposing /api/* (queryview package)
|
|
98
|
-
├── frontend/ # Vite + React + TS + Tailwind v4 SPA (npm workspace)
|
|
99
|
-
├── e2e/ # Playwright (pytest) browser tests
|
|
100
|
-
├── pyproject.toml # Backend deps + console script + e2e `test` group (uv)
|
|
101
|
-
└── package.json # npm workspace root: dev orchestration + frontend build
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
## Prerequisites
|
|
105
|
-
|
|
106
|
-
- [uv](https://docs.astral.sh/uv/) — runs the Python backend and the Playwright
|
|
107
|
-
(pytest) e2e suite (it manages the Python toolchain and dependencies for you).
|
|
108
|
-
- [Node.js](https://nodejs.org) 20+ (with npm) — runs the root tasks and the
|
|
109
|
-
Vite frontend.
|
|
110
|
-
|
|
111
|
-
npm runs the frontend and the root task scripts; uv handles the backend's and
|
|
112
|
-
e2e suite's Python virtualenv and dependencies.
|
|
113
|
-
|
|
114
|
-
## Install
|
|
115
|
-
|
|
116
|
-
Install the backend's Python dependencies (uv reads the root `pyproject.toml`;
|
|
117
|
-
the package lives in `backend/queryview`):
|
|
118
|
-
|
|
119
|
-
```bash
|
|
120
|
-
uv sync
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
Install the JavaScript dependencies for the frontend workspace:
|
|
124
|
-
|
|
125
|
-
```bash
|
|
126
|
-
npm install
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
Install the e2e tooling (the `test` dependency group) and fetch the Playwright
|
|
130
|
-
browser:
|
|
131
|
-
|
|
132
|
-
```bash
|
|
133
|
-
uv sync --group test
|
|
134
|
-
uv run --group test playwright install chromium
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
## Run dev servers
|
|
138
|
-
|
|
139
|
-
Run backend and frontend together:
|
|
140
|
-
|
|
141
|
-
```bash
|
|
142
|
-
npm run dev
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
Or individually:
|
|
146
|
-
|
|
147
|
-
```bash
|
|
148
|
-
npm run backend # uvicorn --reload on http://localhost:8000
|
|
149
|
-
npm run frontend # http://localhost:5173
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
The Vite dev server proxies `/api/*` to the FastAPI backend, so the SPA can call the API on the same origin.
|
|
153
|
-
|
|
154
|
-
## Build & preview production
|
|
155
|
-
|
|
156
|
-
```bash
|
|
157
|
-
npm run build # produces frontend/dist/
|
|
158
|
-
npm run start # SERVE_STATIC=1, FastAPI serves dist/ + /api on :8000
|
|
159
|
-
npm run preview # build && start in one shot
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
In production there is no Vite — the FastAPI backend serves the bundled SPA from `frontend/dist/` and falls back to `index.html` for any unknown non-`/api` path so client-side routing works. Override the dist location with `STATIC_ROOT=/path/to/dist`.
|
|
163
|
-
|
|
164
|
-
## End-to-end tests
|
|
165
|
-
|
|
166
|
-
The e2e suite is [pytest-playwright](https://playwright.dev/python/docs/test-runners),
|
|
167
|
-
installed via the `test` dependency group and run through `uv`.
|
|
168
|
-
|
|
169
|
-
Start the dev servers (`npm run dev`) in one terminal, then in another:
|
|
170
|
-
|
|
171
|
-
```bash
|
|
172
|
-
uv run --group test pytest
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
Override the target URL with `BASE_URL=http://localhost:4173 uv run --group test pytest` (e.g. to test a built preview). To run the full suite against a real ClickHouse the way CI does, use `scripts/setup.sh`.
|
|
176
|
-
|
|
177
|
-
## Release to PyPI
|
|
178
|
-
|
|
179
|
-
The **Publish to PyPI** workflow (`.github/workflows/publish.yaml`, manual
|
|
180
|
-
dispatch with a `vX.Y.Z` tag input) builds the SPA into the wheel
|
|
181
|
-
(`queryview/static/`), then gates the release on the installed wheel: an HTTP
|
|
182
|
-
smoke test, the packaged backend test suite (`pytest --pyargs queryview`), and
|
|
183
|
-
the Playwright e2e suite driving the packaged server (skippable via the
|
|
184
|
-
`skip-e2e` input for emergencies). It then publishes
|
|
185
|
-
[`queryview`](https://pypi.org/project/queryview/) via PyPI trusted publishing,
|
|
186
|
-
pushes the tag, and creates the GitHub release. The package version comes
|
|
187
|
-
from the tag (no version bump in `pyproject.toml`).
|
|
188
|
-
|
|
189
|
-
An installed wheel serves the bundled UI by default — see
|
|
190
|
-
[Quick start](#quick-start).
|
|
191
|
-
|
|
192
127
|
## MCP server
|
|
193
128
|
|
|
194
129
|
The backend mounts a FastMCP server (Streamable HTTP) at
|
|
@@ -228,15 +163,32 @@ git backups). The push tools target an **armed** browser session: enable
|
|
|
228
163
|
the session id it shows. See [docs/remote.md](docs/remote.md) for the full
|
|
229
164
|
protocol.
|
|
230
165
|
|
|
231
|
-
##
|
|
232
|
-
|
|
233
|
-
See [docs/api.md](docs/api.md) for the full endpoint reference.
|
|
234
|
-
|
|
235
|
-
The single-page prompt UI is described in [docs/queryview.md](docs/queryview.md);
|
|
236
|
-
connecting (`new <type>` / `connect <name>`), SQLite persistence, and session
|
|
237
|
-
auto-connect are specified in [docs/connect.md](docs/connect.md).
|
|
166
|
+
## Where your data lives
|
|
238
167
|
|
|
239
168
|
All state lives in one data directory, `~/.queryview` on every OS, relocated
|
|
240
169
|
with `DATA_DIR`. Inside are the SQLite store `db.sqlite`, the local
|
|
241
170
|
password-encryption key `encryption.key`, and the workspace git-sync clones
|
|
242
|
-
under `gitsync/`.
|
|
171
|
+
under `gitsync/`. Back that directory up — or give each workspace a git remote
|
|
172
|
+
and let [git sync](docs/gitsync.md) do it.
|
|
173
|
+
|
|
174
|
+
## Documentation
|
|
175
|
+
|
|
176
|
+
- [queryview.md](docs/queryview.md) — the single-prompt page.
|
|
177
|
+
- [connect.md](docs/connect.md) — connections, drivers, sessions, storage.
|
|
178
|
+
- [query.md](docs/query.md) — the query panel: pagination, predefined queries, CSV.
|
|
179
|
+
- [explorer.md](docs/explorer.md) — the table navigator.
|
|
180
|
+
- [dashboard.md](docs/dashboard.md) — dashboards and how agents author them.
|
|
181
|
+
- [workspace.md](docs/workspace.md) — workspaces.
|
|
182
|
+
- [gitsync.md](docs/gitsync.md) — git backup, history and restore.
|
|
183
|
+
- [export-import.md](docs/export-import.md) — YAML export and import.
|
|
184
|
+
- [remote.md](docs/remote.md) — the remote-control protocol behind the MCP push tools.
|
|
185
|
+
- [api.md](docs/api.md) — the full HTTP endpoint reference.
|
|
186
|
+
|
|
187
|
+
## Contributing
|
|
188
|
+
|
|
189
|
+
Development setup, tests and the release process are in
|
|
190
|
+
[CONTRIBUTING.md](CONTRIBUTING.md).
|
|
191
|
+
|
|
192
|
+
## License
|
|
193
|
+
|
|
194
|
+
[MIT](LICENSE).
|