Skip to content

Python API

Roberto Cruz edited this page May 15, 2026 · 2 revisions

Python API

Synthea exposes a full Python API for integrating synthetic patient generation into your own pipelines.

Installation

uv pip install -e .
# or
pip install -e .

Core Classes

Class Module Purpose
Generator synthea Main entry point — orchestrates full population generation
GeneratorOptions synthea Configuration object for a generation run
Person synthea.world.person Represents a single patient and their health state
Config synthea.helpers.config Reads and writes synthea.properties values
FHIRExporter synthea.export.fhir Serializes a Person to a FHIR R4 bundle

Quick Start

from synthea import Generator, GeneratorOptions

options = GeneratorOptions()
options.population_size = 100
options.state = "California"
options.city = "San Francisco"
options.seed = 12345

generator = Generator(options)
generator.run()

print(f"Generated : {generator.stats['total_generated']}")
print(f"Living    : {generator.stats['living']}")
print(f"Dead      : {generator.stats['dead']}")

Run with UV:

uv run python my_script.py

GeneratorOptions

from synthea import GeneratorOptions

opts = GeneratorOptions()

opts.population_size   = 100        # Number of patients
opts.seed              = 42         # Random seed (None = random)
opts.clinician_seed    = None       # Separate clinician seed
opts.state             = "Texas"    # US state
opts.city              = "Austin"   # City within state
opts.gender            = None       # "M", "F", or None (both)
opts.age_range         = "20-65"    # Age filter string or None
opts.modules           = []         # Module names to enable ([] = all)
opts.threads           = 4          # Worker threads
opts.output_dir        = "./output" # Output directory
opts.config_path       = None       # Path to .properties file
opts.reference_date    = None       # datetime object or None (today)
opts.only_dead         = False      # Emit only deceased patients

Working with Individual Patients

from datetime import datetime
from synthea.world.person import Person
from synthea.engine.generator import Generator, GeneratorOptions
from synthea.export.fhir import FHIRExporter
from pathlib import Path

# Build a specific patient
person = Person(seed=99)
person.attributes.update({
    "gender": "F",
    "birth_date": datetime(1985, 3, 22),
    "first_name": "Maria",
    "last_name": "Santos",
    "race": "hispanic",
    "ethnicity": "hispanic",
})
person.init_health_record()

# Simulate the patient's life
generator = Generator(GeneratorOptions())
generator._simulate_life(person)

# Export to FHIR R4
exporter = FHIRExporter(generator.config, Path("./output"))
output_file = exporter.export(person, index=0)
print(f"FHIR bundle written to: {output_file}")

Batch Processing

from synthea import Generator, GeneratorOptions
import concurrent.futures

def generate_state(state: str, n: int, seed: int) -> dict:
    opts = GeneratorOptions()
    opts.population_size = n
    opts.state = state
    opts.seed = seed
    g = Generator(opts)
    g.run()
    return {"state": state, **g.stats}

states = ["California", "Texas", "New York", "Florida"]

with concurrent.futures.ThreadPoolExecutor(max_workers=4) as pool:
    futures = [
        pool.submit(generate_state, s, 250, i * 1000)
        for i, s in enumerate(states)
    ]
    for f in concurrent.futures.as_completed(futures):
        r = f.result()
        print(f"{r['state']}: {r['total_generated']} patients")

Streaming / Generator Pattern

For very large populations, generate patients one at a time to control memory:

from synthea import Generator, GeneratorOptions

opts = GeneratorOptions()
opts.population_size = 1   # Generate one at a time in a loop
opts.seed = 0

generator = Generator(opts)

for i in range(10_000):
    opts.seed = i
    generator.run()
    # Each iteration writes output files incrementally

Accessing the FHIR Bundle in Memory

import json
from pathlib import Path
from synthea import Generator, GeneratorOptions

opts = GeneratorOptions()
opts.population_size = 5
generator = Generator(opts)
generator.run()

# Read all generated FHIR bundles
fhir_dir = Path(opts.output_dir) / "fhir"
for bundle_file in fhir_dir.glob("*.json"):
    if bundle_file.name.startswith(("hospital", "practitioner")):
        continue
    bundle = json.loads(bundle_file.read_text())
    patient = next(
        e["resource"] for e in bundle["entry"]
        if e["resource"]["resourceType"] == "Patient"
    )
    print(f"Patient: {patient.get('id')}{patient.get('name', [{}])[0].get('family')}")

Custom Configuration via API

from synthea.helpers.config import Config
from synthea import Generator, GeneratorOptions

config = Config()
config.set("exporter.fhir.export", "true")
config.set("exporter.csv.export", "true")
config.set("generate.thread_pool_size", "8")

opts = GeneratorOptions()
opts.population_size = 500
opts.config_path = None   # Config object passed directly

generator = Generator(opts, config=config)
generator.run()

Stats Object

After generator.run(), generator.stats contains:

{
    "total_generated": 100,
    "living": 87,
    "dead": 13,
    "total_encounters": 4521,
    "total_medications": 2103,
    "elapsed_seconds": 12.4,
}

Clone this wiki locally