pish updates on server
This commit is contained in:
@@ -20,7 +20,7 @@ from fastapi.responses import Response
|
||||
from datetime import datetime
|
||||
from fastapi import HTTPException
|
||||
from pydantic import BaseModel
|
||||
from typing import Optional, Union, Dict, Any,List,Optional, List, Tuple, Any
|
||||
from typing import Optional, Union, Dict, Any
|
||||
import os
|
||||
import requests
|
||||
import os
|
||||
@@ -34,10 +34,10 @@ base_path = os.path.join("data", "config_files")
|
||||
QUESTIONS_PATH = os.path.join(base_path, "questions.json")
|
||||
THEME_CONTEXT_PATH = os.path.join(base_path, "theme_context.json")
|
||||
|
||||
|
||||
|
||||
with open(THEME_CONTEXT_PATH, "r", encoding="utf-8") as f:
|
||||
# Load themes at module level
|
||||
with open(THEME_CONTEXT_PATH, "r") as f:
|
||||
themes = json.load(f)
|
||||
|
||||
# Initialize FastAPI app
|
||||
app = FastAPI(
|
||||
title="Fire Fighter Interview API",
|
||||
@@ -58,6 +58,7 @@ app.add_middleware(
|
||||
api_key_header = APIKeyHeader(name="Authorization", auto_error=False)
|
||||
|
||||
|
||||
|
||||
async def get_api_key(api_key_header: str = Security(api_key_header)) -> str:
|
||||
"""Validate API key from header"""
|
||||
if not api_key_header or not api_key_header.startswith('Bearer '):
|
||||
@@ -78,28 +79,22 @@ async def get_api_key(api_key_header: str = Security(api_key_header)) -> str:
|
||||
class ChatRequest(BaseModel):
|
||||
resume_url: Optional[str] = None
|
||||
query: str=None
|
||||
chat_id: int
|
||||
conversation_id: str
|
||||
theme_id: Optional[int] = 1
|
||||
full_history_url: Optional[str] = None
|
||||
form_id:Optional[int] = None
|
||||
feedback: Optional[str] = None
|
||||
generate_theme:str="NO"
|
||||
|
||||
class ChatResponse(BaseModel):
|
||||
message: str
|
||||
end: bool
|
||||
pop_theme_generation:bool
|
||||
error: Optional[str] = None
|
||||
|
||||
|
||||
|
||||
class GeneratePDFRequest(BaseModel):
|
||||
conversation_id: str
|
||||
feedback: Optional[str] = None
|
||||
previous_results: Optional[Dict[str, Any]] = None
|
||||
resume_url: Optional[str] = None
|
||||
chat_id: int
|
||||
theme_id: Optional[int] = 1
|
||||
full_history_url: Optional[str] = None
|
||||
form_id:Optional[int] = None
|
||||
generate_theme:str="YES"
|
||||
|
||||
class QuizRequest(BaseModel):
|
||||
pdf_url: str
|
||||
@@ -108,8 +103,9 @@ class QuizRequest(BaseModel):
|
||||
class QuizResponse(BaseModel):
|
||||
success: bool
|
||||
message: str
|
||||
quiz_data: Optional[List[Any]] = None
|
||||
quiz_data: Optional[Dict[str, Any]] = None
|
||||
error: Optional[str] = None
|
||||
|
||||
|
||||
async def extract_pdf_text(pdf_url: str) -> Union[str, None]:
|
||||
"""Extract text from PDF and handle potential errors."""
|
||||
@@ -145,99 +141,66 @@ async def extract_pdf_text(pdf_url: str) -> Union[str, None]:
|
||||
status_code=500,
|
||||
detail=f"Error processing PDF: {str(e)}"
|
||||
)
|
||||
|
||||
@app.post("/rescue-career/chat")
|
||||
|
||||
@app.post("/rescue-career/chat", response_model=ChatResponse)
|
||||
async def chat_endpoint(
|
||||
request: ChatRequest,
|
||||
api_key: str = Depends(get_api_key)
|
||||
):
|
||||
try:
|
||||
# Validate theme
|
||||
print(f"Received request with theme_id: {request.theme_id}") # Debugging print
|
||||
matching_themes = [t for t in themes if t["id"] == request.theme_id]
|
||||
if not matching_themes:
|
||||
print(f"No theme found with ID: {request.theme_id}") # Debugging print
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail=f"No theme found with ID {request.theme_id}"
|
||||
)
|
||||
print(f"Validated theme ID: {request.theme_id}") # Print statement added
|
||||
|
||||
|
||||
# Only try to load document if resume_url is provided
|
||||
resume_docs = ""
|
||||
if request.resume_url:
|
||||
print(f"Loading resume from URL: {request.resume_url}") # Debugging print
|
||||
docs = load_document(request.resume_url)
|
||||
if not docs:
|
||||
print("Invalid resume URL: Unable to fetch document") # Debugging print
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail="Invalid resume URL: Unable to fetch document"
|
||||
)
|
||||
resume_docs = "\n".join(f"- {doc.page_content}" for doc in docs)
|
||||
print(f"Loaded resume documents: {resume_docs}") # Debugging print
|
||||
|
||||
full_history_docs = ""
|
||||
if request.full_history_url:
|
||||
print(f"Loading full history from URL: {request.full_history_url}") # Debugging print
|
||||
docs = load_document(request.full_history_url)
|
||||
if not docs:
|
||||
print("Invalid full history URL: Unable to fetch document") # Debugging print
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail="Invalid full history URL: Unable to fetch document"
|
||||
)
|
||||
full_history_docs = "\n".join(f"- {doc.page_content}" for doc in docs)
|
||||
print(f"Loaded full history documents: {full_history_docs}") # Debugging print
|
||||
|
||||
form_response_docs = ""
|
||||
if request.form_id:
|
||||
print(f"Fetching form response for form_id: {request.form_id}") # Debugging print
|
||||
try:
|
||||
x_api_key = os.getenv("BACKEND_XAPI_KEY")
|
||||
url = f"{os.getenv('BACKEND_BASE_URL')}/v3/api/custom/theme-document/answer/{request.form_id}?x-project={x_api_key}"
|
||||
result = requests.get(url)
|
||||
result.raise_for_status() # Ensure we raise an error for bad responses
|
||||
form_response = result.json()["data"] # Return response in JSON format
|
||||
form_response_docs = "\n".join(f"- {form_response}")
|
||||
|
||||
print(f"Fetched form response: {form_response}") # Debugging print
|
||||
except requests.RequestException as e:
|
||||
print(f"Error fetching onboarding data: {str(e)}") # Debugging print
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail="Unable to fetch onboarding data"
|
||||
)
|
||||
# Parse response
|
||||
print("Parsing AI response...") # Debugging print
|
||||
query = request.query
|
||||
if not query:
|
||||
query = "Let's get started"
|
||||
# Get AI chat response
|
||||
response = ai_chat(
|
||||
query=query,
|
||||
conversation_id=request.chat_id,
|
||||
theme_id=request.theme_id,
|
||||
resume=resume_docs,
|
||||
full_history=full_history_docs,
|
||||
form_response=form_response_docs
|
||||
)
|
||||
print(response)
|
||||
|
||||
return ChatResponse(
|
||||
message=response.get("message", ""),
|
||||
end=response.get("end", "no") == "yes",
|
||||
pop_theme_generation=response.get("pop_theme_generation","no") == "yes",
|
||||
error=None
|
||||
query=request.query,
|
||||
conversation_id=request.conversation_id,
|
||||
theme_id=request.theme_id,
|
||||
resume=resume_docs
|
||||
)
|
||||
|
||||
|
||||
# Parse response
|
||||
try:
|
||||
parsed_response = json.loads(response)
|
||||
return ChatResponse(
|
||||
message=parsed_response.get("message", ""),
|
||||
end=parsed_response.get("end", "no") == "yes",
|
||||
error=None
|
||||
)
|
||||
except json.JSONDecodeError:
|
||||
return ChatResponse(
|
||||
message=response,
|
||||
end=False,
|
||||
error=None
|
||||
)
|
||||
|
||||
except HTTPException as e:
|
||||
# Re-raise HTTP exceptions
|
||||
raise
|
||||
except Exception as e:
|
||||
print(f"Error processing chat request: {str(e)}") # Print statement added
|
||||
raise HTTPException(
|
||||
status_code=500,
|
||||
detail=f"Error processing chat request: {str(e)}"
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@app.post("/rescue-career/generate-theme")
|
||||
async def generate_pdf_endpoint(
|
||||
request: GeneratePDFRequest,
|
||||
@@ -245,119 +208,72 @@ async def generate_pdf_endpoint(
|
||||
):
|
||||
|
||||
try:
|
||||
|
||||
print(f"Received request with theme_id: {request.theme_id}") # Debugging print
|
||||
matching_themes = [t for t in themes if t["id"] == request.theme_id]
|
||||
if not matching_themes:
|
||||
print(f"No theme found with ID: {request.theme_id}") # Debugging print
|
||||
# Here you would fetch the conversation data using the conversation_id
|
||||
# This is a placeholder - replace with your actual conversation data fetching logic
|
||||
conversation_data = await get_conversation_data(request.conversation_id)
|
||||
|
||||
if not conversation_data:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail=f"No theme found with ID {request.theme_id}"
|
||||
status_code=404,
|
||||
detail=f"No conversation found with ID {request.conversation_id}"
|
||||
)
|
||||
print(f"Validated theme ID: {request.theme_id}") # Print statement added
|
||||
|
||||
resume_docs = ""
|
||||
if request.resume_url:
|
||||
print(f"Loading resume from URL: {request.resume_url}") # Debugging print
|
||||
docs = load_document(request.resume_url)
|
||||
if not docs:
|
||||
print("Invalid resume URL: Unable to fetch document") # Debugging print
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail="Invalid resume URL: Unable to fetch document"
|
||||
)
|
||||
resume_docs = "\n".join(f"- {doc.page_content}" for doc in docs)
|
||||
print(f"Loaded resume documents: {resume_docs}") # Debugging print
|
||||
|
||||
|
||||
full_history_docs = ""
|
||||
if request.full_history_url:
|
||||
print(f"Loading full history from URL: {request.full_history_url}") # Debugging print
|
||||
docs = load_document(request.full_history_url)
|
||||
if not docs:
|
||||
print("Invalid full history URL: Unable to fetch document") # Debugging print
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail="Invalid full history URL: Unable to fetch document"
|
||||
detail="Invalid full_history URL: Unable to fetch document"
|
||||
)
|
||||
full_history_docs = "\n".join(f"- {doc.page_content}" for doc in docs)
|
||||
print(f"Loaded full history documents: {full_history_docs}") # Debugging print
|
||||
|
||||
form_response_docs = ""
|
||||
if request.form_id:
|
||||
print(f"Fetching form response for form_id: {request.form_id}") # Debugging print
|
||||
try:
|
||||
x_api_key = os.getenv("BACKEND_XAPI_KEY")
|
||||
url = f"{os.getenv('BACKEND_BASE_URL')}/v3/api/custom/theme-document/answer/{request.form_id}?x-project={x_api_key}"
|
||||
result = requests.get(url)
|
||||
result.raise_for_status() # Ensure we raise an error for bad responses
|
||||
form_response = result.json()["data"] # Return response in JSON format
|
||||
form_response_docs = "\n".join(f"- {form_response}")
|
||||
|
||||
print(f"Fetched form response: {form_response}") # Debugging print
|
||||
except requests.RequestException as e:
|
||||
print(f"Error fetching onboarding data: {str(e)}") # Debugging print
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail="Unable to fetch onboarding data"
|
||||
)
|
||||
# Here you would fetch the conversation data using the conversation_id
|
||||
# This is a placeholder - replace with your actual conversation data fetching logic
|
||||
# Get AI-generated theme content
|
||||
# Get AI-generated theme content
|
||||
response = ai_chat(
|
||||
query="NOW GENERATE THE STARTPOP FRAMEWORK",
|
||||
conversation_id=request.chat_id,
|
||||
theme_id=request.theme_id,
|
||||
resume=resume_docs,
|
||||
full_history=full_history_docs,
|
||||
form_response=form_response_docs,
|
||||
generate_theme="YES"
|
||||
)
|
||||
print(f"AI Response for theme: {response}")
|
||||
# Generate theme data using the generate_theme function
|
||||
theme_data = generate_theme(
|
||||
conversation_data=conversation_data,
|
||||
feedback=request.feedback,
|
||||
previous_result=request.previous_results,
|
||||
resume = resume_docs,
|
||||
full_history = full_history_docs
|
||||
)
|
||||
|
||||
# Ensure AI response is valid
|
||||
if not isinstance(response, str):
|
||||
raise HTTPException(status_code=500, detail="Invalid AI response format")
|
||||
if not theme_data:
|
||||
raise HTTPException(
|
||||
status_code=500,
|
||||
detail="Failed to generate theme data"
|
||||
)
|
||||
|
||||
# Generate PDF
|
||||
response_data = json.loads(response)
|
||||
pdf_content = create_pdf(response_data)
|
||||
# Generate the PDF using the create_pdf function
|
||||
pdf_content = create_pdf(theme_data)
|
||||
|
||||
# Create filename with timestamp
|
||||
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
file_path = f"theme_{timestamp}.pdf"
|
||||
filename = f"theme_{timestamp}.pdf"
|
||||
|
||||
# Save the PDF locally temporarily
|
||||
with open(file_path, "wb") as file:
|
||||
file.write(pdf_content)
|
||||
|
||||
# Upload the PDF to S3 using the API
|
||||
upload_url = f"{os.getenv('BACKEND_BASE_URL')}/v3/api/custom/theme/doc-upload?x-project={x_api_key}"
|
||||
with open(file_path, 'rb') as file:
|
||||
files = {'file': file}
|
||||
upload_response = requests.post(upload_url, files=files)
|
||||
|
||||
# Check if the upload was successful
|
||||
if upload_response.status_code != 200:
|
||||
raise HTTPException(status_code=upload_response.status_code, detail="File upload to S3 failed: " + upload_response.text)
|
||||
|
||||
upload_data = upload_response.json() # Get the response in JSON format
|
||||
|
||||
# Extract the uploaded file URL
|
||||
theme_url = upload_data.get("url") # Adjust this key based on the actual API response structure
|
||||
if not theme_url:
|
||||
raise HTTPException(status_code=500, detail="Failed to retrieve theme URL from upload response")
|
||||
|
||||
# Clean up the temporary file
|
||||
os.remove(file_path)
|
||||
|
||||
# Return JSON response with theme URL and text
|
||||
return {
|
||||
"theme_url": theme_url,
|
||||
"theme_text": response_data
|
||||
}
|
||||
# Return the PDF as a response
|
||||
return Response(
|
||||
content=pdf_content,
|
||||
media_type="application/pdf",
|
||||
headers={
|
||||
"Content-Disposition": f'attachment; filename="{filename}"'
|
||||
}
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error generating theme: {str(e)}")
|
||||
raise HTTPException(status_code=500, detail=f"Error: {str(e)}")
|
||||
|
||||
raise HTTPException(
|
||||
status_code=500,
|
||||
detail=f"Error generating PDF: {str(e)}"
|
||||
)
|
||||
|
||||
@app.post("/rescue-career/generate-quiz", response_model=QuizResponse)
|
||||
async def generate_quiz_endpoint(
|
||||
|
||||
Reference in New Issue
Block a user