contractgate 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.
@@ -0,0 +1,25 @@
1
+ # Rust
2
+ target/
3
+
4
+ # Environment
5
+ .env
6
+ .env.local
7
+
8
+ # Node / Next.js
9
+ dashboard/node_modules/
10
+ dashboard/.next/
11
+ dashboard/out/
12
+ dashboard/.env.local
13
+ dashboard/.env
14
+
15
+ # OS
16
+ .DS_Store
17
+ *.swp
18
+ *.swo
19
+
20
+ # Editor
21
+ .vscode/
22
+ .idea/
23
+ dashboard/tsconfig.tsbuildinfo
24
+ # Added by code-review-graph
25
+ .code-review-graph/
@@ -0,0 +1,14 @@
1
+ # Changelog
2
+
3
+ All notable changes to the `contractgate` Python SDK.
4
+
5
+ ## 0.1.0 — 2026-04-26 (unreleased)
6
+
7
+ Initial scaffold per RFC-005.
8
+
9
+ - `Client` (sync) + `AsyncClient` (async) over httpx.
10
+ - `ingest`, `audit`, `get_contract`, `get_version`, `playground`.
11
+ - Local validator (`Contract.from_yaml`, `CompiledContract.validate`).
12
+ - Strict parity with Rust validator: same `ViolationKind`, same field
13
+ paths, same message text. Locked via shared fixture corpus.
14
+ - No PII transforms in the local validator (RFC-004 invariant).
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 ContractGate
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.
@@ -0,0 +1,118 @@
1
+ Metadata-Version: 2.4
2
+ Name: contractgate
3
+ Version: 0.1.0
4
+ Summary: Python SDK for ContractGate — high-performance semantic contract enforcement gateway.
5
+ Project-URL: Homepage, https://contractgate.dev
6
+ Project-URL: Source, https://github.com/contractgate/contractgate
7
+ Author: ContractGate
8
+ License: MIT
9
+ License-File: LICENSE
10
+ Keywords: contract,data-quality,ingestion,schema,validation
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.9
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Topic :: Software Development :: Libraries
20
+ Requires-Python: >=3.9
21
+ Requires-Dist: httpx<1.0,>=0.25
22
+ Requires-Dist: pyyaml>=6.0
23
+ Provides-Extra: dev
24
+ Requires-Dist: mypy>=1.8; extra == 'dev'
25
+ Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
26
+ Requires-Dist: pytest-httpx>=0.30; extra == 'dev'
27
+ Requires-Dist: pytest>=8.0; extra == 'dev'
28
+ Requires-Dist: ruff>=0.5; extra == 'dev'
29
+ Description-Content-Type: text/markdown
30
+
31
+ # contractgate (Python SDK)
32
+
33
+ First-party Python SDK for [ContractGate][gw] — a high-performance
34
+ semantic contract enforcement gateway (Patent Pending).
35
+
36
+ [gw]: https://contractgate.dev
37
+
38
+ ## Install
39
+
40
+ ```bash
41
+ pip install contractgate
42
+ ```
43
+
44
+ Python 3.9+. Runtime deps: `httpx`, `PyYAML`.
45
+
46
+ ## Quickstart — HTTP client
47
+
48
+ ```python
49
+ from contractgate import Client
50
+
51
+ cg = Client(base_url="https://gw.example.com", api_key="cg_live_...")
52
+
53
+ result = cg.ingest(
54
+ contract_id="11111111-1111-1111-1111-111111111111",
55
+ events=[
56
+ {"user_id": "alice_01", "event_type": "click", "timestamp": 1712000000},
57
+ ],
58
+ )
59
+
60
+ print(result.passed, "/", result.total, "events passed")
61
+ for r in result.results:
62
+ if not r.passed:
63
+ for v in r.violations:
64
+ print(v.field, v.kind, v.message)
65
+ ```
66
+
67
+ Async equivalent:
68
+
69
+ ```python
70
+ import asyncio
71
+ from contractgate import AsyncClient
72
+
73
+ async def main():
74
+ async with AsyncClient(base_url="...", api_key="...") as cg:
75
+ result = await cg.ingest(contract_id="...", events=[...])
76
+
77
+ asyncio.run(main())
78
+ ```
79
+
80
+ ## Quickstart — local validator
81
+
82
+ Pure-Python port of the Rust validator. Useful in unit tests and
83
+ pre-commit hooks:
84
+
85
+ ```python
86
+ from contractgate import Contract
87
+
88
+ contract = Contract.from_yaml(open("user_events.yaml").read())
89
+ compiled = contract.compile()
90
+
91
+ vr = compiled.validate({
92
+ "user_id": "alice_01",
93
+ "event_type": "click",
94
+ "timestamp": 1712000000,
95
+ })
96
+ assert vr.passed, vr.violations
97
+ ```
98
+
99
+ ## Caveats
100
+
101
+ - **Local validator does not run RFC-004 PII transforms** (`mask`,
102
+ `hash`, `drop`, `redact`). The per-contract salt is server-side
103
+ only. The gateway is the single source of truth for the
104
+ post-transform payload — read it from each per-event result's
105
+ `transformed_event` field.
106
+ - **Audit honesty**: every per-event result carries the
107
+ `contract_version` that *actually matched* the event (relevant
108
+ under `multi_stable_resolution: fallback`). Surface it as-is — do
109
+ not substitute the requested version.
110
+ - **Retries are off by default.** Layer `httpx.HTTPTransport(retries=)`
111
+ or `tenacity` if you need them. Avoid client-side retry on ingest
112
+ to prevent double-write; use the gateway's quarantine replay
113
+ endpoint instead.
114
+ - `httpx` is pinned `>=0.25,<1.0`; we'll widen once 1.x ships.
115
+
116
+ ## License
117
+
118
+ MIT. See [`LICENSE`](LICENSE).
@@ -0,0 +1,88 @@
1
+ # contractgate (Python SDK)
2
+
3
+ First-party Python SDK for [ContractGate][gw] — a high-performance
4
+ semantic contract enforcement gateway (Patent Pending).
5
+
6
+ [gw]: https://contractgate.dev
7
+
8
+ ## Install
9
+
10
+ ```bash
11
+ pip install contractgate
12
+ ```
13
+
14
+ Python 3.9+. Runtime deps: `httpx`, `PyYAML`.
15
+
16
+ ## Quickstart — HTTP client
17
+
18
+ ```python
19
+ from contractgate import Client
20
+
21
+ cg = Client(base_url="https://gw.example.com", api_key="cg_live_...")
22
+
23
+ result = cg.ingest(
24
+ contract_id="11111111-1111-1111-1111-111111111111",
25
+ events=[
26
+ {"user_id": "alice_01", "event_type": "click", "timestamp": 1712000000},
27
+ ],
28
+ )
29
+
30
+ print(result.passed, "/", result.total, "events passed")
31
+ for r in result.results:
32
+ if not r.passed:
33
+ for v in r.violations:
34
+ print(v.field, v.kind, v.message)
35
+ ```
36
+
37
+ Async equivalent:
38
+
39
+ ```python
40
+ import asyncio
41
+ from contractgate import AsyncClient
42
+
43
+ async def main():
44
+ async with AsyncClient(base_url="...", api_key="...") as cg:
45
+ result = await cg.ingest(contract_id="...", events=[...])
46
+
47
+ asyncio.run(main())
48
+ ```
49
+
50
+ ## Quickstart — local validator
51
+
52
+ Pure-Python port of the Rust validator. Useful in unit tests and
53
+ pre-commit hooks:
54
+
55
+ ```python
56
+ from contractgate import Contract
57
+
58
+ contract = Contract.from_yaml(open("user_events.yaml").read())
59
+ compiled = contract.compile()
60
+
61
+ vr = compiled.validate({
62
+ "user_id": "alice_01",
63
+ "event_type": "click",
64
+ "timestamp": 1712000000,
65
+ })
66
+ assert vr.passed, vr.violations
67
+ ```
68
+
69
+ ## Caveats
70
+
71
+ - **Local validator does not run RFC-004 PII transforms** (`mask`,
72
+ `hash`, `drop`, `redact`). The per-contract salt is server-side
73
+ only. The gateway is the single source of truth for the
74
+ post-transform payload — read it from each per-event result's
75
+ `transformed_event` field.
76
+ - **Audit honesty**: every per-event result carries the
77
+ `contract_version` that *actually matched* the event (relevant
78
+ under `multi_stable_resolution: fallback`). Surface it as-is — do
79
+ not substitute the requested version.
80
+ - **Retries are off by default.** Layer `httpx.HTTPTransport(retries=)`
81
+ or `tenacity` if you need them. Avoid client-side retry on ingest
82
+ to prevent double-write; use the gateway's quarantine replay
83
+ endpoint instead.
84
+ - `httpx` is pinned `>=0.25,<1.0`; we'll widen once 1.x ships.
85
+
86
+ ## License
87
+
88
+ MIT. See [`LICENSE`](LICENSE).
File without changes
@@ -0,0 +1,52 @@
1
+ [build-system]
2
+ requires = ["hatchling>=1.18"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "contractgate"
7
+ version = "0.1.0"
8
+ description = "Python SDK for ContractGate — high-performance semantic contract enforcement gateway."
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ license = { text = "MIT" }
12
+ authors = [{ name = "ContractGate" }]
13
+ keywords = ["contract", "validation", "data-quality", "ingestion", "schema"]
14
+ classifiers = [
15
+ "Development Status :: 3 - Alpha",
16
+ "Intended Audience :: Developers",
17
+ "License :: OSI Approved :: MIT License",
18
+ "Programming Language :: Python :: 3",
19
+ "Programming Language :: Python :: 3.9",
20
+ "Programming Language :: Python :: 3.10",
21
+ "Programming Language :: Python :: 3.11",
22
+ "Programming Language :: Python :: 3.12",
23
+ "Topic :: Software Development :: Libraries",
24
+ ]
25
+ dependencies = [
26
+ "httpx>=0.25,<1.0",
27
+ "PyYAML>=6.0",
28
+ ]
29
+
30
+ [project.optional-dependencies]
31
+ dev = [
32
+ "pytest>=8.0",
33
+ "pytest-asyncio>=0.23",
34
+ "pytest-httpx>=0.30",
35
+ "mypy>=1.8",
36
+ "ruff>=0.5",
37
+ ]
38
+
39
+ [project.urls]
40
+ Homepage = "https://contractgate.dev"
41
+ Source = "https://github.com/contractgate/contractgate"
42
+
43
+ [tool.hatch.build.targets.wheel]
44
+ packages = ["src/contractgate"]
45
+
46
+ [tool.pytest.ini_options]
47
+ asyncio_mode = "auto"
48
+ testpaths = ["tests"]
49
+
50
+ [tool.ruff]
51
+ line-length = 100
52
+ target-version = "py39"
@@ -0,0 +1,107 @@
1
+ """ContractGate Python SDK.
2
+
3
+ First-party client and pure-Python validator for the ContractGate
4
+ semantic contract enforcement gateway.
5
+
6
+ Public surface:
7
+ Client, AsyncClient -- HTTP clients (sync, async)
8
+ Contract, CompiledContract -- local contract parse + compile
9
+ FieldDefinition, FieldType -- ontology types
10
+ MetricDefinition, MetricType -- metric types
11
+ Transform, TransformKind, -- RFC-004 declarations (declared, not run)
12
+ MaskStyle
13
+ ValidationResult, Violation, -- validator outputs
14
+ ViolationKind
15
+ BatchIngestResponse, -- HTTP response shapes
16
+ IngestEventResult,
17
+ AuditEntry, ContractResponse,
18
+ VersionResponse, VersionSummary,
19
+ IngestionStats
20
+ ContractGateError, HTTPError, -- error hierarchy
21
+ BadRequestError, AuthError,
22
+ NotFoundError, ConflictError,
23
+ ValidationFailedError,
24
+ ServerError, ConnectionError,
25
+ ContractCompileError
26
+
27
+ See README.md for usage. See ../docs/rfcs/005-python-sdk.md for the
28
+ design rationale.
29
+ """
30
+
31
+ from contractgate._version import __version__
32
+ from contractgate.async_client import AsyncClient
33
+ from contractgate.client import Client
34
+ from contractgate.contract import (
35
+ CompiledContract,
36
+ Contract,
37
+ FieldDefinition,
38
+ FieldType,
39
+ MaskStyle,
40
+ MetricDefinition,
41
+ MetricType,
42
+ Transform,
43
+ TransformKind,
44
+ )
45
+ from contractgate.exceptions import (
46
+ AuthError,
47
+ BadRequestError,
48
+ ConflictError,
49
+ ConnectionError,
50
+ ContractCompileError,
51
+ ContractGateError,
52
+ HTTPError,
53
+ NotFoundError,
54
+ ServerError,
55
+ ValidationFailedError,
56
+ )
57
+ from contractgate.models import (
58
+ AuditEntry,
59
+ BatchIngestResponse,
60
+ ContractResponse,
61
+ IngestEventResult,
62
+ IngestionStats,
63
+ ValidationResult,
64
+ VersionResponse,
65
+ VersionSummary,
66
+ Violation,
67
+ ViolationKind,
68
+ )
69
+
70
+ __all__ = [
71
+ "__version__",
72
+ # Clients
73
+ "Client",
74
+ "AsyncClient",
75
+ # Contract / validator
76
+ "Contract",
77
+ "CompiledContract",
78
+ "FieldDefinition",
79
+ "FieldType",
80
+ "MetricDefinition",
81
+ "MetricType",
82
+ "Transform",
83
+ "TransformKind",
84
+ "MaskStyle",
85
+ # Models
86
+ "ValidationResult",
87
+ "Violation",
88
+ "ViolationKind",
89
+ "BatchIngestResponse",
90
+ "IngestEventResult",
91
+ "AuditEntry",
92
+ "ContractResponse",
93
+ "VersionResponse",
94
+ "VersionSummary",
95
+ "IngestionStats",
96
+ # Errors
97
+ "ContractGateError",
98
+ "HTTPError",
99
+ "BadRequestError",
100
+ "AuthError",
101
+ "NotFoundError",
102
+ "ConflictError",
103
+ "ValidationFailedError",
104
+ "ServerError",
105
+ "ConnectionError",
106
+ "ContractCompileError",
107
+ ]