File size: 5,468 Bytes
7bc7ddb 4564d70 7bc7ddb 4564d70 f79f78e 7bc7ddb 00a6f58 7bc7ddb 152241c 00a6f58 a6e766c 00a6f58 a6e766c 7bc7ddb 4564d70 7bc7ddb 4564d70 7bc7ddb 4564d70 7bc7ddb 4564d70 007a4cf 4564d70 7bc7ddb |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
from fastapi import FastAPI
from interface import PlanRequest, PlanResponse, TripPlan , YoutubeLinkRequest, YoutubeLinkResponse, ChatRequest
from data_importer import DataImporter
from utils.llm_caller import LLMCaller
import asyncio
import time
from datetime import datetime
from fastapi import FastAPI, HTTPException
import logging
app = FastAPI()
data_importer = DataImporter()
agent = LLMCaller()
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
@app.get("/")
def root():
"""Root endpoint - Hugging Face checks this"""
return {
"message": "PAN-SEA Travel Planning API is running",
"status": "healthy",
"timestamp": datetime.utcnow().isoformat()
}
@app.get("/health")
def health_check():
"""Health check endpoint"""
return {
"status": "healthy",
"timestamp": datetime.utcnow().isoformat(),
"service": "PAN-SEA Travel Planning API"
}
@app.get("/v1")
def greet_json():
start_time = time.time()
health_status = {
"status": "healthy",
"timestamp": datetime.utcnow().isoformat(),
"service": "SealionAI Travel Planning Service",
"version": "1.0.0",
"checks": {}
}
return health_status
MAX_RETRIES = 3
RETRY_DELAY = 2 # seconds
@app.post("/v1/generateTripPlan", response_model=PlanResponse)
def generate_trip_plan(request: PlanRequest):
data_importer.coldStartDatabase()
for attempt in range(MAX_RETRIES):
try:
logger.info(f"Generating trip plan - attempt {attempt + 1}/{MAX_RETRIES}")
trip_plan = asyncio.run(agent.query_with_rag(request))
return PlanResponse(
tripOverview=trip_plan.tripOverview,
query_params=request,
retrieved_data=trip_plan.retrieved_data,
trip_plan=trip_plan.trip_plan,
preparation=trip_plan.preparation,
meta={
"status": "success",
"timestamp": datetime.utcnow().isoformat(),
"attempt": attempt + 1
}
)
except Exception as e:
logger.warning(f"Error on attempt {attempt + 1}: {e}")
# If this was the last attempt, raise the error
if attempt == MAX_RETRIES - 1:
logger.error(f"All {MAX_RETRIES} attempts failed due to timeout")
raise HTTPException(
status_code=504, # Gateway Timeout
detail={
"error": "Request timeout",
"message": f"Failed to generate trip plan after {MAX_RETRIES} attempts",
"details": "The service is experiencing high load. Please try again later."
}
)
# Wait before retrying
logger.info(f"Retrying in {RETRY_DELAY} seconds...")
time.sleep(RETRY_DELAY)
# except Exception as e:
# # For non-timeout errors, don't retry
# logger.error(f"Non-timeout error in generate_trip_plan: {e}")
# raise HTTPException(
# status_code=500,
# detail={
# "error": "Internal server error",
# "message": "Failed to generate trip plan",
# "details": str(e),
# "attempt": attempt + 1
# }
# )
@app.post("/v1/addYoutubeLink", response_model=YoutubeLinkResponse)
def add_youtube_link(request: YoutubeLinkRequest):
try:
data_importer.insert_from_youtube(request.video_id)
return YoutubeLinkResponse(
message="add successfully",
video_url=f"https://www.youtube.com/watch?v={request.video_id}"
)
except ValueError as e:
raise HTTPException(status_code=400, detail=f"Invalid video ID: {str(e)}")
except Exception as e:
logger.error(f"Error adding YouTube link: {e}")
raise HTTPException(
status_code=500,
detail={
"error": "Internal server error",
"message": "Failed to add YouTube link",
"details": str(e)
}
)
@app.post("/v1/searchSimilar", response_model=list[dict])
def search_similar(request: YoutubeLinkRequest):
try:
results = data_importer.search_similar(query=request.video_id)
return results
except Exception as e:
logger.error(f"Error during search: {e}")
raise HTTPException(
status_code=500,
detail={
"error": "Search failed",
"message": "Unable to search similar content",
"details": str(e)
}
)
@app.post("/v1/basicChat", response_model=str)
def basic_chat(request: ChatRequest):
try:
user_message = request.message
print(f"User message: {user_message}")
llm_response = asyncio.run(agent.basic_query(
user_prompt=user_message
))
return llm_response
except Exception as e:
logger.error(f"Error in basic_chat: {e}")
raise HTTPException(
status_code=500,
detail={
"error": "Internal server error",
"message": "Failed to process chat request",
"details": str(e)
}
)
|