synthea_webservice/webservice/apps/synthea/lib/utils.py

83 lines
2.8 KiB
Python

from pathlib import Path
import pandas as pd
import shlex
import subprocess
from zipfile import ZipFile
import json
from django.conf import settings
from uuid import uuid4
def available_states():
states = []
# Read the demographics.csv file from the Synthea resources and get all the unique state names
# Important, the state name for synthea is case sensitive (field id)
df = pd.read_csv(settings.SYNTHEA_STATES_DIR / 'demographics.csv', index_col=False)
for state in df.STNAME.unique():
states.append({'id' : state , 'name' : state})
# Sort on name
states = sorted(states, key=lambda k: k['name'].lower())
return states
def available_modules():
# Assumption here: Only .json files in the main folder are modules. The rest are submodules...
modules = []
for module in settings.SYNTHEA_MODULE_DIR.iterdir():
if module.is_file() and module.suffix == '.json':
data = json.loads(module.read_text())
modules.append({'id' : module.name.replace('.json',''), 'name' : data['name']})
modules = sorted(modules, key=lambda k: k['name'].lower())
return modules
def run_synthea(state = None, population = None, gender = None, age = None, module = None):
# Add a unique dir to the output, so multiple Synthea processes can run parallel
temp_id = uuid4().hex
output_folder = settings.SYNTHEA_OUTPUT_DIR / temp_id
synthea_cmd = [settings.SYNTHEA_BASE_DIR / 'run_synthea','--exporter.baseDirectory',output_folder]
zip_file = 'Synthea_'
if population:
synthea_cmd.append('-p')
synthea_cmd.append(str(population))
zip_file += f'population_{population}_'
if gender:
synthea_cmd.append('-g')
synthea_cmd.append(gender.upper())
zip_file += f'gender_{gender}_'
if age:
synthea_cmd.append('-a')
synthea_cmd.append(age)
zip_file += f'age_{age}_'
if module:
synthea_cmd.append('-m')
synthea_cmd.append(module)
zip_file += f'module_{module}_'
if state:
synthea_cmd.append(state)
zip_file += f'state_{state}'
process_ok = False
log = ''
with subprocess.Popen(synthea_cmd,cwd=settings.SYNTHEA_BASE_DIR, stdout=subprocess.PIPE,stderr=subprocess.PIPE) as process:
for line in process.stdout:
line = line.decode('utf8')
log += line
if not process_ok:
process_ok = line.find('BUILD SUCCESSFUL') >= 0
if process_ok:
with ZipFile(f'{output_folder}/{zip_file}_{temp_id}.zip', 'w') as export:
for file in (output_folder / settings.SYNTHEA_EXPORT_TYPE).iterdir():
export.write(file,file.name)
return (log,Path(f'{output_folder}/{zip_file}_{temp_id}.zip'))
else:
raise Exception(log)