warp-commerce-types 1.0.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 (26) hide show
  1. warp_commerce_types-1.0.0/PKG-INFO +147 -0
  2. warp_commerce_types-1.0.0/README.md +123 -0
  3. warp_commerce_types-1.0.0/pyproject.toml +46 -0
  4. warp_commerce_types-1.0.0/setup.cfg +4 -0
  5. warp_commerce_types-1.0.0/src/warp_commerce_types/__init__.py +92 -0
  6. warp_commerce_types-1.0.0/src/warp_commerce_types/_data.py +46 -0
  7. warp_commerce_types-1.0.0/src/warp_commerce_types/_models.py +1486 -0
  8. warp_commerce_types-1.0.0/src/warp_commerce_types/invariants.py +307 -0
  9. warp_commerce_types-1.0.0/src/warp_commerce_types/money.py +184 -0
  10. warp_commerce_types-1.0.0/src/warp_commerce_types/platforms/__init__.py +6 -0
  11. warp_commerce_types-1.0.0/src/warp_commerce_types/platforms/shopify.py +147 -0
  12. warp_commerce_types-1.0.0/src/warp_commerce_types/platforms/stripe.py +101 -0
  13. warp_commerce_types-1.0.0/src/warp_commerce_types/primitives.py +137 -0
  14. warp_commerce_types-1.0.0/src/warp_commerce_types/py.typed +0 -0
  15. warp_commerce_types-1.0.0/src/warp_commerce_types/schema_data/VERSION +1 -0
  16. warp_commerce_types-1.0.0/src/warp_commerce_types/schema_data/invariants.json +196 -0
  17. warp_commerce_types-1.0.0/src/warp_commerce_types/schema_data/transitions.json +39 -0
  18. warp_commerce_types-1.0.0/src/warp_commerce_types/transitions.py +267 -0
  19. warp_commerce_types-1.0.0/src/warp_commerce_types.egg-info/PKG-INFO +147 -0
  20. warp_commerce_types-1.0.0/src/warp_commerce_types.egg-info/SOURCES.txt +24 -0
  21. warp_commerce_types-1.0.0/src/warp_commerce_types.egg-info/dependency_links.txt +1 -0
  22. warp_commerce_types-1.0.0/src/warp_commerce_types.egg-info/requires.txt +6 -0
  23. warp_commerce_types-1.0.0/src/warp_commerce_types.egg-info/top_level.txt +1 -0
  24. warp_commerce_types-1.0.0/tests/test_bug_fixes.py +223 -0
  25. warp_commerce_types-1.0.0/tests/test_invariants.py +136 -0
  26. warp_commerce_types-1.0.0/tests/test_transitions.py +151 -0
@@ -0,0 +1,147 @@
1
+ Metadata-Version: 2.4
2
+ Name: warp-commerce-types
3
+ Version: 1.0.0
4
+ Summary: Formal commerce types generated from the Warp Commerce Model — typed money, validated state transitions, and the six commerce invariants. The Python twin of @warp-lang/commerce-types.
5
+ Author: Lamar Tech
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/yasirlts/warp-lang
8
+ Project-URL: Repository, https://github.com/yasirlts/warp-lang
9
+ Keywords: commerce,ecommerce,types,warp,pydantic,state-machine,formal-methods
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.9
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Typing :: Typed
17
+ Requires-Python: >=3.9
18
+ Description-Content-Type: text/markdown
19
+ Requires-Dist: pydantic>=2
20
+ Provides-Extra: dev
21
+ Requires-Dist: pytest>=7; extra == "dev"
22
+ Requires-Dist: mypy>=1.8; extra == "dev"
23
+ Requires-Dist: build>=1.0; extra == "dev"
24
+
25
+ # warp-commerce-types
26
+
27
+ **Formal commerce types for Python — the twin of [`@warp-lang/commerce-types`](../commerce-types).**
28
+
29
+ Typed money, validated state transitions, and the six commerce invariants of the
30
+ Warp Commerce Model — as Pydantic v2 models. Both this package and the TypeScript
31
+ package are generated from / read the **same canonical schema**
32
+ ([`../../schema`](../../schema)), so the two languages agree *by construction*:
33
+
34
+ - the data shapes come from `schema/structure/*.schema.json`;
35
+ - the legal state-machine edges come from `schema/behavior/transitions.json`;
36
+ - the invariant definitions come from `schema/behavior/invariants.json`.
37
+
38
+ ```bash
39
+ pip install warp-commerce-types
40
+ ```
41
+
42
+ > **Available on PyPI as of v1.0.0.** If you're building from a pre-release
43
+ > checkout (before v1.0.0 is live on PyPI), the line above won't resolve yet —
44
+ > install from source instead:
45
+ >
46
+ > ```bash
47
+ > # from a checkout of the warp-lang repo:
48
+ > pip install ./packages/commerce-types-py
49
+ > # …or editable, with dev deps, for working on the package:
50
+ > pip install -e "./packages/commerce-types-py[dev]"
51
+ > ```
52
+
53
+ ## What you get
54
+
55
+ ```python
56
+ from warp_commerce_types import (
57
+ Money, new_commitment, transition_commitment, audit_commerce, allocate,
58
+ )
59
+
60
+ # Currency-safe money. You cannot add MAD to EUR — and minor units are correct
61
+ # per currency (TND is 3-decimal: 1.5 TND == 1500 millimes, not 150).
62
+ from warp_commerce_types import add, convert
63
+ add(Money(amount=100, currency="MAD"), Money(amount=50, currency="MAD"))
64
+ # add(Money(amount=1, currency="MAD"), Money(amount=1, currency="EUR")) -> CurrencyMismatchError
65
+
66
+ # Exact splits that always reconcile (largest-remainder, minor-unit aware):
67
+ allocate(Money(amount=100, currency="MAD"), [1, 1, 1])
68
+ # -> 33.34 + 33.33 + 33.33 == 100.00 exactly
69
+
70
+ # State machines validate every move against the canonical transition table.
71
+ c = new_commitment("buyer", "seller")
72
+ r = transition_commitment(c, {"type": "Proposed"}, actor="buyer")
73
+ assert r.ok and r.value.state.type == "Proposed"
74
+ bad = transition_commitment(c, {"type": "Fulfilled"}, actor="buyer")
75
+ assert not bad.ok and "Invariant 2" in bad.error # Draft -> Fulfilled is illegal
76
+
77
+ # The six invariants, as runtime checkers that return actionable violations.
78
+ violations = audit_commerce(commitments=[c], fulfillments=[], parties=[])
79
+ ```
80
+
81
+ ## The model
82
+
83
+ Five primitives — **Party, Value, Intent, Commitment, Fulfillment** — plus the
84
+ v0.3 commerce vocabulary (terms, auctions, resolution, metering, evidence, …),
85
+ all generated as Pydantic models with discriminated unions keyed on `"type"` /
86
+ `"kind"`.
87
+
88
+ | Concern | Module |
89
+ |---------|--------|
90
+ | Currency-safe `Money`, minor-unit math, `allocate`, `MoneyBreakdown` | `warp_commerce_types.money` |
91
+ | Primitive constructors (`new_commitment`, `party_id`, …) | `warp_commerce_types.primitives` |
92
+ | `transition_*` / `is_valid_*_transition`, history synthesis | `warp_commerce_types.transitions` |
93
+ | `check_i1..i6`, `audit_commerce`, `check_loyalty_liability` | `warp_commerce_types.invariants` |
94
+ | Generated data models | `warp_commerce_types` (re-exported) |
95
+ | Platform adapters | `warp_commerce_types.platforms.shopify`, `…stripe` |
96
+
97
+ ### The six invariants
98
+
99
+ 1. **Value Conservation** — value is transferred, not created; no mixed currencies
100
+ without explicit conversion. (Fourth clause: loyalty-point liability —
101
+ `check_loyalty_liability`.)
102
+ 2. **State Monotonicity** — only legal transitions; terminal states never reverse.
103
+ 3. **Capacity Verification** — a buyer must be verified (`can_buy`) before Accepted.
104
+ 4. **Temporal Integrity** — commitments form before fulfillments execute;
105
+ append-only history; timestamps never move backward.
106
+ 5. **Identity Permanence** — identifiers are globally unique, never reused.
107
+ 6. **Commitment Tree Consistency** — a parent's value equals the sum of its
108
+ children, within minor-unit tolerance (build exact children with `allocate`).
109
+
110
+ ### `MoneyBreakdown`
111
+
112
+ A total decomposed into labelled components. Construction enforces the
113
+ `money_breakdown_sum` rule from `schema/behavior/invariants.json`: components sum
114
+ to the total (minor-unit tolerance), all share one currency, and discount
115
+ components are negative.
116
+
117
+ ```python
118
+ from warp_commerce_types import MoneyBreakdown
119
+ MoneyBreakdown.model_validate({
120
+ "components": [
121
+ {"kind": "subtotal", "amount": {"amount": 90, "currency": "MAD"}},
122
+ {"kind": "discount", "amount": {"amount": -10, "currency": "MAD"}},
123
+ {"kind": "tax", "amount": {"amount": 20, "currency": "MAD"}},
124
+ ],
125
+ "total": {"amount": 100, "currency": "MAD"},
126
+ }) # ok — components sum to 100
127
+ ```
128
+
129
+ ## Regenerating from the schema
130
+
131
+ The models and the bundled behavior data are generated. Edit the schema, never
132
+ the generated `_models.py`:
133
+
134
+ ```bash
135
+ python scripts/generate_from_schema.py # reads ../../schema, writes src/.../_models.py
136
+ ```
137
+
138
+ ## Development
139
+
140
+ ```bash
141
+ pip install -e ".[dev]"
142
+ pytest # mirrors the TS bug-fix, transition, and invariant suites
143
+ mypy # configured in pyproject.toml
144
+ python -m build
145
+ ```
146
+
147
+ MIT licensed. Part of the [Warp](https://github.com/yasirlts/warp-lang) project.
@@ -0,0 +1,123 @@
1
+ # warp-commerce-types
2
+
3
+ **Formal commerce types for Python — the twin of [`@warp-lang/commerce-types`](../commerce-types).**
4
+
5
+ Typed money, validated state transitions, and the six commerce invariants of the
6
+ Warp Commerce Model — as Pydantic v2 models. Both this package and the TypeScript
7
+ package are generated from / read the **same canonical schema**
8
+ ([`../../schema`](../../schema)), so the two languages agree *by construction*:
9
+
10
+ - the data shapes come from `schema/structure/*.schema.json`;
11
+ - the legal state-machine edges come from `schema/behavior/transitions.json`;
12
+ - the invariant definitions come from `schema/behavior/invariants.json`.
13
+
14
+ ```bash
15
+ pip install warp-commerce-types
16
+ ```
17
+
18
+ > **Available on PyPI as of v1.0.0.** If you're building from a pre-release
19
+ > checkout (before v1.0.0 is live on PyPI), the line above won't resolve yet —
20
+ > install from source instead:
21
+ >
22
+ > ```bash
23
+ > # from a checkout of the warp-lang repo:
24
+ > pip install ./packages/commerce-types-py
25
+ > # …or editable, with dev deps, for working on the package:
26
+ > pip install -e "./packages/commerce-types-py[dev]"
27
+ > ```
28
+
29
+ ## What you get
30
+
31
+ ```python
32
+ from warp_commerce_types import (
33
+ Money, new_commitment, transition_commitment, audit_commerce, allocate,
34
+ )
35
+
36
+ # Currency-safe money. You cannot add MAD to EUR — and minor units are correct
37
+ # per currency (TND is 3-decimal: 1.5 TND == 1500 millimes, not 150).
38
+ from warp_commerce_types import add, convert
39
+ add(Money(amount=100, currency="MAD"), Money(amount=50, currency="MAD"))
40
+ # add(Money(amount=1, currency="MAD"), Money(amount=1, currency="EUR")) -> CurrencyMismatchError
41
+
42
+ # Exact splits that always reconcile (largest-remainder, minor-unit aware):
43
+ allocate(Money(amount=100, currency="MAD"), [1, 1, 1])
44
+ # -> 33.34 + 33.33 + 33.33 == 100.00 exactly
45
+
46
+ # State machines validate every move against the canonical transition table.
47
+ c = new_commitment("buyer", "seller")
48
+ r = transition_commitment(c, {"type": "Proposed"}, actor="buyer")
49
+ assert r.ok and r.value.state.type == "Proposed"
50
+ bad = transition_commitment(c, {"type": "Fulfilled"}, actor="buyer")
51
+ assert not bad.ok and "Invariant 2" in bad.error # Draft -> Fulfilled is illegal
52
+
53
+ # The six invariants, as runtime checkers that return actionable violations.
54
+ violations = audit_commerce(commitments=[c], fulfillments=[], parties=[])
55
+ ```
56
+
57
+ ## The model
58
+
59
+ Five primitives — **Party, Value, Intent, Commitment, Fulfillment** — plus the
60
+ v0.3 commerce vocabulary (terms, auctions, resolution, metering, evidence, …),
61
+ all generated as Pydantic models with discriminated unions keyed on `"type"` /
62
+ `"kind"`.
63
+
64
+ | Concern | Module |
65
+ |---------|--------|
66
+ | Currency-safe `Money`, minor-unit math, `allocate`, `MoneyBreakdown` | `warp_commerce_types.money` |
67
+ | Primitive constructors (`new_commitment`, `party_id`, …) | `warp_commerce_types.primitives` |
68
+ | `transition_*` / `is_valid_*_transition`, history synthesis | `warp_commerce_types.transitions` |
69
+ | `check_i1..i6`, `audit_commerce`, `check_loyalty_liability` | `warp_commerce_types.invariants` |
70
+ | Generated data models | `warp_commerce_types` (re-exported) |
71
+ | Platform adapters | `warp_commerce_types.platforms.shopify`, `…stripe` |
72
+
73
+ ### The six invariants
74
+
75
+ 1. **Value Conservation** — value is transferred, not created; no mixed currencies
76
+ without explicit conversion. (Fourth clause: loyalty-point liability —
77
+ `check_loyalty_liability`.)
78
+ 2. **State Monotonicity** — only legal transitions; terminal states never reverse.
79
+ 3. **Capacity Verification** — a buyer must be verified (`can_buy`) before Accepted.
80
+ 4. **Temporal Integrity** — commitments form before fulfillments execute;
81
+ append-only history; timestamps never move backward.
82
+ 5. **Identity Permanence** — identifiers are globally unique, never reused.
83
+ 6. **Commitment Tree Consistency** — a parent's value equals the sum of its
84
+ children, within minor-unit tolerance (build exact children with `allocate`).
85
+
86
+ ### `MoneyBreakdown`
87
+
88
+ A total decomposed into labelled components. Construction enforces the
89
+ `money_breakdown_sum` rule from `schema/behavior/invariants.json`: components sum
90
+ to the total (minor-unit tolerance), all share one currency, and discount
91
+ components are negative.
92
+
93
+ ```python
94
+ from warp_commerce_types import MoneyBreakdown
95
+ MoneyBreakdown.model_validate({
96
+ "components": [
97
+ {"kind": "subtotal", "amount": {"amount": 90, "currency": "MAD"}},
98
+ {"kind": "discount", "amount": {"amount": -10, "currency": "MAD"}},
99
+ {"kind": "tax", "amount": {"amount": 20, "currency": "MAD"}},
100
+ ],
101
+ "total": {"amount": 100, "currency": "MAD"},
102
+ }) # ok — components sum to 100
103
+ ```
104
+
105
+ ## Regenerating from the schema
106
+
107
+ The models and the bundled behavior data are generated. Edit the schema, never
108
+ the generated `_models.py`:
109
+
110
+ ```bash
111
+ python scripts/generate_from_schema.py # reads ../../schema, writes src/.../_models.py
112
+ ```
113
+
114
+ ## Development
115
+
116
+ ```bash
117
+ pip install -e ".[dev]"
118
+ pytest # mirrors the TS bug-fix, transition, and invariant suites
119
+ mypy # configured in pyproject.toml
120
+ python -m build
121
+ ```
122
+
123
+ MIT licensed. Part of the [Warp](https://github.com/yasirlts/warp-lang) project.
@@ -0,0 +1,46 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "warp-commerce-types"
7
+ version = "1.0.0"
8
+ description = "Formal commerce types generated from the Warp Commerce Model — typed money, validated state transitions, and the six commerce invariants. The Python twin of @warp-lang/commerce-types."
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ license = { text = "MIT" }
12
+ authors = [{ name = "Lamar Tech" }]
13
+ keywords = ["commerce", "ecommerce", "types", "warp", "pydantic", "state-machine", "formal-methods"]
14
+ classifiers = [
15
+ "License :: OSI Approved :: MIT License",
16
+ "Programming Language :: Python :: 3",
17
+ "Programming Language :: Python :: 3.9",
18
+ "Programming Language :: Python :: 3.10",
19
+ "Programming Language :: Python :: 3.11",
20
+ "Programming Language :: Python :: 3.12",
21
+ "Typing :: Typed",
22
+ ]
23
+ dependencies = ["pydantic>=2"]
24
+
25
+ [project.optional-dependencies]
26
+ dev = ["pytest>=7", "mypy>=1.8", "build>=1.0"]
27
+
28
+ [project.urls]
29
+ Homepage = "https://github.com/yasirlts/warp-lang"
30
+ Repository = "https://github.com/yasirlts/warp-lang"
31
+
32
+ [tool.setuptools.packages.find]
33
+ where = ["src"]
34
+
35
+ [tool.setuptools.package-data]
36
+ warp_commerce_types = ["py.typed", "schema_data/*.json", "schema_data/VERSION"]
37
+
38
+ [tool.pytest.ini_options]
39
+ testpaths = ["tests"]
40
+
41
+ [tool.mypy]
42
+ python_version = "3.9"
43
+ plugins = ["pydantic.mypy"]
44
+ packages = ["warp_commerce_types"]
45
+ mypy_path = "src"
46
+ ignore_missing_imports = true
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,92 @@
1
+ """warp-commerce-types — the Python twin of @warp-lang/commerce-types.
2
+
3
+ Formal commerce types generated from the canonical Warp Commerce Model schema
4
+ (schema/structure/*.schema.json) v1.0.0:
5
+ - the five primitives (Party, Value, Intent, Commitment, Fulfillment),
6
+ - currency-safe Money + minor-unit-aware money math and MoneyBreakdown,
7
+ - validated state transitions (the 26-transition commitment table), read from
8
+ schema/behavior/transitions.json — the same data the TS binding reads,
9
+ - runtime checkers for the six commerce invariants.
10
+
11
+ Platform mappings (Shopify, Stripe) are available under
12
+ ``warp_commerce_types.platforms``.
13
+ """
14
+ from __future__ import annotations
15
+
16
+ # Generated data models (objects + discriminated unions) + SCHEMA_VERSION.
17
+ from ._models import * # noqa: F401,F403
18
+ from ._models import SCHEMA_VERSION
19
+
20
+ # Money math.
21
+ from .money import ( # noqa: F401
22
+ CurrencyMismatchError,
23
+ ZERO_DECIMAL_CURRENCIES,
24
+ THREE_DECIMAL_CURRENCIES,
25
+ add,
26
+ allocate,
27
+ compare,
28
+ convert,
29
+ currency_decimals,
30
+ format_money,
31
+ minor_unit_factor,
32
+ money_epsilon,
33
+ money_equals,
34
+ subtract,
35
+ validate_money_breakdown,
36
+ zero,
37
+ )
38
+
39
+ # Primitive constructors.
40
+ from .primitives import ( # noqa: F401
41
+ commitment_id,
42
+ fulfillment_id,
43
+ individual,
44
+ intent_id,
45
+ new_commitment,
46
+ new_fulfillment,
47
+ new_intent,
48
+ now,
49
+ organization,
50
+ party_id,
51
+ system,
52
+ unverified_capacity,
53
+ value_id,
54
+ )
55
+
56
+ # Transitions.
57
+ from .transitions import ( # noqa: F401
58
+ CapacityError,
59
+ InvalidTransitionError,
60
+ Result,
61
+ apply_commitment_path,
62
+ apply_fulfillment_path,
63
+ is_valid_commitment_transition,
64
+ is_valid_fulfillment_transition,
65
+ is_valid_intent_transition,
66
+ transition_commitment,
67
+ transition_fulfillment,
68
+ transition_intent,
69
+ )
70
+
71
+ # Invariants.
72
+ from .invariants import ( # noqa: F401
73
+ InvariantViolation,
74
+ LoyaltyLiabilityCheck,
75
+ audit_commerce,
76
+ audit_commerce_code,
77
+ check_i1_value_conservation,
78
+ check_i2_state_monotonicity,
79
+ check_i3_capacity_verification,
80
+ check_i4_temporal_integrity,
81
+ check_i5_identity_permanence,
82
+ check_i6_tree_consistency,
83
+ check_loyalty_liability,
84
+ verify_invariant1,
85
+ verify_invariant2,
86
+ verify_invariant3,
87
+ verify_invariant4,
88
+ verify_invariant5,
89
+ verify_invariant6,
90
+ )
91
+
92
+ __version__ = SCHEMA_VERSION
@@ -0,0 +1,46 @@
1
+ """Runtime loaders for the canonical behavior data (transition tables and
2
+ invariant definitions).
3
+
4
+ Both the TypeScript and Python bindings read these same JSON files, so they
5
+ agree by construction. In a source checkout we read the canonical files under
6
+ ``schema/behavior`` directly; an installed wheel reads the build-time mirror
7
+ bundled at ``warp_commerce_types/schema_data`` (synced from the canonical files
8
+ by ``scripts/generate_from_schema.py``).
9
+ """
10
+ from __future__ import annotations
11
+
12
+ import json
13
+ from functools import lru_cache
14
+ from pathlib import Path
15
+ from typing import Any, Dict
16
+
17
+ _PKG_DIR = Path(__file__).resolve().parent
18
+ _BUNDLED = _PKG_DIR / "schema_data"
19
+ # In a source checkout: .../warp-lang/packages/commerce-types-py/src/warp_commerce_types
20
+ # parents[3] is the repo root that holds the canonical schema/ directory.
21
+ _CANONICAL = _PKG_DIR.parents[3] / "schema" / "behavior"
22
+
23
+
24
+ def _read(name: str) -> Dict[str, Any]:
25
+ canonical = _CANONICAL / name
26
+ if canonical.is_file():
27
+ return json.loads(canonical.read_text())
28
+ bundled = _BUNDLED / name
29
+ if bundled.is_file():
30
+ return json.loads(bundled.read_text())
31
+ raise FileNotFoundError(
32
+ "behavior file %r not found (looked in %s and %s); "
33
+ "run scripts/generate_from_schema.py" % (name, _CANONICAL, _BUNDLED)
34
+ )
35
+
36
+
37
+ @lru_cache(maxsize=None)
38
+ def transitions() -> Dict[str, Any]:
39
+ """The legal-transition tables (schema/behavior/transitions.json)."""
40
+ return _read("transitions.json")
41
+
42
+
43
+ @lru_cache(maxsize=None)
44
+ def invariants() -> Dict[str, Any]:
45
+ """The invariant definitions + money_breakdown_sum / loyalty rules."""
46
+ return _read("invariants.json")