Python prototype

Install and run the local exchange, validate examples, and inspect its API contracts.

Working draft · Version 0.1 · For review and prototypingView source on GitHub ↗

The Python implementation demonstrates the draft SCDx contract with synthetic import, export, and interprovincial messages. It uses FastAPI, Pydantic, and a local SQLite database. It is a development prototype, with organization-level access and no live government, carrier, port, rail, trucking, or warehouse integration.

Install

Use Python 3.11 or newer from the repository root:

python -m venv .venv
source .venv/bin/activate
python -m pip install '.[dev]'

On Windows, activate the environment with .venv\Scripts\activate instead of the source command.

Validate the synthetic examples and inspect the generated message schema:

scdx validate examples/import.json
scdx validate examples/export.json
scdx validate examples/interprovincial.json
scdx schema

Validation checks the draft profile and cross-field rules. It does not establish the authenticity or legal acceptance of the represented information.

Run an in-process demonstration of all three trade flows without starting a server:

python scripts/demo.py

The demonstration uses a temporary database and tests repeat submission, recipient receipts, and rejection of an unrelated reader for each flow.

Run the local demonstration

scdx serve --demo

The default address is http://127.0.0.1:8000. Interactive API documentation is available at http://127.0.0.1:8000/docs, and /health reports whether demo mode is active. The CLI restricts demo mode to a loopback address.

Demo mode explicitly enables public demonstration credentials, including demo-supplier-key for supplier-demo and demo-importer-key for importer-demo. Use synthetic data only. The credentials identify illustrative roles and confer no real-world authority.

Submit the import example:

curl -i http://127.0.0.1:8000/v1/messages \
  -H 'Content-Type: application/json' \
  -H 'X-API-Key: demo-supplier-key' \
  --data-binary @examples/import.json

The response includes record.exchange_id, record.superseded_by, record.message, record.receipts, and duplicate. The exchange identifier is server-generated. Use that returned UUID in subsequent record URLs.

record.superseded_by is the exchange identifier of the immediate correcting record, or null on the latest revision. Check it before treating a retrieved record as current. Follow successor links until superseded_by is null when you need the latest revision; earlier records remain available as evidence.

API operations

Method and path Behavior
GET /health Public health and prototype-status response.
POST /v1/messages Submit as the authenticated issuer. Returns 201 for a new record or 200 for an identical retry.
GET /v1/messages?limit=50&offset=0 List records visible to the authenticated issuer or recipient. Limit must be 1 to 100; offset must be nonnegative.
GET /v1/messages/{exchange_id} Retrieve one visible record, including its receipts.
POST /v1/messages/{exchange_id}/receipts A named recipient records its own acceptance or rejection. Returns 201 when new or 200 for an identical repeat.

All /v1 operations require X-API-Key. For example, list the demo importer's visible records:

curl http://127.0.0.1:8000/v1/messages \
  -H 'X-API-Key: demo-importer-key'

The receipt request body is:

{"status": "accepted", "detail": "Synthetic message received for local testing"}

Send it to the returned record's receipts URL as a named recipient. Receipt acceptance concerns the message only. The exchange does not change cargo, document, payment, or regulatory state on that basis.

Configuration

Setting Meaning
SCDX_API_KEYS JSON object mapping API key strings to organization IDs. Configured keys must have at least 16 ASCII characters. The service refuses normal startup without configured keys.
SCDX_DATABASE SQLite file path; defaults to var/scdx.sqlite3.
--database CLI database-path override.
--host and --port CLI address overrides; defaults are 127.0.0.1 and 8000.

Do not combine configured credentials with --demo. Keep credentials outside source control. Normal configuration is still a local prototype: it does not add verified onboarding, TLS termination, key rotation, delegated roles, rate limiting, or field-level authorization.

Contracts and verification

The versioned JSON Schema and OpenAPI document are generated from the implementation. Regenerate or check them from the repository root:

python scripts/export_schemas.py
python scripts/export_schemas.py --check
pytest

Tests cover the draft contract, access, repeat submissions, corrections, receipts, and persistence. A passing test suite is evidence about this implementation, not certification of a deployed network. See the core profile for business rules and the roadmap for operational gaps.

Copyright © 2026 Stephen Makonin.