from fastapi import FastAPI, UploadFile, File, HTTPException, Request from fastapi.middleware.cors import CORSMiddleware import os import tempfile from pathlib import Path from pydantic import BaseModel import traceback import logging from review_api import review_story, review_story_text # Set up logging logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) # Create Pydantic model for text input class StoryText(BaseModel): text: str app = FastAPI(title="Rawi Review API") # Configure CORS app.add_middleware( CORSMiddleware, allow_origins=["*"], # In production, replace with specific origins allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) @app.get("/") def read_root(): return {"message": "Welcome to Rawi Story Review API"} @app.middleware("http") async def log_requests(request: Request, call_next): """Log all requests and responses""" logger.info(f"Request: {request.method} {request.url.path}") try: response = await call_next(request) logger.info(f"Response status: {response.status_code}") return response except Exception as e: logger.error(f"Request failed: {e}") logger.error(traceback.format_exc()) raise @app.post("/review-story/") async def create_review_from_file(file: UploadFile = File(...)): # Validate file is PDF if not file.filename.lower().endswith('.pdf'): raise HTTPException(status_code=400, detail="Only PDF files are supported") logger.info(f"Processing PDF file: {file.filename}") # Create temporary file temp_dir = tempfile.gettempdir() temp_file_path = Path(temp_dir) / file.filename try: # Save uploaded file with open(temp_file_path, "wb") as buffer: content = await file.read() buffer.write(content) logger.info(f"PDF saved to temporary location: {temp_file_path}") # Process PDF and get review result = review_story(str(temp_file_path)) return result except Exception as e: logger.error(f"Error processing PDF: {e}") logger.error(traceback.format_exc()) raise HTTPException(status_code=500, detail=str(e)) finally: # Clean up temporary file if temp_file_path.exists(): os.unlink(temp_file_path) @app.post("/review-story-text/") async def create_review_from_text(story: StoryText): try: # Log the request logger.info(f"Received text review request with {len(story.text)} characters") # Validate text length if len(story.text) < 100: raise HTTPException(status_code=400, detail="Text is too short for review. Minimum 100 characters required.") # Process text directly and get review result = review_story_text(story.text) return result except Exception as e: logger.error(f"Error processing text: {e}") logger.error(traceback.format_exc()) raise HTTPException(status_code=500, detail=f"Error processing text: {str(e)}") if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=8000)