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.