import os from fastapi import FastAPI, HTTPException, Header from pydantic import BaseModel from dotenv import load_dotenv from schemas import GenerateWholeRequest, GenerateWholeResponse, GeneratePartialRequest, GeneratePartialResponse, ChatWithPersonaRequest, ChatWithPersonaResponse, ChatWithReportRequest, ChatWithReportResponse import uvicorn import logging logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) load_dotenv() API_KEY = os.getenv("MY_API_KEY") app = FastAPI( title="Alter Ego API", description="API for generating and interacting with synthetic user personas", version="1.0.0", docs_url="/docs", redoc_url="/redoc" ) @app.post("/re-generate", response_model=GeneratePartialResponse, summary="Generate report from existing personas", description="Generate a research report using existing user personas and a new set of questions" ) def generate_report(request: GeneratePartialRequest, x_api_key: str = Header(...)): if x_api_key != API_KEY: raise HTTPException(status_code=403, detail="Invalid API Key") from core import generate_report, generate_fleet_from_users logger.info("Generating interviews for each persona.") fleet=generate_fleet_from_users(users_personas=request.users, questions=request.questions) logger.info(f"Generated fleet:\n{fleet}") logger.info("Generating report based on all interviews.") report = generate_report(fleet=fleet, scope=request.scope,questions=request.questions) logger.info("Report generation completed.") return GeneratePartialResponse(report=report, users=fleet) @app.post("/generate", response_model=GenerateWholeResponse, summary="Generate complete research", description="Generate user personas and a research report from scratch" ) def generate_all(request: GenerateWholeRequest, x_api_key: str = Header(...)): if x_api_key != API_KEY: logger.warning("Unauthorized access attempt.") raise HTTPException(status_code=403, detail="Invalid API Key") from core import generate_user_parameters, generate_synthetic_personas, generate_fleet, generate_report, generate_audience_name # Generate a concise audience name audience_name = generate_audience_name(request.audience, request.scope) logger.info(f"Generated audience name: {audience_name}") logger.info(f"Generating user personas for audience: {audience_name}, scope: {request.scope}, n: {request.n}") user_parameters = generate_user_parameters(request.audience, request.scope) logger.info(f"User parameters: {user_parameters}") users = generate_synthetic_personas(parameters=user_parameters, num_personas=request.n, audience=request.audience)["users_personas"] logger.info(f"Generated {len(users)} personas:\n{users}") logger.info("Generating interviews for each persona.") fleet = generate_fleet(n=request.n, parameters=user_parameters, questions=request.questions, audience=request.audience) logger.info(f"Generated fleet of length {len(fleet)}:\n{fleet}") logger.info("Generating report based on all interviews.") report_text = generate_report(questions=request.questions,fleet=fleet, scope=request.scope) logger.info(f"Report generated:\n{report_text}") return { "audience_name": audience_name, "users": fleet, "report": report_text } @app.post("/chat-with-persona", response_model=ChatWithPersonaResponse, summary="Chat with a specific persona", description="Have a conversation with a specific user persona, optionally including conversation history" ) def chat_with_persona_endpoint(request: ChatWithPersonaRequest, x_api_key: str = Header(...)): if x_api_key != API_KEY: logger.warning("Unauthorized access attempt.") raise HTTPException(status_code=403, detail="Invalid API Key") from core import chat_with_persona logger.info(f"Chatting with persona: {request.user}") answer = chat_with_persona( persona=request.user, question=request.question, conversation_history=request.conversation_history ) logger.info("Chat completed successfully.") return ChatWithPersonaResponse(answer=answer) @app.post("/chat-with-report", response_model=ChatWithReportResponse, summary="Chat with report content", description="Ask questions about the synthesized content from multiple user interviews" ) def chat_with_report_endpoint(request: ChatWithReportRequest, x_api_key: str = Header(...)): if x_api_key != API_KEY: logger.warning("Unauthorized access attempt.") raise HTTPException(status_code=403, detail="Invalid API Key") from core import chat_with_report logger.info("Chatting with report content") answer = chat_with_report( users=request.users, question=request.question, questions=request.questions ) logger.info(f"Chat with report completed successfully.\nAnswer:\n{answer}") return ChatWithReportResponse(answer=answer) if __name__ == "__main__": uvicorn.run("app:app", host="0.0.0.0", port=8000, reload=False)