Spaces:
Sleeping
Sleeping
device token
Browse files
api/services/synthea_integration.py
CHANGED
|
@@ -19,14 +19,39 @@ class SyntheaIntegrationService:
|
|
| 19 |
"""
|
| 20 |
|
| 21 |
def __init__(self):
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 25 |
self.synthea_jar_path = self.synthea_dir / "synthea-with-dependencies.jar"
|
| 26 |
|
| 27 |
-
# Ensure directories exist
|
| 28 |
-
|
| 29 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 30 |
|
| 31 |
# Synthea configuration
|
| 32 |
self.default_config = {
|
|
@@ -386,6 +411,15 @@ class SyntheaIntegrationService:
|
|
| 386 |
try:
|
| 387 |
logger.info(f"🎯 Starting Synthea generation for {population} patients")
|
| 388 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 389 |
# Try to use real Synthea first
|
| 390 |
try:
|
| 391 |
# Download Synthea if needed
|
|
@@ -530,9 +564,21 @@ class SyntheaIntegrationService:
|
|
| 530 |
"practitioner_files": 0,
|
| 531 |
"total_size_mb": 0,
|
| 532 |
"synthea_available": False,
|
| 533 |
-
"java_available": False
|
|
|
|
| 534 |
}
|
| 535 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 536 |
# Check if Java is available
|
| 537 |
try:
|
| 538 |
java_check = await asyncio.create_subprocess_exec(
|
|
@@ -548,20 +594,34 @@ class SyntheaIntegrationService:
|
|
| 548 |
# Check if Synthea JAR exists
|
| 549 |
stats["synthea_available"] = self.synthea_jar_path.exists()
|
| 550 |
|
| 551 |
-
if
|
| 552 |
-
|
| 553 |
-
|
| 554 |
-
|
| 555 |
-
|
| 556 |
-
|
| 557 |
-
|
| 558 |
-
|
| 559 |
-
|
| 560 |
-
|
| 561 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 562 |
|
| 563 |
return stats
|
| 564 |
|
| 565 |
except Exception as e:
|
| 566 |
logger.error(f"❌ Error getting Synthea statistics: {str(e)}")
|
| 567 |
-
return {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 19 |
"""
|
| 20 |
|
| 21 |
def __init__(self):
|
| 22 |
+
# Use temp directory for containerized environments
|
| 23 |
+
import tempfile
|
| 24 |
+
import os
|
| 25 |
+
|
| 26 |
+
# Try to use /tmp first (common in containers)
|
| 27 |
+
if os.access('/tmp', os.W_OK):
|
| 28 |
+
base_temp_dir = Path('/tmp')
|
| 29 |
+
else:
|
| 30 |
+
# Fallback to system temp directory
|
| 31 |
+
base_temp_dir = Path(tempfile.gettempdir())
|
| 32 |
+
|
| 33 |
+
self.synthea_dir = base_temp_dir / "cps_synthea"
|
| 34 |
+
self.output_dir = base_temp_dir / "cps_fhir_output"
|
| 35 |
self.synthea_jar_path = self.synthea_dir / "synthea-with-dependencies.jar"
|
| 36 |
|
| 37 |
+
# Ensure directories exist with proper error handling
|
| 38 |
+
try:
|
| 39 |
+
self.synthea_dir.mkdir(exist_ok=True)
|
| 40 |
+
self.output_dir.mkdir(parents=True, exist_ok=True)
|
| 41 |
+
logger.info(f"✅ Using directories: synthea={self.synthea_dir}, output={self.output_dir}")
|
| 42 |
+
except PermissionError as e:
|
| 43 |
+
logger.error(f"❌ Permission denied creating directories: {e}")
|
| 44 |
+
# Fallback to current working directory
|
| 45 |
+
self.synthea_dir = Path.cwd() / "synthea_temp"
|
| 46 |
+
self.output_dir = Path.cwd() / "fhir_output_temp"
|
| 47 |
+
self.synthea_jar_path = self.synthea_dir / "synthea-with-dependencies.jar"
|
| 48 |
+
try:
|
| 49 |
+
self.synthea_dir.mkdir(exist_ok=True)
|
| 50 |
+
self.output_dir.mkdir(parents=True, exist_ok=True)
|
| 51 |
+
logger.info(f"✅ Using fallback directories: synthea={self.synthea_dir}, output={self.output_dir}")
|
| 52 |
+
except Exception as fallback_error:
|
| 53 |
+
logger.error(f"❌ Failed to create fallback directories: {fallback_error}")
|
| 54 |
+
raise
|
| 55 |
|
| 56 |
# Synthea configuration
|
| 57 |
self.default_config = {
|
|
|
|
| 411 |
try:
|
| 412 |
logger.info(f"🎯 Starting Synthea generation for {population} patients")
|
| 413 |
|
| 414 |
+
# Check if directories are accessible
|
| 415 |
+
try:
|
| 416 |
+
if not os.access(self.synthea_dir, os.W_OK) or not os.access(self.output_dir, os.W_OK):
|
| 417 |
+
logger.warning("⚠️ Directories not accessible, falling back to mock data")
|
| 418 |
+
return await self._generate_mock_patients(population, age_min, age_max, gender, location)
|
| 419 |
+
except Exception as dir_error:
|
| 420 |
+
logger.warning(f"⚠️ Directory access check failed: {dir_error}, falling back to mock data")
|
| 421 |
+
return await self._generate_mock_patients(population, age_min, age_max, gender, location)
|
| 422 |
+
|
| 423 |
# Try to use real Synthea first
|
| 424 |
try:
|
| 425 |
# Download Synthea if needed
|
|
|
|
| 564 |
"practitioner_files": 0,
|
| 565 |
"total_size_mb": 0,
|
| 566 |
"synthea_available": False,
|
| 567 |
+
"java_available": False,
|
| 568 |
+
"directories_accessible": False
|
| 569 |
}
|
| 570 |
|
| 571 |
+
# Check if directories are accessible
|
| 572 |
+
try:
|
| 573 |
+
stats["directories_accessible"] = (
|
| 574 |
+
self.synthea_dir.exists() and
|
| 575 |
+
self.output_dir.exists() and
|
| 576 |
+
os.access(self.synthea_dir, os.W_OK) and
|
| 577 |
+
os.access(self.output_dir, os.W_OK)
|
| 578 |
+
)
|
| 579 |
+
except Exception:
|
| 580 |
+
stats["directories_accessible"] = False
|
| 581 |
+
|
| 582 |
# Check if Java is available
|
| 583 |
try:
|
| 584 |
java_check = await asyncio.create_subprocess_exec(
|
|
|
|
| 594 |
# Check if Synthea JAR exists
|
| 595 |
stats["synthea_available"] = self.synthea_jar_path.exists()
|
| 596 |
|
| 597 |
+
# Only try to count files if output directory exists and is accessible
|
| 598 |
+
if stats["directories_accessible"] and self.output_dir.exists():
|
| 599 |
+
try:
|
| 600 |
+
for file_path in self.output_dir.glob("*.json"):
|
| 601 |
+
stats["total_files"] += 1
|
| 602 |
+
stats["total_size_mb"] += file_path.stat().st_size / (1024 * 1024)
|
| 603 |
+
|
| 604 |
+
if "hospitalInformation" in file_path.name:
|
| 605 |
+
stats["hospital_files"] += 1
|
| 606 |
+
elif "practitionerInformation" in file_path.name:
|
| 607 |
+
stats["practitioner_files"] += 1
|
| 608 |
+
else:
|
| 609 |
+
stats["patient_files"] += 1
|
| 610 |
+
except Exception as file_error:
|
| 611 |
+
logger.warning(f"⚠️ Error accessing output directory files: {file_error}")
|
| 612 |
|
| 613 |
return stats
|
| 614 |
|
| 615 |
except Exception as e:
|
| 616 |
logger.error(f"❌ Error getting Synthea statistics: {str(e)}")
|
| 617 |
+
return {
|
| 618 |
+
"error": str(e),
|
| 619 |
+
"total_files": 0,
|
| 620 |
+
"patient_files": 0,
|
| 621 |
+
"hospital_files": 0,
|
| 622 |
+
"practitioner_files": 0,
|
| 623 |
+
"total_size_mb": 0,
|
| 624 |
+
"synthea_available": False,
|
| 625 |
+
"java_available": False,
|
| 626 |
+
"directories_accessible": False
|
| 627 |
+
}
|