import shutil import tempfile import os from fastapi import FastAPI, File, UploadFile, HTTPException from fastapi.responses import HTMLResponse, JSONResponse, Response from fastapi.staticfiles import StaticFiles from main import analyze_pdf app = FastAPI() # serve index.html at root @app.get("/", response_class=HTMLResponse) async def read_root(): with open("index.html", "r") as f: return f.read() @app.post("/analyze") async def analyze_endpoint(file: UploadFile = File(...)): if not file.filename.endswith(".pdf"): raise HTTPException(status_code=400, detail="File must be a PDF") # Save to a known fixed path for the viewing endpoint # Note: This is not thread-safe/multi-user safe, but sufficient for this local demo. # Using /tmp to avoid permission issues on read-only filesystems (Hugging Face Spaces) fixed_path = "/tmp/latest_upload.pdf" with open(fixed_path, "wb") as f: shutil.copyfileobj(file.file, f) try: result = analyze_pdf( pdf_path=fixed_path, output_path="", debug_dir="" ) return JSONResponse(content=result) except Exception as e: import traceback traceback.print_exc() raise HTTPException(status_code=500, detail=str(e)) import fitz @app.get("/pdf/page/{page_num}") async def get_pdf_page(page_num: int): path = "/tmp/latest_upload.pdf" if not os.path.exists(path): return Response(status_code=404) try: doc = fitz.open(path) if page_num < 1 or page_num > doc.page_count: doc.close() return Response(status_code=404) page = doc.load_page(page_num - 1) # decent resolution for web viewing zoom = 150 / 72.0 mat = fitz.Matrix(zoom, zoom) pix = page.get_pixmap(matrix=mat, alpha=False) img_bytes = pix.tobytes("png") doc.close() return Response(content=img_bytes, media_type="image/png") except Exception as e: print(f"Error serving page: {e}") return Response(status_code=500)