Run a contract in five minutes.
This quick start shows the ContractForge shape: install the core, add the adapter for your target runtime, validate the contract, then render or execute through the adapter.
1. Install packages
Install the platform-neutral core and the adapter packages you need.
pip install contractforge-core contractforge-databricks contractforge-aws
For local repository development:
uv run pytest
uv build --wheel
cd adapters/databricks
uv build --wheel
cd ../aws
uv build --wheel
On Databricks, install the core and Databricks wheels on the job, cluster, notebook environment or workspace file path. Spark and Delta come from Databricks Runtime; they are not dependencies of the core wheel.
2. Create a minimal ingestion contract
source:
type: table
table: main.raw.orders
system: crm
target:
catalog: main
schema: bronze
table: b_orders
layer: bronze
mode: append
schema_policy: additive_only
quality_rules:
not_null: [order_id]
expressions:
- name: positive_amount
expression: amount >= 0
severity: abort
The canonical target is always nested under target. Source ownership metadata belongs under source.system, not as a top-level field.
3. Validate with the core CLI
contractforge validate contracts/bronze/b_orders.ingestion.yaml
The core validation step checks contract shape, portable semantics and fields that must not leak platform implementation details into the semantic model.
4. Plan or render with an adapter
Use the Databricks adapter when the execution target is Databricks:
from contractforge_databricks import render_databricks_contract
artifacts = render_databricks_contract("contracts/bronze/b_orders.ingestion.yaml")
print(artifacts.status)
print(sorted(artifacts.artifacts))
Rendering produces native Databricks artifacts such as SQL, Python, Asset Bundle fragments and review reports where applicable.
For AWS:
contractforge-aws render contracts/bronze/b_orders.ingestion.yaml --environment environments/prod.aws.yaml
Rendering produces Glue Spark scripts, Glue job definitions, review artifacts, evidence DDL and infrastructure scaffolds.
5. Execute a split-contract bundle on Databricks
from contractforge_databricks import ingest_databricks_bundle
result = ingest_databricks_bundle(
"/Workspace/Shared/contracts/bronze/b_orders",
options={
"catalog": "main",
"schema": "ops",
},
)
display(result)
The bundle path can resolve:
b_orders.ingestion.yaml
b_orders.annotations.yaml
b_orders.operations.yaml
b_orders.access.yaml
b_orders.environment.yaml
Only ingestion is required to move data. The other contracts make catalog metadata, operations, access and environment choices explicit.
6. Inspect evidence
On Databricks, the adapter persists the core evidence model in Delta control tables:
SELECT
status,
target_table,
mode,
source_system,
source_connector,
rows_read,
rows_written,
rows_quarantined,
quality_status,
framework_version,
error_message
FROM main.ops.ctrl_ingestion_runs
ORDER BY started_at_utc DESC
LIMIT 20;
Other adapters must preserve the same evidence concepts, even when their persistence implementation is not Delta.
7. Deploy to AWS Glue
AWS uses an environment contract to select S3 artifact publication, Glue job settings and the Iceberg warehouse:
adapter: aws
artifacts:
uri: s3://contractforge-artifacts/prod/orders/
include_contract_bundle: true
include_normalized_contract: true
parameters:
aws:
iceberg:
warehouse: s3://contractforge-warehouse/prod/
glue_job:
role_arn: arn:aws:iam::123456789012:role/ContractForgeGlueRole
environment.name defaults to dev. Glue version, worker type, worker count,
timeout, retries and bookmark behavior also use documented AWS adapter defaults
unless overridden.
contractforge-aws deploy contracts/bronze/b_orders.ingestion.yaml --environment environments/prod.aws.yaml
The adapter renders artifacts, publishes them to S3 and creates or updates the Glue job. Glue executes native Spark/Iceberg code; it does not parse contract YAML at runtime.
8. Use logical table refs
When a downstream contract reads a table produced by another ContractForge contract, use a neutral ref:
source:
type: table
ref: bronze.b_products_jdbc
Inline SQL can use:
FROM {{ table_ref:silver.s_product_tags }}
Databricks and AWS resolve those refs differently, but the contract intent stays the same.