Skip to content

Commit 43c6fa9

Browse files
fix: include policyengine_api in Modal image and improve error handling
- Added policyengine_api package to Modal image via add_local_python_source - Moved model imports inside try blocks so failures are caught - Added raw SQL fallback to mark jobs as failed when exceptions occur - Ensures DB is updated even if model imports fail
1 parent f94dcbd commit 43c6fa9

1 file changed

Lines changed: 90 additions & 59 deletions

File tree

src/policyengine_api/modal_app.py

Lines changed: 90 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
"supabase>=2.10.0 "
2828
"rich>=13.9.4"
2929
)
30+
# Include the policyengine_api models package (copy=True allows subsequent build steps)
31+
.add_local_python_source("policyengine_api", copy=True)
3032
)
3133

3234

@@ -383,13 +385,12 @@ def simulate_economy_uk(simulation_id: str) -> None:
383385

384386
engine = create_engine(database_url)
385387

386-
from policyengine_api.models import (
387-
Dataset,
388-
Simulation,
389-
SimulationStatus,
390-
)
391-
392388
try:
389+
from policyengine_api.models import (
390+
Dataset,
391+
Simulation,
392+
SimulationStatus,
393+
)
393394
with Session(engine) as session:
394395
simulation = session.get(Simulation, UUID(simulation_id))
395396
if not simulation:
@@ -464,13 +465,21 @@ def simulate_economy_uk(simulation_id: str) -> None:
464465
console.print(
465466
f"[bold red]UK economy simulation {simulation_id} failed: {e}[/bold red]"
466467
)
467-
with Session(engine) as session:
468-
simulation = session.get(Simulation, UUID(simulation_id))
469-
if simulation:
470-
simulation.status = SimulationStatus.FAILED
471-
simulation.error_message = str(e)
472-
session.add(simulation)
468+
# Use raw SQL to mark as failed - models may not be available
469+
try:
470+
from sqlmodel import text
471+
472+
with Session(engine) as session:
473+
session.execute(
474+
text(
475+
"UPDATE simulations SET status = 'failed', error_message = :error "
476+
"WHERE id = :sim_id"
477+
),
478+
{"sim_id": simulation_id, "error": str(e)[:1000]},
479+
)
473480
session.commit()
481+
except Exception as db_error:
482+
console.print(f"[bold red]Failed to update DB: {db_error}[/bold red]")
474483
raise
475484

476485

@@ -496,13 +505,12 @@ def simulate_economy_us(simulation_id: str) -> None:
496505

497506
engine = create_engine(database_url)
498507

499-
from policyengine_api.models import (
500-
Dataset,
501-
Simulation,
502-
SimulationStatus,
503-
)
504-
505508
try:
509+
from policyengine_api.models import (
510+
Dataset,
511+
Simulation,
512+
SimulationStatus,
513+
)
506514
with Session(engine) as session:
507515
simulation = session.get(Simulation, UUID(simulation_id))
508516
if not simulation:
@@ -577,13 +585,21 @@ def simulate_economy_us(simulation_id: str) -> None:
577585
console.print(
578586
f"[bold red]US economy simulation {simulation_id} failed: {e}[/bold red]"
579587
)
580-
with Session(engine) as session:
581-
simulation = session.get(Simulation, UUID(simulation_id))
582-
if simulation:
583-
simulation.status = SimulationStatus.FAILED
584-
simulation.error_message = str(e)
585-
session.add(simulation)
588+
# Use raw SQL to mark as failed - models may not be available
589+
try:
590+
from sqlmodel import text
591+
592+
with Session(engine) as session:
593+
session.execute(
594+
text(
595+
"UPDATE simulations SET status = 'failed', error_message = :error "
596+
"WHERE id = :sim_id"
597+
),
598+
{"sim_id": simulation_id, "error": str(e)[:1000]},
599+
)
586600
session.commit()
601+
except Exception as db_error:
602+
console.print(f"[bold red]Failed to update DB: {db_error}[/bold red]")
587603
raise
588604

589605

@@ -607,19 +623,18 @@ def economy_comparison_uk(job_id: str) -> None:
607623

608624
engine = create_engine(database_url)
609625

610-
# Import models inline to avoid import issues
611-
from policyengine_api.models import (
612-
Dataset,
613-
DecileImpact,
614-
ProgramStatistics,
615-
Report,
616-
ReportStatus,
617-
Simulation,
618-
SimulationStatus,
619-
TaxBenefitModelVersion,
620-
)
621-
622626
try:
627+
# Import models inline
628+
from policyengine_api.models import (
629+
Dataset,
630+
DecileImpact,
631+
ProgramStatistics,
632+
Report,
633+
ReportStatus,
634+
Simulation,
635+
SimulationStatus,
636+
TaxBenefitModelVersion,
637+
)
623638
with Session(engine) as session:
624639
# Load report and related data
625640
report = session.get(Report, UUID(job_id))
@@ -802,13 +817,21 @@ def economy_comparison_uk(job_id: str) -> None:
802817
console.print(
803818
f"[bold red]UK economy comparison {job_id} failed: {e}[/bold red]"
804819
)
805-
with Session(engine) as session:
806-
report = session.get(Report, UUID(job_id))
807-
if report:
808-
report.status = ReportStatus.FAILED
809-
report.error_message = str(e)
810-
session.add(report)
820+
# Use raw SQL to mark as failed - models may not be available
821+
try:
822+
from sqlmodel import text
823+
824+
with Session(engine) as session:
825+
session.execute(
826+
text(
827+
"UPDATE reports SET status = 'failed', error_message = :error "
828+
"WHERE id = :job_id"
829+
),
830+
{"job_id": job_id, "error": str(e)[:1000]},
831+
)
811832
session.commit()
833+
except Exception as db_error:
834+
console.print(f"[bold red]Failed to update DB: {db_error}[/bold red]")
812835
raise
813836

814837

@@ -832,18 +855,18 @@ def economy_comparison_us(job_id: str) -> None:
832855

833856
engine = create_engine(database_url)
834857

835-
# Import models inline
836-
from policyengine_api.models import (
837-
Dataset,
838-
DecileImpact,
839-
ProgramStatistics,
840-
Report,
841-
ReportStatus,
842-
Simulation,
843-
SimulationStatus,
844-
)
845-
846858
try:
859+
# Import models inline
860+
from policyengine_api.models import (
861+
Dataset,
862+
DecileImpact,
863+
ProgramStatistics,
864+
Report,
865+
ReportStatus,
866+
Simulation,
867+
SimulationStatus,
868+
)
869+
847870
with Session(engine) as session:
848871
# Load report and related data
849872
report = session.get(Report, UUID(job_id))
@@ -1015,13 +1038,21 @@ def economy_comparison_us(job_id: str) -> None:
10151038
console.print(
10161039
f"[bold red]US economy comparison {job_id} failed: {e}[/bold red]"
10171040
)
1018-
with Session(engine) as session:
1019-
report = session.get(Report, UUID(job_id))
1020-
if report:
1021-
report.status = ReportStatus.FAILED
1022-
report.error_message = str(e)
1023-
session.add(report)
1041+
# Use raw SQL to mark as failed - models may not be available
1042+
try:
1043+
from sqlmodel import text
1044+
1045+
with Session(engine) as session:
1046+
session.execute(
1047+
text(
1048+
"UPDATE reports SET status = 'failed', error_message = :error "
1049+
"WHERE id = :job_id"
1050+
),
1051+
{"job_id": job_id, "error": str(e)[:1000]},
1052+
)
10241053
session.commit()
1054+
except Exception as db_error:
1055+
console.print(f"[bold red]Failed to update DB: {db_error}[/bold red]")
10251056
raise
10261057

10271058

0 commit comments

Comments
 (0)