from fastapi import FastAPI, File, UploadFile, HTTPException from fastapi.responses import JSONResponse import tempfile import os # Import our services from app.services.text_extractor import extract_text_from_pdf from app.services.risk_analyzer import analyze_clause_with_gemini from app.services.risk_scorer import calculate_scores, get_risk_definition from app.schemas import AnalysisReport, AnalyzedClause, RiskFinding # Create FastAPI app instance app = FastAPI( title="Multilingual Legal Contract Analyzer", description="AI-powered contract analysis for English and Indic languages", version="1.0.0" ) @app.post("/analyze/", response_model=AnalysisReport) async def analyze_contract(file: UploadFile = File(...)): """ Analyze a legal contract PDF and return detailed risk analysis. Args: file: PDF file to analyze Returns: AnalysisReport with risk analysis and suggestions """ if not file.filename.lower().endswith('.pdf'): raise HTTPException( status_code=400, detail="Only PDF files are supported") with tempfile.NamedTemporaryFile(delete=False, suffix='.pdf') as temp_file: try: content = await file.read() temp_file.write(content) temp_file.flush() # Step 1: Extract text from PDF print(f"Extracting text from {file.filename}...") full_text = extract_text_from_pdf(temp_file.name) if not full_text or len(full_text.strip()) < 50: raise HTTPException( status_code=400, detail="Unable to extract meaningful text from PDF. Please ensure the PDF is readable." ) # Step 2 removed → directly analyze full contract print("Analyzing full contract with AI...") ai_result = analyze_clause_with_gemini(full_text) # Build findings list risks = [] for risk_data in ai_result.get("risks", []): risk_id = risk_data.get("risk_id") if risk_id: risk_def = get_risk_definition(risk_id) risk_finding = RiskFinding( risk_id=risk_id, description=risk_data.get( "explanation", risk_def["description"]), score=risk_def["score"] ) risks.append(risk_finding) # Wrap into single "clause" (actually full contract text) analyzed_clause = AnalyzedClause( clause_number=1, text=full_text[:500] + "..." if len(full_text) > 500 else full_text, risks=risks, suggestion=ai_result.get("suggestion") ) # Step 3: Calculate final risk score print("Calculating final risk score...") final_score, all_findings = calculate_scores([analyzed_clause]) # Step 4: Contract metadata (basic detection) contract_type = "General Contract" language = "English" # Create final analysis report analysis_report = AnalysisReport( file_name=file.filename, language=language, contract_type=contract_type, final_risk_score=final_score, clauses=[analyzed_clause] ) print(f"Analysis complete. Final risk score: {final_score}") return analysis_report except HTTPException: raise except Exception as e: print(f"Error during analysis: {e}") raise HTTPException( status_code=500, detail=f"Analysis failed: {str(e)}" ) finally: try: os.unlink(temp_file.name) except: pass @app.get("/") async def root(): return {"message": "Multilingual Legal Contract Analyzer API is running"} @app.get("/health") async def health_check(): return {"status": "healthy", "service": "contract-analyzer"} if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=7860)