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.
Files changed (67) hide show
  1. cantrip-0.1.0/.coveragerc +37 -0
  2. cantrip-0.1.0/.github/workflows/integration.yml +113 -0
  3. cantrip-0.1.0/.github/workflows/pr.yml +29 -0
  4. cantrip-0.1.0/.github/workflows/release.yml +46 -0
  5. cantrip-0.1.0/.gitignore +5 -0
  6. cantrip-0.1.0/.pre-commit-config.yaml +44 -0
  7. cantrip-0.1.0/CONTRIBUTING.md +30 -0
  8. cantrip-0.1.0/LICENSE +661 -0
  9. cantrip-0.1.0/Makefile +19 -0
  10. cantrip-0.1.0/PKG-INFO +462 -0
  11. cantrip-0.1.0/README.md +438 -0
  12. cantrip-0.1.0/docker-compose.yml +20 -0
  13. cantrip-0.1.0/examples/bigquery/tpcds.sql +178 -0
  14. cantrip-0.1.0/examples/duckdb/tpcds.sql +154 -0
  15. cantrip-0.1.0/examples/postgres/tpcds.sql +154 -0
  16. cantrip-0.1.0/examples/snowflake/tpcds.sql +163 -0
  17. cantrip-0.1.0/examples/sqlite/tpcds.sql +160 -0
  18. cantrip-0.1.0/pyproject.toml +52 -0
  19. cantrip-0.1.0/scripts/generate_calendar.py +408 -0
  20. cantrip-0.1.0/scripts/generate_geometries.py +614 -0
  21. cantrip-0.1.0/src/cantrip/__init__.py +0 -0
  22. cantrip-0.1.0/src/cantrip/implementations/__init__.py +0 -0
  23. cantrip-0.1.0/src/cantrip/implementations/base.py +2168 -0
  24. cantrip-0.1.0/src/cantrip/implementations/bigquery.py +463 -0
  25. cantrip-0.1.0/src/cantrip/implementations/duckdb.py +305 -0
  26. cantrip-0.1.0/src/cantrip/implementations/information_schema.py +336 -0
  27. cantrip-0.1.0/src/cantrip/implementations/postgres.py +341 -0
  28. cantrip-0.1.0/src/cantrip/implementations/snowflake.py +468 -0
  29. cantrip-0.1.0/src/cantrip/implementations/sqlite.py +882 -0
  30. cantrip-0.1.0/src/cantrip/models.py +414 -0
  31. cantrip-0.1.0/src/cantrip/protocol.py +111 -0
  32. cantrip-0.1.0/src/cantrip/py.typed +0 -0
  33. cantrip-0.1.0/src/cantrip/toolbox.py +41 -0
  34. cantrip-0.1.0/src/cantrip/transforms.py +75 -0
  35. cantrip-0.1.0/src/cantrip/type_map.py +149 -0
  36. cantrip-0.1.0/tests/__init__.py +0 -0
  37. cantrip-0.1.0/tests/conftest.py +3 -0
  38. cantrip-0.1.0/tests/implementations/__init__.py +0 -0
  39. cantrip-0.1.0/tests/implementations/base_test.py +2897 -0
  40. cantrip-0.1.0/tests/implementations/bigquery_integration_test.py +420 -0
  41. cantrip-0.1.0/tests/implementations/bigquery_spatial_integration_test.py +181 -0
  42. cantrip-0.1.0/tests/implementations/bigquery_test.py +1580 -0
  43. cantrip-0.1.0/tests/implementations/duckdb_integration_test.py +303 -0
  44. cantrip-0.1.0/tests/implementations/duckdb_spatial_integration_test.py +145 -0
  45. cantrip-0.1.0/tests/implementations/duckdb_test.py +620 -0
  46. cantrip-0.1.0/tests/implementations/partition_integration_test.py +196 -0
  47. cantrip-0.1.0/tests/implementations/postgres_integration_test.py +296 -0
  48. cantrip-0.1.0/tests/implementations/postgres_spatial_integration_test.py +185 -0
  49. cantrip-0.1.0/tests/implementations/postgres_test.py +649 -0
  50. cantrip-0.1.0/tests/implementations/snowflake_integration_test.py +274 -0
  51. cantrip-0.1.0/tests/implementations/snowflake_spatial_integration_test.py +158 -0
  52. cantrip-0.1.0/tests/implementations/snowflake_test.py +1063 -0
  53. cantrip-0.1.0/tests/implementations/sqlite_spatial_integration_test.py +219 -0
  54. cantrip-0.1.0/tests/implementations/sqlite_test.py +1611 -0
  55. cantrip-0.1.0/tests/init/bigquery/schema.sql +219 -0
  56. cantrip-0.1.0/tests/init/bigquery/spatial.sql +58 -0
  57. cantrip-0.1.0/tests/init/duckdb/schema.sql +148 -0
  58. cantrip-0.1.0/tests/init/duckdb/spatial.sql +58 -0
  59. cantrip-0.1.0/tests/init/postgres/schema.sql +148 -0
  60. cantrip-0.1.0/tests/init/postgres/spatial.sql +60 -0
  61. cantrip-0.1.0/tests/init/snowflake/schema.sql +206 -0
  62. cantrip-0.1.0/tests/init/snowflake/spatial.sql +89 -0
  63. cantrip-0.1.0/tests/init/sqlite/schema.sql +177 -0
  64. cantrip-0.1.0/tests/init/sqlite/spatial.sql +63 -0
  65. cantrip-0.1.0/tests/models_test.py +373 -0
  66. cantrip-0.1.0/tests/protocol_test.py +60 -0
  67. 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
@@ -0,0 +1,5 @@
1
+ __pycache__
2
+ .coverage
3
+ .python-version
4
+ *.db
5
+ .env
@@ -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.