cantrip 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.
- cantrip-0.1.0/.coveragerc +37 -0
- cantrip-0.1.0/.github/workflows/integration.yml +113 -0
- cantrip-0.1.0/.github/workflows/pr.yml +29 -0
- cantrip-0.1.0/.github/workflows/release.yml +46 -0
- cantrip-0.1.0/.gitignore +5 -0
- cantrip-0.1.0/.pre-commit-config.yaml +44 -0
- cantrip-0.1.0/CONTRIBUTING.md +30 -0
- cantrip-0.1.0/LICENSE +661 -0
- cantrip-0.1.0/Makefile +19 -0
- cantrip-0.1.0/PKG-INFO +462 -0
- cantrip-0.1.0/README.md +438 -0
- cantrip-0.1.0/docker-compose.yml +20 -0
- cantrip-0.1.0/examples/bigquery/tpcds.sql +178 -0
- cantrip-0.1.0/examples/duckdb/tpcds.sql +154 -0
- cantrip-0.1.0/examples/postgres/tpcds.sql +154 -0
- cantrip-0.1.0/examples/snowflake/tpcds.sql +163 -0
- cantrip-0.1.0/examples/sqlite/tpcds.sql +160 -0
- cantrip-0.1.0/pyproject.toml +52 -0
- cantrip-0.1.0/scripts/generate_calendar.py +408 -0
- cantrip-0.1.0/scripts/generate_geometries.py +614 -0
- cantrip-0.1.0/src/cantrip/__init__.py +0 -0
- cantrip-0.1.0/src/cantrip/implementations/__init__.py +0 -0
- cantrip-0.1.0/src/cantrip/implementations/base.py +2168 -0
- cantrip-0.1.0/src/cantrip/implementations/bigquery.py +463 -0
- cantrip-0.1.0/src/cantrip/implementations/duckdb.py +305 -0
- cantrip-0.1.0/src/cantrip/implementations/information_schema.py +336 -0
- cantrip-0.1.0/src/cantrip/implementations/postgres.py +341 -0
- cantrip-0.1.0/src/cantrip/implementations/snowflake.py +468 -0
- cantrip-0.1.0/src/cantrip/implementations/sqlite.py +882 -0
- cantrip-0.1.0/src/cantrip/models.py +414 -0
- cantrip-0.1.0/src/cantrip/protocol.py +111 -0
- cantrip-0.1.0/src/cantrip/py.typed +0 -0
- cantrip-0.1.0/src/cantrip/toolbox.py +41 -0
- cantrip-0.1.0/src/cantrip/transforms.py +75 -0
- cantrip-0.1.0/src/cantrip/type_map.py +149 -0
- cantrip-0.1.0/tests/__init__.py +0 -0
- cantrip-0.1.0/tests/conftest.py +3 -0
- cantrip-0.1.0/tests/implementations/__init__.py +0 -0
- cantrip-0.1.0/tests/implementations/base_test.py +2897 -0
- cantrip-0.1.0/tests/implementations/bigquery_integration_test.py +420 -0
- cantrip-0.1.0/tests/implementations/bigquery_spatial_integration_test.py +181 -0
- cantrip-0.1.0/tests/implementations/bigquery_test.py +1580 -0
- cantrip-0.1.0/tests/implementations/duckdb_integration_test.py +303 -0
- cantrip-0.1.0/tests/implementations/duckdb_spatial_integration_test.py +145 -0
- cantrip-0.1.0/tests/implementations/duckdb_test.py +620 -0
- cantrip-0.1.0/tests/implementations/partition_integration_test.py +196 -0
- cantrip-0.1.0/tests/implementations/postgres_integration_test.py +296 -0
- cantrip-0.1.0/tests/implementations/postgres_spatial_integration_test.py +185 -0
- cantrip-0.1.0/tests/implementations/postgres_test.py +649 -0
- cantrip-0.1.0/tests/implementations/snowflake_integration_test.py +274 -0
- cantrip-0.1.0/tests/implementations/snowflake_spatial_integration_test.py +158 -0
- cantrip-0.1.0/tests/implementations/snowflake_test.py +1063 -0
- cantrip-0.1.0/tests/implementations/sqlite_spatial_integration_test.py +219 -0
- cantrip-0.1.0/tests/implementations/sqlite_test.py +1611 -0
- cantrip-0.1.0/tests/init/bigquery/schema.sql +219 -0
- cantrip-0.1.0/tests/init/bigquery/spatial.sql +58 -0
- cantrip-0.1.0/tests/init/duckdb/schema.sql +148 -0
- cantrip-0.1.0/tests/init/duckdb/spatial.sql +58 -0
- cantrip-0.1.0/tests/init/postgres/schema.sql +148 -0
- cantrip-0.1.0/tests/init/postgres/spatial.sql +60 -0
- cantrip-0.1.0/tests/init/snowflake/schema.sql +206 -0
- cantrip-0.1.0/tests/init/snowflake/spatial.sql +89 -0
- cantrip-0.1.0/tests/init/sqlite/schema.sql +177 -0
- cantrip-0.1.0/tests/init/sqlite/spatial.sql +63 -0
- cantrip-0.1.0/tests/models_test.py +373 -0
- cantrip-0.1.0/tests/protocol_test.py +60 -0
- cantrip-0.1.0/uv.lock +1349 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# .coveragerc to control coverage.py
|
|
2
|
+
[run]
|
|
3
|
+
branch = True
|
|
4
|
+
source = cantrip
|
|
5
|
+
# omit = bad_file.py
|
|
6
|
+
|
|
7
|
+
[paths]
|
|
8
|
+
source =
|
|
9
|
+
src/
|
|
10
|
+
*/site-packages/
|
|
11
|
+
|
|
12
|
+
[report]
|
|
13
|
+
# Regexes for lines to exclude from consideration
|
|
14
|
+
exclude_lines =
|
|
15
|
+
# Have to re-enable the standard pragma
|
|
16
|
+
pragma: no cover
|
|
17
|
+
|
|
18
|
+
# Don't complain about missing debug-only code:
|
|
19
|
+
def __repr__
|
|
20
|
+
if self\.debug
|
|
21
|
+
|
|
22
|
+
# Don't complain if tests don't hit defensive assertion code:
|
|
23
|
+
raise AssertionError
|
|
24
|
+
raise NotImplementedError
|
|
25
|
+
|
|
26
|
+
# Don't complain if non-runnable code isn't run:
|
|
27
|
+
if 0:
|
|
28
|
+
if __name__ == "__main__":
|
|
29
|
+
|
|
30
|
+
# Ignore importlib backport
|
|
31
|
+
from importlib
|
|
32
|
+
|
|
33
|
+
# Protocol
|
|
34
|
+
\.\.\.
|
|
35
|
+
|
|
36
|
+
fail_under = 100
|
|
37
|
+
show_missing = True
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# Integration tests — requires secrets, so only runs on pushes to main
|
|
2
|
+
# or PRs from the same repo (never from forks).
|
|
3
|
+
|
|
4
|
+
name: Integration
|
|
5
|
+
|
|
6
|
+
on:
|
|
7
|
+
push:
|
|
8
|
+
branches: [main]
|
|
9
|
+
pull_request:
|
|
10
|
+
branches: [main]
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
postgres:
|
|
14
|
+
name: PostgreSQL + PostGIS
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
if: >-
|
|
17
|
+
github.event_name == 'push'
|
|
18
|
+
|| github.event.pull_request.head.repo.full_name == github.repository
|
|
19
|
+
|
|
20
|
+
services:
|
|
21
|
+
postgres:
|
|
22
|
+
image: imresamu/postgis:16-3.4
|
|
23
|
+
env:
|
|
24
|
+
POSTGRES_PASSWORD: test
|
|
25
|
+
POSTGRES_DB: cantrip_test
|
|
26
|
+
ports:
|
|
27
|
+
- 5433:5432
|
|
28
|
+
options: >-
|
|
29
|
+
--health-cmd "pg_isready -U postgres"
|
|
30
|
+
--health-interval 2s
|
|
31
|
+
--health-timeout 5s
|
|
32
|
+
--health-retries 10
|
|
33
|
+
|
|
34
|
+
steps:
|
|
35
|
+
- uses: actions/checkout@v4
|
|
36
|
+
- uses: astral-sh/setup-uv@v4
|
|
37
|
+
- run: >-
|
|
38
|
+
uv run --extra postgres pytest -vv
|
|
39
|
+
--with-integration --with-slow-integration
|
|
40
|
+
tests/implementations/postgres_integration_test.py
|
|
41
|
+
tests/implementations/postgres_spatial_integration_test.py
|
|
42
|
+
env:
|
|
43
|
+
CANTRIP_POSTGRES_URL: postgresql+psycopg2://postgres:test@localhost:5433/cantrip_test
|
|
44
|
+
|
|
45
|
+
duckdb:
|
|
46
|
+
name: DuckDB
|
|
47
|
+
runs-on: ubuntu-latest
|
|
48
|
+
if: >-
|
|
49
|
+
github.event_name == 'push'
|
|
50
|
+
|| github.event.pull_request.head.repo.full_name == github.repository
|
|
51
|
+
|
|
52
|
+
steps:
|
|
53
|
+
- uses: actions/checkout@v4
|
|
54
|
+
- uses: astral-sh/setup-uv@v4
|
|
55
|
+
- run: >-
|
|
56
|
+
uv run --extra duckdb pytest -vv
|
|
57
|
+
--with-integration --with-slow-integration
|
|
58
|
+
tests/implementations/duckdb_integration_test.py
|
|
59
|
+
tests/implementations/duckdb_spatial_integration_test.py
|
|
60
|
+
|
|
61
|
+
sqlite:
|
|
62
|
+
name: SQLite + SpatiaLite
|
|
63
|
+
runs-on: ubuntu-latest
|
|
64
|
+
if: >-
|
|
65
|
+
github.event_name == 'push'
|
|
66
|
+
|| github.event.pull_request.head.repo.full_name == github.repository
|
|
67
|
+
|
|
68
|
+
steps:
|
|
69
|
+
- uses: actions/checkout@v4
|
|
70
|
+
- uses: astral-sh/setup-uv@v4
|
|
71
|
+
- run: sudo apt-get update && sudo apt-get install -y libsqlite3-mod-spatialite
|
|
72
|
+
- run: >-
|
|
73
|
+
uv run pytest -vv
|
|
74
|
+
--with-integration --with-slow-integration
|
|
75
|
+
tests/implementations/sqlite_spatial_integration_test.py
|
|
76
|
+
tests/implementations/partition_integration_test.py
|
|
77
|
+
|
|
78
|
+
bigquery:
|
|
79
|
+
name: BigQuery
|
|
80
|
+
runs-on: ubuntu-latest
|
|
81
|
+
if: >-
|
|
82
|
+
github.event_name == 'push'
|
|
83
|
+
|| github.event.pull_request.head.repo.full_name == github.repository
|
|
84
|
+
|
|
85
|
+
steps:
|
|
86
|
+
- uses: actions/checkout@v4
|
|
87
|
+
- uses: astral-sh/setup-uv@v4
|
|
88
|
+
- uses: google-github-actions/auth@v2
|
|
89
|
+
with:
|
|
90
|
+
credentials_json: ${{ secrets.GCP_SA_KEY }}
|
|
91
|
+
- run: >-
|
|
92
|
+
uv run --extra bigquery pytest -vv
|
|
93
|
+
--with-integration --with-slow-integration
|
|
94
|
+
tests/implementations/bigquery_integration_test.py
|
|
95
|
+
tests/implementations/bigquery_spatial_integration_test.py
|
|
96
|
+
|
|
97
|
+
snowflake:
|
|
98
|
+
name: Snowflake
|
|
99
|
+
runs-on: ubuntu-latest
|
|
100
|
+
if: >-
|
|
101
|
+
github.event_name == 'push'
|
|
102
|
+
|| github.event.pull_request.head.repo.full_name == github.repository
|
|
103
|
+
|
|
104
|
+
steps:
|
|
105
|
+
- uses: actions/checkout@v4
|
|
106
|
+
- uses: astral-sh/setup-uv@v4
|
|
107
|
+
- run: >-
|
|
108
|
+
uv run --extra snowflake pytest -vv
|
|
109
|
+
--with-integration --with-slow-integration
|
|
110
|
+
tests/implementations/snowflake_integration_test.py
|
|
111
|
+
tests/implementations/snowflake_spatial_integration_test.py
|
|
112
|
+
env:
|
|
113
|
+
CANTRIP_SNOWFLAKE_URL: ${{ secrets.SNOWFLAKE_URL }}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Pre-commit checks and unit tests — runs on every PR (including forks).
|
|
2
|
+
# No secrets required.
|
|
3
|
+
|
|
4
|
+
name: PR
|
|
5
|
+
|
|
6
|
+
on:
|
|
7
|
+
pull_request:
|
|
8
|
+
branches: [main]
|
|
9
|
+
push:
|
|
10
|
+
branches: [main]
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
check:
|
|
14
|
+
name: Pre-commit
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
- uses: actions/setup-python@v5
|
|
19
|
+
with:
|
|
20
|
+
python-version: "3.11"
|
|
21
|
+
- uses: pre-commit/action@v3.0.1
|
|
22
|
+
|
|
23
|
+
test:
|
|
24
|
+
name: Unit tests
|
|
25
|
+
runs-on: ubuntu-latest
|
|
26
|
+
steps:
|
|
27
|
+
- uses: actions/checkout@v4
|
|
28
|
+
- uses: astral-sh/setup-uv@v4
|
|
29
|
+
- run: uv run --extra duckdb pytest -vv --cov=src/cantrip --integration-cover tests/
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Build and publish a release when a v* tag is pushed.
|
|
2
|
+
#
|
|
3
|
+
# Usage:
|
|
4
|
+
# git tag v0.1.0
|
|
5
|
+
# git push origin v0.1.0
|
|
6
|
+
#
|
|
7
|
+
# Or trigger manually from the Actions tab.
|
|
8
|
+
|
|
9
|
+
name: Release
|
|
10
|
+
|
|
11
|
+
on:
|
|
12
|
+
push:
|
|
13
|
+
tags:
|
|
14
|
+
- "v*"
|
|
15
|
+
workflow_dispatch:
|
|
16
|
+
inputs:
|
|
17
|
+
tag:
|
|
18
|
+
description: "Tag to release (e.g. v0.1.0)"
|
|
19
|
+
required: true
|
|
20
|
+
|
|
21
|
+
jobs:
|
|
22
|
+
release:
|
|
23
|
+
runs-on: ubuntu-latest
|
|
24
|
+
permissions:
|
|
25
|
+
contents: write
|
|
26
|
+
id-token: write # required for trusted PyPI publishing
|
|
27
|
+
|
|
28
|
+
steps:
|
|
29
|
+
- uses: actions/checkout@v4
|
|
30
|
+
with:
|
|
31
|
+
ref: ${{ inputs.tag || github.ref }}
|
|
32
|
+
|
|
33
|
+
- uses: astral-sh/setup-uv@v4
|
|
34
|
+
|
|
35
|
+
- name: Build package
|
|
36
|
+
run: uv build
|
|
37
|
+
|
|
38
|
+
- name: Create GitHub release
|
|
39
|
+
uses: softprops/action-gh-release@v2
|
|
40
|
+
with:
|
|
41
|
+
tag_name: ${{ inputs.tag || github.ref_name }}
|
|
42
|
+
files: dist/*
|
|
43
|
+
generate_release_notes: true
|
|
44
|
+
|
|
45
|
+
- name: Publish to PyPI
|
|
46
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
cantrip-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
# Linting & formatting with Ruff (includes import sorting via I001)
|
|
3
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
4
|
+
rev: v0.6.9
|
|
5
|
+
hooks:
|
|
6
|
+
- id: ruff
|
|
7
|
+
args: [--fix]
|
|
8
|
+
|
|
9
|
+
# Black for code formatting
|
|
10
|
+
- repo: https://github.com/psf/black
|
|
11
|
+
rev: 23.9.1
|
|
12
|
+
hooks:
|
|
13
|
+
- id: black
|
|
14
|
+
args: [--quiet]
|
|
15
|
+
|
|
16
|
+
# Enforce type checking
|
|
17
|
+
- repo: https://github.com/pre-commit/mirrors-mypy
|
|
18
|
+
rev: v1.11.2
|
|
19
|
+
hooks:
|
|
20
|
+
- id: mypy
|
|
21
|
+
additional_dependencies:
|
|
22
|
+
- types-requests
|
|
23
|
+
- types-python-dateutil
|
|
24
|
+
- types-PyYAML
|
|
25
|
+
- types-tabulate
|
|
26
|
+
|
|
27
|
+
# Upgrade syntax to modern Python
|
|
28
|
+
- repo: https://github.com/asottile/pyupgrade
|
|
29
|
+
rev: v3.17.0
|
|
30
|
+
hooks:
|
|
31
|
+
- id: pyupgrade
|
|
32
|
+
args: [--py39-plus]
|
|
33
|
+
|
|
34
|
+
# Trim trailing whitespace, fix line endings, ensure final newline, and validate data files
|
|
35
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
36
|
+
rev: v5.0.0
|
|
37
|
+
hooks:
|
|
38
|
+
- id: end-of-file-fixer
|
|
39
|
+
- id: trailing-whitespace
|
|
40
|
+
- id: mixed-line-ending
|
|
41
|
+
args: [--fix=auto]
|
|
42
|
+
- id: check-json
|
|
43
|
+
- id: check-xml
|
|
44
|
+
- id: check-yaml
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Contributing to Cantrip
|
|
2
|
+
|
|
3
|
+
Thank you for your interest in contributing! This document explains how to get involved and what to expect.
|
|
4
|
+
|
|
5
|
+
## Contributor License Agreement (CLA)
|
|
6
|
+
|
|
7
|
+
To protect both you and the project, I ask all contributors to sign a Contributor License Agreement before I can merge your work. The CLA lets you keep the copyright to your contribution while granting me the rights needed to distribute and, if necessary, relicense the project.
|
|
8
|
+
|
|
9
|
+
**Individual contributors:** When you open your first pull request, a bot will automatically prompt you to sign the CLA. It takes about a minute — you'll review the agreement and confirm via GitHub.
|
|
10
|
+
|
|
11
|
+
**Corporate contributors (contributing on behalf of your employer):** Please email me at contact@robida.net before opening a pull request so we can arrange signing the Entity CLA. Your employer retains rights to their contributions; I just need the appropriate agreement in place first.
|
|
12
|
+
|
|
13
|
+
## My Licensing Commitment
|
|
14
|
+
|
|
15
|
+
Cantrip is currently licensed under AGPL-3.0. I may relicense it in the future — for example, to MIT or Apache 2.0 — but I commit to the following:
|
|
16
|
+
|
|
17
|
+
> **If I ever relicense Cantrip, it will only become more permissive, never less. I will never take this project fully closed-source.**
|
|
18
|
+
|
|
19
|
+
The CLA's broad outbound license grant exists to give me that flexibility. I appreciate the trust contributors place in me by signing it.
|
|
20
|
+
|
|
21
|
+
## How to Contribute
|
|
22
|
+
|
|
23
|
+
1. Fork the repository and create a branch for your change.
|
|
24
|
+
2. Make your changes, with clear commit messages.
|
|
25
|
+
3. Open a pull request. The CLA bot will guide you through signing if you haven't already.
|
|
26
|
+
4. I'll review your PR and get back to you.
|
|
27
|
+
|
|
28
|
+
## Questions?
|
|
29
|
+
|
|
30
|
+
Feel free to open an issue or reach out at contact@robida.net.
|