from fastapi import FastAPI, File, UploadFile, HTTPException from fastapi.responses import JSONResponse, HTMLResponse from fastapi.middleware.cors import CORSMiddleware from fastapi.staticfiles import StaticFiles import base64 import io from PIL import Image from lab_analyzer import LabReportAnalyzer import logging import os # Configure logging logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) # Initialize FastAPI app app = FastAPI( title="Lab Report Analysis API", description="AI-powered lab report analysis service using Google AI Studio", version="1.0.0", docs_url="/docs", redoc_url="/redoc" ) # Add CORS middleware app.add_middleware( CORSMiddleware, allow_origins=["*"], # Configure this properly for production allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # Initialize the lab analyzer analyzer = LabReportAnalyzer() @app.get("/health") async def health_check(): """Health check endpoint for monitoring""" return {"status": "healthy", "service": "lab-report-analyzer"} @app.post("/analyze") async def analyze_lab_report(file: UploadFile = File(...)): """ Analyze a lab report image and return structured results Args: file: Uploaded image file (jpg, jpeg, png, bmp, tiff, webp) Returns: JSON response with analysis results """ try: # Validate file type if not file.content_type.startswith('image/'): raise HTTPException( status_code=400, detail="File must be an image (jpg, jpeg, png, bmp, tiff, webp)" ) # Read and validate image contents = await file.read() if len(contents) == 0: raise HTTPException(status_code=400, detail="Empty file uploaded") # Validate image can be opened try: image = Image.open(io.BytesIO(contents)) image.verify() # Verify it's a valid image except Exception as e: raise HTTPException(status_code=400, detail=f"Invalid image file: {str(e)}") # Convert to base64 for analysis image_b64 = base64.b64encode(contents).decode("utf-8") # Analyze the lab report logger.info(f"Analyzing lab report: {file.filename}") analysis_result = await analyzer.analyze_report(image_b64) return JSONResponse( status_code=200, content={ "success": True, "filename": file.filename, "analysis": analysis_result } ) except HTTPException: raise except Exception as e: logger.error(f"Error analyzing lab report: {str(e)}") raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}") @app.post("/analyze-base64") async def analyze_lab_report_base64(data: dict): """ Analyze a lab report from base64 encoded image Args: data: JSON with 'image' key containing base64 encoded image Returns: JSON response with analysis results """ try: if 'image' not in data: raise HTTPException(status_code=400, detail="Missing 'image' field in request body") image_b64 = data['image'] # Remove data:image/...;base64, prefix if present if image_b64.startswith('data:image'): image_b64 = image_b64.split(',')[1] # Validate base64 and image try: image_bytes = base64.b64decode(image_b64) image = Image.open(io.BytesIO(image_bytes)) image.verify() except Exception as e: raise HTTPException(status_code=400, detail=f"Invalid base64 image: {str(e)}") # Analyze the lab report logger.info("Analyzing lab report from base64 data") analysis_result = await analyzer.analyze_report(image_b64) return JSONResponse( status_code=200, content={ "success": True, "analysis": analysis_result } ) except HTTPException: raise except Exception as e: logger.error(f"Error analyzing base64 lab report: {str(e)}") raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}") # Flutter-friendly endpoint aliases @app.post("/api/analyze-lab") async def analyze_lab_api(file: UploadFile = File(...)): """Flutter-friendly endpoint for lab analysis""" return await analyze_lab_report(file) @app.post("/api/analyze-lab-base64") async def analyze_lab_base64_api(data: dict): """Flutter-friendly endpoint for base64 lab analysis""" return await analyze_lab_report_base64(data) @app.get("/", response_class=HTMLResponse) async def root(): """Main page with upload interface""" return """ 🏥 Lab Report Analysis AI

🏥 Lab Report Analysis AI

AI-powered medical lab report analysis using Google AI Studio

📸

Image Upload

Support for JPG, PNG, TIFF, and more

🤖

AI Analysis

Google Gemini 2.0 Flash model

📊

Structured Results

Summary, findings, and interpretations

Fast Processing

Real-time analysis results

📤 Upload Lab Report Image

Click here or drag and drop your lab report image

🔧 API Documentation

This service provides RESTful API endpoints for programmatic access:

POST /analyze

Upload lab report image file for analysis

POST /analyze-base64

Analyze lab report from base64 encoded image

POST /api/analyze-lab

Flutter-friendly endpoint for file upload

POST /api/analyze-lab-base64

Flutter-friendly endpoint for base64 analysis

📚 Interactive Documentation:

⚠️ This tool is for educational purposes only. Always consult healthcare professionals for medical advice.

""" if __name__ == "__main__": import uvicorn uvicorn.run("app:app", host="0.0.0.0", port=7860, reload=True)