import asyncio from typing import Dict, List, Optional from typing_extensions import Annotated from temporalio.client import Client from fastapi import APIRouter, HTTPException, status from fastapi.params import Query from src.calculation_target_reliability.utils import wait_for_workflow from src.config import TEMPORAL_URL, TR_RBD_ID from src.database.core import DbSession, CollectorDbSession from src.auth.service import Token from src.models import StandardResponse from .service import run_rbd_simulation, get_simulation_results, identify_worst_eaf_contributors from .schema import OptimizationResult, TargetReliabiltiyQuery from src.auth.access_control import required_permission, OHPermission from src.overhaul_scope.model import OverhaulScope from fastapi import Depends router = APIRouter() # @router.get("", response_model=StandardResponse[List[Dict]]) # async def get_target_reliability( # db_session: DbSession, # scope_name: Optional[str] = Query(None), # eaf_threshold: float = Query(100), # ): # """Get all scope pagination.""" # results = await get_all_target_reliability( # db_session=db_session, scope_name=scope_name, eaf_threshold=eaf_threshold # ) # return StandardResponse( # data=results, # message="Data retrieved successfully", # ) @router.get("", response_model=StandardResponse[OptimizationResult], dependencies=[Depends(required_permission(OHPermission.READ, OverhaulScope))]) async def get_target_reliability( db_session: DbSession, token: Token, collector_db: CollectorDbSession, params: Annotated[TargetReliabiltiyQuery, Query()], # oh_session_id: Optional[str] = Query(None), # eaf_input: float = Query(99.8), # duration: int = Query(17520), # simulation_id: Optional[str] = Query(None), # cut_hours = Query(0) ): """Get all scope pagination.""" oh_session_id = params.oh_session_id eaf_input = params.eaf_input duration = params.duration simulation_id = params.simulation_id cut_hours = params.cut_hours if not oh_session_id: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="oh_session_id is required", ) # results = await get_eaf_timeline( # db_session=db_session, # oh_session_id=oh_session_id, # eaf_input=eaf_input, # oh_duration=duration # ) if duration != 17520: if not simulation_id: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Simulation ID is required for non-default duration. Please run simulation first.", ) else: try: temporal_client = await Client.connect(TEMPORAL_URL) handle = temporal_client.get_workflow_handle(f"simulation-{simulation_id}") desc = await handle.describe() status_name = desc.status.name if status_name in ["RUNNING", "CONTINUED_AS_NEW"]: raise HTTPException( status_code=status.HTTP_425_TOO_EARLY, detail="Simulation is still running.", ) elif status_name != "COMPLETED": raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=f"Simulation failed with status: {status_name}", ) except HTTPException: raise except Exception as e: # Handle connection errors or invalid workflow IDs raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail=f"Simulation not found or error checking status: {str(e)}", ) else: simulation_id = TR_RBD_ID results = await get_simulation_results( simulation_id=simulation_id, token=token ) optimize_result = await identify_worst_eaf_contributors( simulation_result=results, target_eaf=eaf_input, db_session=db_session, oh_session_id=oh_session_id, collector_db=collector_db, simulation_id=simulation_id, duration=duration, po_duration=1200, cut_hours=float(cut_hours) ) return StandardResponse( data=optimize_result, message="Data retrieved successfully", )