datacontract-faker reads an ODCS v3.1.0 data contract and produces realistic, contract-compliant synthetic data — as a CLI tool or a Python library.
datacontract-faker generate orders.yaml -r 50000 -o data/orders.parquet -f parquet- Strict contract compliance —
minimum,maximum,exclusiveMinimum,exclusiveMaximum,multipleOf,minLength,maxLength,pattern,examples,format, and length-constrained types are all enforced on every row. - Foreign-key integrity — declares from
relationships:are honored across models. Referenced tables are generated first; child rows sample real parent keys. - Nested + array types — recursive
objectfields andarrayitems (including arrays of objects) generate properly typed values. - Reproducible — pin
--seedfor byte-identical output across runs. - Four output formats — JSON, JSONL, CSV, Parquet (via
polars+pyarrow). - Locale-aware — any Faker locale (
en_US,de_DE,ja_JP, …). - Library-first — every component (
ContractParser,SyntheticGenerator,ProviderMapper,Exporter) is independently importable.
pip install datacontract-faker # standard
pipx install datacontract-faker # isolated CLI
poetry add datacontract-faker # poetry projectsRequires Python ≥ 3.11.
Generate synthetic data from a contract.
datacontract-faker generate CONTRACT [OPTIONS]| Option | Short | Default | Description |
|---|---|---|---|
CONTRACT |
— | required | Path to the ODCS contract (YAML), as a positional argument |
--rows INT |
-r |
100 |
Rows to generate per model |
--output PATH |
-o |
— | Output file. Omit to preview in the terminal |
--format |
-f |
json |
csv | json | jsonl | parquet |
--model TEXT |
-m |
all | Generate only this model |
--locale TEXT |
— | en_US |
Faker locale |
--seed INT |
— | — | Seed for reproducible output |
--nullable-ratio FLOAT |
— | 0.1 |
Probability of null for optional fields (0.0–1.0) |
--validate-only |
— | false |
Only validate the contract; skip generation |
--verbose |
-v |
false |
Debug logging to stderr |
When a contract has multiple models and --output is set, each model is written to {stem}_{model}{suffix} — e.g. data.parquet becomes data_orders.parquet, data_customers.parquet.
Render the parsed schema as a table — type, format, flags (PK, req, uniq, →fk_target), examples, and constraints.
datacontract-faker inspect CONTRACT [--nullable-ratio FLOAT]# Preview 10 rows in the terminal
datacontract-faker generate contract.yaml -r 10
# Validate without generating
datacontract-faker generate contract.yaml --validate-only
# 1M rows to Parquet, deterministic
datacontract-faker generate contract.yaml -r 1000000 -o out.parquet -f parquet --seed 42
# Single model, German locale, NDJSON
datacontract-faker generate contract.yaml -m customers --locale de_DE -o cust.jsonl -f jsonl
# Stress-test null handling
datacontract-faker generate contract.yaml --nullable-ratio 0.5Every CLI capability is available as a library. Public exports from the top-level package:
from datacontract_faker import (
ContractParser, ContractValidationError,
SyntheticGenerator,
Exporter, OutputFormat,
FieldSpec, GenerationSchema, QualityRule,
)from pathlib import Path
from datacontract_faker import ContractParser, SyntheticGenerator, Exporter, OutputFormat
schema = ContractParser(nullable_ratio=0.05).load_and_validate(Path("contract.yaml"))
gen = SyntheticGenerator(schema, rows=10_000, seed=42, locale="en_US")
dataframes = gen.generate_all() # dict[str, polars.DataFrame], FK-aware order
exporter = Exporter()
for name, df in dataframes.items():
exporter.export(df, Path(f"output/{name}.parquet"), OutputFormat.PARQUET)generate_all() honors foreign-key relationships: referenced models are generated first and child models sample real parent keys.
df = gen.generate_model("orders") # polars.DataFrame
df = gen.generate_model("orders", fk_pools={"customer_id": ["c1", "c2", "c3"]})schema = ContractParser().parse_string(contract_yaml_str)Override or extend the type-to-provider resolution:
from datacontract_faker.mapper import ProviderMapper
from datacontract_faker import SyntheticGenerator
mapper = ProviderMapper(
logical_format_overrides={
"string:product_sku": lambda f: f.bothify("???-####").upper(),
},
logical_overrides={
"integer": lambda f: f.random_int(min=1000, max=9999),
},
physical_overrides={
"decimal": lambda f: round(f.pyfloat(min_value=1, max_value=500), 2),
},
)
gen = SyntheticGenerator(schema, rows=500, mapper=mapper)| Format | Flag | Extension | Notes |
|---|---|---|---|
| JSON (array) | json |
.json |
Pretty-printed, UTF-8 |
| NDJSON | jsonl |
.jsonl |
One record per line, stream-friendly |
| CSV | csv |
.csv |
UTF-8, no index |
| Apache Parquet | parquet |
.parquet |
Columnar, compressed (recommended for large datasets) |
datacontract-cli for contract validation · Faker for synthetic values · polars + pyarrow for DataFrames and Parquet · rstr for regex-conforming strings · Typer + Rich for the CLI.