Skip to content

Python API reference

Package: dtcs on PyPI. Source: python/dtcs/__init__.py.

CLI JSON shapes in json-output.md use the same camelCase keys as Python dicts.

Install

pip install 'dtcs==0.13.0'
import dtcs
print(dtcs.__version__)   # package version, e.g. "0.13.0"
print(dtcs.SPEC_VERSION)  # "3.0.0"

Errors and validity

Most APIs return dicts that may include a diagnostics list (and sometimes other fields). They do not raise for validation failures.

Helper Behavior
is_valid(report) True when no diagnostic has error severity. Missing severity is treated as an error.
report = dtcs.parse_and_validate(yaml_bytes)
if not dtcs.is_valid(report):
    for d in report["diagnostics"]:
        print(d["severity"], d["id"], d["message"])

analyze returns nested reports — check each:

result = dtcs.analyze(contract)
assert dtcs.is_valid(result["validation"])
assert dtcs.is_valid(result["analysis"])

Parse and validate

Function Arguments Returns
parse(content, format="yaml") bytes/str, format yaml|json {contract, report: {diagnostics}}
parse_file(path) filesystem path {contract, report: {diagnostics}}
validate(contract, registry_path=None) COM dict {diagnostics}
validate_with_registry(contract, registry_path) COM dict + vendor registry path {diagnostics}
parse_and_validate(content, format="yaml") document bytes {diagnostics}
validate_result(result, registry_path=None) parse result dict {diagnostics}
is_valid(report) any report-like dict with diagnostics bool

Example

import urllib.request
import dtcs

url = "https://raw.githubusercontent.com/eddiethedean/dtcs/main/examples/minimal.dtcs.yaml"
content = urllib.request.urlopen(url).read()
report = dtcs.parse_and_validate(content)
assert dtcs.is_valid(report)
contract = dtcs.parse(content)["contract"]
assert contract["dtcsVersion"] == "3.0.0"

Analysis and planning

Function Returns (typical)
analyze(contract, registry_path=None) {validation, analysis} (each has diagnostics)
plan_lower(contract, registry_path=None) {plan, diagnostics}
plan_validate(plan, registry_path=None) {diagnostics}
plan_optimize(plan, registry_path=None, *, validate=True) {plan, diagnostics}
plan_equivalent(before, after) bool
plan_topological_order(contract, plan) ordered node id list
metadata_validate(contract) / version_validate(contract) focused {diagnostics} reports

Compatibility and lineage

Function Notes
compat_analyze(source, target, scope=None) classification of target vs source
evolve_analyze(older, newer) same-identity revision analysis
lineage_analyze(contract, impact=None, dependency=None) dataset lineage
inspect(contract) human-readable string summary (not a dict)

Registry

Function Notes
registry_list(registry_path=None) entry list
registry_resolve(id, registry_path=None) single entry or None
registry_load(path) load document

Execution pipeline

Function Notes
capability_reference_profile() embedded dtcs:reference
capability_match(plan, profile=None) {supported, diagnostics, …}
compile_plan(plan) {plan, diagnostics} execution plan
execution_validate(plan) {diagnostics}
runtime_execute(execution_plan, inputs) {outputs, diagnostics}

inputs map interface id → list of row dicts. Cell values may be JSON null, or {"$dtcs":"missing"} / {"$dtcs":"invalid"}. Do not coerce missing/invalid to None. Fixture dialect note: expressions.md.

Pip-only run (no clone): wheels do not include examples/ or tests/. Paste a tiny contract and input inline:

import dtcs

yaml = b"""
dtcsVersion: "3.0.0"
id: "demo.hello"
name: "Hello Run"
version: "0.1.0"
metadata:
  description: "pip-only run demo"
  classification: internal
  governance: { owner: "docs", steward: "docs" }
  provenance: { author: "docs", createdAt: "2026-01-01T00:00:00Z" }
inputs:
  - id: "people"
    schema:
      fields:
        - { name: "name", type: "string", nullable: false }
outputs:
  - id: "people_out"
    schema:
      fields:
        - { name: "name", type: "string", nullable: false }
semanticActions:
  - { id: "lower_name", action: "dtcs:lowercase", target: "people.name" }
lineage:
  mappings:
    - { output: "people_out", inputs: ["people"] }
"""
contract = dtcs.parse(yaml)["contract"]
plan = dtcs.plan_lower(contract)["plan"]
compiled = dtcs.compile_plan(plan)["plan"]
result = dtcs.runtime_execute(compiled, {"people": [{"name": "Ada"}, {"name": "Grace"}]})
assert dtcs.is_valid(result)
assert result["outputs"]["people_out"][0]["name"] == "ada"

After cloning the repo, you can also parse_file("examples/customer_pipeline.dtcs.yaml") with fixtures under tests/fixtures/runtime/.

Signatures and __all__: see python/dtcs/__init__.py (source of truth until py.typed ships).

Portable plans

Function Arguments Returns
plan_export_portable(plan, profile=...) lowered plan dict; default profile dtcs:profile/portable-relational-kernel/2 portable plan dict (planIdentity, nodes, …)
plan_fingerprint(portable_plan) portable plan dict SHA-256 hex string
expression_to_structured(source) expression source string structured AST dict
capability_portable_manifest(profile=...) portable profile id per-entry capability manifest
import dtcs

contract = dtcs.parse_file("contract.dtcs.yaml")["contract"]
plan = dtcs.plan_lower(contract)["plan"]
portable = dtcs.plan_export_portable(plan)
fp = dtcs.plan_fingerprint(portable)
manifest = dtcs.capability_portable_manifest()
assert portable["planIdentity"] == "dtcs.transform-plan/2"
assert isinstance(fp, str) and len(fp) == 64

The Rust and Python CLIs expose the same export as dtcs export-portable (also python -m dtcs export-portable).

Conformance

Function Notes
conformance_declare(profile=None) Ch 23 capability declaration
conformance_run(profile=None) offline report (None/"all" runs every profile). Fixtures are embedded in the wheel; optional DTCS_FIXTURES overrides the on-disk search path.

Typing

The wheel does not yet ship py.typed / .pyi stubs. Treat return values as JSON-compatible dicts/lists (except inspect, which returns str). Longer-term: TypedDicts or published JSON Schema for envelopes (json-output.md).

Raises vs diagnostics

Most APIs return diagnostic dicts and do not raise for invalid contracts. Exceptions typically indicate programmer error (e.g. None where a contract dict is required) or I/O failures. See error-taxonomy.md.

See also