Skip to main content

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.

Project description

warp-commerce-types

Formal commerce types for Python — the twin of @warp-lang/commerce-types.

Typed money, validated state transitions, and the six commerce invariants of the Warp Commerce Model — as Pydantic v2 models. Both this package and the TypeScript package are generated from / read the same canonical schema (../../schema), so the two languages agree by construction:

  • the data shapes come from schema/structure/*.schema.json;
  • the legal state-machine edges come from schema/behavior/transitions.json;
  • the invariant definitions come from schema/behavior/invariants.json.
pip install warp-commerce-types

Available on PyPI as of v1.0.0. If you're building from a pre-release checkout (before v1.0.0 is live on PyPI), the line above won't resolve yet — install from source instead:

# from a checkout of the warp-lang repo:
pip install ./packages/commerce-types-py
# …or editable, with dev deps, for working on the package:
pip install -e "./packages/commerce-types-py[dev]"

What you get

from warp_commerce_types import (
    Money, new_commitment, transition_commitment, audit_commerce, allocate,
)

# Currency-safe money. You cannot add MAD to EUR — and minor units are correct
# per currency (TND is 3-decimal: 1.5 TND == 1500 millimes, not 150).
from warp_commerce_types import add, convert
add(Money(amount=100, currency="MAD"), Money(amount=50, currency="MAD"))
# add(Money(amount=1, currency="MAD"), Money(amount=1, currency="EUR"))  -> CurrencyMismatchError

# Exact splits that always reconcile (largest-remainder, minor-unit aware):
allocate(Money(amount=100, currency="MAD"), [1, 1, 1])
# -> 33.34 + 33.33 + 33.33 == 100.00 exactly

# State machines validate every move against the canonical transition table.
c = new_commitment("buyer", "seller")
r = transition_commitment(c, {"type": "Proposed"}, actor="buyer")
assert r.ok and r.value.state.type == "Proposed"
bad = transition_commitment(c, {"type": "Fulfilled"}, actor="buyer")
assert not bad.ok and "Invariant 2" in bad.error   # Draft -> Fulfilled is illegal

# The six invariants, as runtime checkers that return actionable violations.
violations = audit_commerce(commitments=[c], fulfillments=[], parties=[])

The model

Five primitives — Party, Value, Intent, Commitment, Fulfillment — plus the v0.3 commerce vocabulary (terms, auctions, resolution, metering, evidence, …), all generated as Pydantic models with discriminated unions keyed on "type" / "kind".

Concern Module
Currency-safe Money, minor-unit math, allocate, MoneyBreakdown warp_commerce_types.money
Primitive constructors (new_commitment, party_id, …) warp_commerce_types.primitives
transition_* / is_valid_*_transition, history synthesis warp_commerce_types.transitions
check_i1..i6, audit_commerce, check_loyalty_liability warp_commerce_types.invariants
Generated data models warp_commerce_types (re-exported)
Platform adapters warp_commerce_types.platforms.shopify, …stripe

The six invariants

  1. Value Conservation — value is transferred, not created; no mixed currencies without explicit conversion. (Fourth clause: loyalty-point liability — check_loyalty_liability.)
  2. State Monotonicity — only legal transitions; terminal states never reverse.
  3. Capacity Verification — a buyer must be verified (can_buy) before Accepted.
  4. Temporal Integrity — commitments form before fulfillments execute; append-only history; timestamps never move backward.
  5. Identity Permanence — identifiers are globally unique, never reused.
  6. Commitment Tree Consistency — a parent's value equals the sum of its children, within minor-unit tolerance (build exact children with allocate).

MoneyBreakdown

A total decomposed into labelled components. Construction enforces the money_breakdown_sum rule from schema/behavior/invariants.json: components sum to the total (minor-unit tolerance), all share one currency, and discount components are negative.

from warp_commerce_types import MoneyBreakdown
MoneyBreakdown.model_validate({
    "components": [
        {"kind": "subtotal", "amount": {"amount": 90, "currency": "MAD"}},
        {"kind": "discount", "amount": {"amount": -10, "currency": "MAD"}},
        {"kind": "tax",      "amount": {"amount": 20, "currency": "MAD"}},
    ],
    "total": {"amount": 100, "currency": "MAD"},
})  # ok — components sum to 100

Regenerating from the schema

The models and the bundled behavior data are generated. Edit the schema, never the generated _models.py:

python scripts/generate_from_schema.py   # reads ../../schema, writes src/.../_models.py

Development

pip install -e ".[dev]"
pytest        # mirrors the TS bug-fix, transition, and invariant suites
mypy          # configured in pyproject.toml
python -m build

MIT licensed. Part of the Warp project.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

warp_commerce_types-1.0.0.tar.gz (39.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

warp_commerce_types-1.0.0-py3-none-any.whl (38.9 kB view details)

Uploaded Python 3

File details

Details for the file warp_commerce_types-1.0.0.tar.gz.

File metadata

  • Download URL: warp_commerce_types-1.0.0.tar.gz
  • Upload date:
  • Size: 39.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for warp_commerce_types-1.0.0.tar.gz
Algorithm Hash digest
SHA256 c42c7280376ec996cb15c1d2d5ef3336ad0df45fd8aeb3c6ceda81dccfe27ea0
MD5 ad088c2b40918f49257d778363006f27
BLAKE2b-256 b39a1ba05485376d12eb47b1fa718d86aa96a71e8fad836ebc2cc68fb02977a2

See more details on using hashes here.

File details

Details for the file warp_commerce_types-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for warp_commerce_types-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 69747f64ea7eea2bf19b04ee43dd70b41ea27029eb04357c0c57671e0f1b6d6f
MD5 9fa04c776c041ff1845acbc9aa1bb32a
BLAKE2b-256 024b468295434b6e8b28875041a22018a3cd818da4fc360a499093c82d96c7bf

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page