from fastapi import FastAPI, File, UploadFile, HTTPException from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import JSONResponse from generate_report import generate_report from utils import convert_to_png from utils import dicom_to_png import pydicom import tempfile import io app = FastAPI(title="FastAPI Example App", version="0.1.0") app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) @app.get("/") async def read_root(): return {"message": "Hello oopa"} @app.post("/upload-image/") async def upload_image(file: UploadFile = File(...)): try: print(f"✅ Received file: {file.filename}") image = await convert_to_png(file) # this may hang print(f"✅ Image converted to PNG") image_io = io.BytesIO() image.save(image_io, format="PNG") image_data = image_io.getvalue() report = generate_report(image_data) # this may also hang print(f"✅ Report generated") return {"report": report} except Exception as e: print(f"❌ Error: {str(e)}") raise HTTPException(status_code=500, detail=str(e)) @app.post("/generate_report_dicom") async def generate_report_dicom(file: UploadFile = File(...)): """ Generate radiology report from DICOM file. Checks if the DICOM is an X-ray, converts it to PNG, and generates a report. """ try: # Validate file type if not file.filename.lower().endswith(('.dcm', '.dicom')): raise HTTPException(status_code=400, detail="File must be a DICOM file (.dcm or .dicom)") # Read DICOM file file_content = await file.read() # Create a temporary file to store DICOM data with tempfile.NamedTemporaryFile(delete=False, suffix='.dcm') as temp_file: temp_file.write(file_content) temp_file_path = temp_file.name try: # Read DICOM data dicom_data = pydicom.dcmread(temp_file_path) # # Check if it's an X-ray # if not is_xray_dicom(dicom_data): # return JSONResponse( # {"error": "DICOM file does not appear to be an X-ray image"}, # status_code=400 # ) # Convert DICOM to PNG image = dicom_to_png(dicom_data) image_io = io.BytesIO() image.save(image_io, format="PNG") image_data = image_io.getvalue() report= generate_report(image_data) # Generate report using the image # Get additional DICOM metadata for context metadata = {} if hasattr(dicom_data, 'PatientID'): metadata['patient_id'] = str(dicom_data.PatientID) if hasattr(dicom_data, 'StudyDate'): metadata['study_date'] = str(dicom_data.StudyDate) if hasattr(dicom_data, 'Modality'): metadata['modality'] = str(dicom_data.Modality) if hasattr(dicom_data, 'BodyPartExamined'): metadata['body_part'] = str(dicom_data.BodyPartExamined) return JSONResponse({ "generated_report": report, "dicom_metadata": metadata, "image_info": { "width": image.width, "height": image.height, "mode": image.mode } }) finally: # Clean up temporary file import os try: os.unlink(temp_file_path) except: pass except HTTPException: raise except Exception as e: return JSONResponse({"error": str(e)}, status_code=500)