Skip to main content

Template-driven synthetic data generation engine.

Project description

pysynthgen

Template-driven synthetic data generation engine.

pysynthgen takes a validated JSON template describing a dataset and yields synthetic rows as an Iterator[dict], writing them to a configurable sink (JSON, CSV, Parquet, or Avro).

Design

  • Engine is standalone and dependency-light. It takes a validated template and returns an iterator of rows; the heavy format dependencies are optional extras.
  • Templates are validated with Pydantic, not raw dict parsing. Each field type is its own model in a discriminated union keyed on type, so validation is type-specific and mistakes are caught up front.
  • Generation is seeded and reproducible. A single seed at the template level drives all randomness (numeric, Faker, regex), so a run is byte-for-byte repeatable.
  • Streaming = chunked generation. The engine exposes iter_rows() and iter_batches(batch_size); the consumer (a sink or a file writer) decides how to persist batches.
  • Relationships are out of scope for now but the schema is shaped to grow into multi-table generation without a rewrite (a future entities: {name: template} wrapper, and cross-table reference fields).

Template format

{
  "row_count": 100000,
  "seed": 42,
  "fields": [
    {"name": "user_id", "type": "uuid"},
    {"name": "signup_date", "type": "date", "start": "2023-01-01", "end": "2026-01-01"},
    {"name": "age", "type": "int", "distribution": "normal", "mean": 35, "stddev": 10, "min": 18},
    {"name": "country", "type": "category", "values": ["US", "NL", "DE"], "weights": [0.5, 0.3, 0.2]},
    {"name": "email", "type": "faker", "provider": "email"},
    {"name": "sku", "type": "regex", "pattern": "[A-Z]{3}-\\d{4}"},
    {"name": "referrer_id", "type": "reference", "field": "user_id", "null_probability": 0.7}
  ],
  "constraints": [
    {"type": "unique", "fields": ["user_id"]}
  ]
}

Field types

type Produces Key params
uuid UUIDv4 string
date date between bounds start, end
datetime datetime between bounds start, end
int integer distribution (uniform/normal), min/max or mean/stddev
float float same as int
category value from a set values, optional weights (sum to 1)
faker Faker output provider (e.g. email), optional max_length
regex string matching a pattern pattern, optional max_length
reference copy of an earlier field in the same row field

String-producing fields (faker, regex) accept an optional max_length that truncates the generated value. For regex, truncation may break the pattern match.

Every field also accepts null_probability (0–1): the chance of emitting null for that field on a given row.

Constraints

  • unique — the listed field(s) form a unique key across generated rows.

Usage

from pysynthgen import load_and_validate_template, SynthEngine, build_sink

spec = load_and_validate_template("template.json")
engine = SynthEngine(spec)

# iterate rows directly
for row in engine.iter_rows():
    ...

# or write the whole dataset to a sink in one call (batches internally)
sink = build_sink("parquet", "out.parquet")
path = sink.write(engine.iter_rows())  # -> "out.parquet"

# for finer control, drive the batches yourself
sink = build_sink("parquet", "out.parquet")
for batch in engine.iter_batches(batch_size=10_000):
    sink.write_batch(batch)
path = sink.finalize()

Command line:

python -m pysynthgen template.json                     # validate + echo the normalized spec
python -m pysynthgen template.json --rows 20           # print 20 sample rows as JSON
python -m pysynthgen template.json --out data.parquet  # generate full dataset to a file
python -m pysynthgen template.json --out data --format avro

Sinks

A sink consumes rows in batches and writes one output artifact. All sinks implement write_batch(rows) / finalize() -> path, and build_sink(format, path) selects one by name.

format extension dependency
json .json stdlib (streamed JSON array)
csv .csv stdlib (delimiter/quotechar configurable)
parquet .parquet, .pq pyarrowpysynthgen[parquet]
avro .avro fastavropysynthgen[avro]

Notes: parquet/avro infer their schema from the first batch with all columns nullable; avro writes naive datetimes as UTC so output is deterministic across machines. Install both format deps with pysynthgen[all].

Benchmarks

benchmarks/bench_sinks.py streams a wide dataset into each sink format and reports throughput, output size, and peak resident memory sampled while writing. Because the engine yields rows lazily and sinks write in batches, memory stays flat as row count grows — a multi-GB file is written with tens of MB of RSS.

python benchmarks/bench_sinks.py --rows 200000          # quick pass
python benchmarks/bench_sinks.py --rows 10000000        # full ~10M-row target (slow, multi-GB)
python benchmarks/bench_sinks.py --rows 1000000 --formats parquet avro --keep

Development

This repo uses uv:

uv venv
uv pip install -e ".[dev]"
uv run pytest        # tests
uv run ruff check .  # lint
uv run mypy src      # types

Status

  • ✅ Template schema + loader (Pydantic, validated)
  • ✅ Generation engine — generators + SynthEngine
  • ✅ File sinks — json, csv, parquet, avro
  • ⬜ More sinks (DB table, Kafka)
  • ⬜ Multi-table / linked-entity generation

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pysynthgen-0.1.1.tar.gz (22.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pysynthgen-0.1.1-py3-none-any.whl (20.5 kB view details)

Uploaded Python 3

File details

Details for the file pysynthgen-0.1.1.tar.gz.

File metadata

  • Download URL: pysynthgen-0.1.1.tar.gz
  • Upload date:
  • Size: 22.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"22.04","id":"jammy","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for pysynthgen-0.1.1.tar.gz
Algorithm Hash digest
SHA256 a6f1d01f8397fef62b828e7abf9d61ee16ef519662f71d6cfa904e2b867ac60d
MD5 0f7605508262438a21cc07d51f60c7d7
BLAKE2b-256 96364459a9fbed838e242b168678eb762a328932bb621c9472b5b837581d0eb6

See more details on using hashes here.

File details

Details for the file pysynthgen-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: pysynthgen-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 20.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"22.04","id":"jammy","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for pysynthgen-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 1b5d3b7241ed968818456de4c5a1b046b9d91f514ad8a55075437d0b57f26783
MD5 f70f5d5c3c503de1240ff1be8c7069b3
BLAKE2b-256 46751ed2d0874ce057206dbdf0a3dd947da2d9a1725c8f3af8c19ccfd51b1f05

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page