Skip to content

Commit 2f43546

Browse files
committed
Merge branch 'feat/python-wrapper' of https://github.com/Candice0313/synthea into python-wrapper
2 parents c807432 + 55739ef commit 2f43546

File tree

6 files changed

+93
-0
lines changed

6 files changed

+93
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,4 @@ src/main/resources/export/outpatient_rev_cntr_code_map.json
5151

5252
# VS Code plugin files
5353
.history
54+
output/
Binary file not shown.
Binary file not shown.
Binary file not shown.

scripts/python_wrapper/example.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
from wrapper import SyntheaGenerator
2+
import os
3+
4+
gen = SyntheaGenerator(
5+
state="California",
6+
gender="F",
7+
age="30-40",
8+
patients=2,
9+
module="diabetes"
10+
)
11+
12+
patients = gen.generate()
13+
14+
15+
if not patients:
16+
print("No patients generated.")
17+
else:
18+
print(f"Generated {len(patients)} patients")
19+
print("Sample patient resourceType:", patients[0].get("resourceType"))
20+
21+
gen.save("my_output/diabetes_test")
22+
23+
saved_files = os.listdir("my_output/diabetes_test")
24+
print("Saved files:", saved_files)

scripts/python_wrapper/wrapper.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import subprocess
2+
import os
3+
import json
4+
5+
class SyntheaGenerator:
6+
def __init__(self, state="Massachusetts", gender=None, age=None, patients=1, module=None, synth_path=None):
7+
if synth_path is None:
8+
synth_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", ".."))
9+
10+
self.state = state
11+
self.gender = gender
12+
self.age = age
13+
self.patients = patients
14+
self.module = module
15+
self.synth_path = synth_path
16+
self.output_path = os.path.join(self.synth_path, "output", "fhir")
17+
18+
def _clear_output(self):
19+
if os.path.exists(self.output_path):
20+
for f in os.listdir(self.output_path):
21+
if f.endswith(".json"):
22+
os.remove(os.path.join(self.output_path, f))
23+
24+
def _build_command(self):
25+
script = "run_synthea.bat" if os.name == "nt" else "./run_synthea"
26+
cmd = [script, self.state, "-p", str(self.patients)]
27+
if self.age:
28+
cmd += ["-a", self.age]
29+
if self.gender:
30+
cmd += ["-g", self.gender]
31+
if self.module:
32+
cmd += ["-m", self.module]
33+
return cmd
34+
35+
36+
def generate(self):
37+
self._clear_output()
38+
cmd = self._build_command()
39+
try:
40+
subprocess.run(cmd, cwd=self.synth_path, check=True)
41+
except subprocess.CalledProcessError as e:
42+
raise RuntimeError(f"[Synthea Error] CLI failed: {e}")
43+
44+
if not os.path.exists(self.output_path):
45+
raise RuntimeError("No output folder found.")
46+
47+
json_files = [f for f in os.listdir(self.output_path) if f.endswith(".json")]
48+
patients = []
49+
for file in json_files:
50+
with open(os.path.join(self.output_path, file), "r") as f:
51+
data = json.load(f)
52+
entries = data.get("entry", [])
53+
has_patient = any(
54+
e.get("resource", {}).get("resourceType") == "Patient" for e in entries
55+
)
56+
if data.get("resourceType") == "Bundle" and has_patient:
57+
patients.append(data)
58+
59+
return patients
60+
61+
def save(self, output_dir):
62+
os.makedirs(output_dir, exist_ok=True)
63+
for file in os.listdir(self.output_path):
64+
if file.endswith(".json"):
65+
src = os.path.join(self.output_path, file)
66+
dst = os.path.join(output_dir, file)
67+
with open(src, "r") as f_in, open(dst, "w") as f_out:
68+
f_out.write(f_in.read())

0 commit comments

Comments
 (0)