from fastapi import FastAPI, File, UploadFile from fastapi.responses import HTMLResponse import fitz # PyMuPDF import pytesseract from PIL import Image import io from pdfminer.high_level import extract_pages from pdfminer.layout import LTTextContainer app = FastAPI() @app.get("/", response_class=HTMLResponse) async def home(): html_content = """ PDF Text Extraction API

Welcome to PDF Text Extraction API

This API allows you to upload PDFs and extract text — including optional OCR for images.

Available endpoints:

Use a tool like Postman or write your own client to send PDF files to the endpoints.

""" return HTMLResponse(content=html_content, status_code=200) @app.post("/extract-text") async def extract_text(file: UploadFile = File(...)): try: contents = await file.read() doc = fitz.open(stream=contents, filetype="pdf") extracted_text = "" for i, page in enumerate(doc): extracted_text += f"\n\n--- Page {i + 1} ---\n\n" + page.get_text() return {"filename": file.filename, "text": extracted_text} except Exception as e: return {"error": str(e)} @app.post("/extract-text-ocr") async def extract_text_ocr(file: UploadFile = File(...)): try: contents = await file.read() doc = fitz.open(stream=contents, filetype="pdf") full_text = "" for i in range(len(doc)): page = doc.load_page(i) # Normal text text = page.get_text() # Render page to an image pix = page.get_pixmap() img = Image.open(io.BytesIO(pix.tobytes())) # OCR text ocr_text = pytesseract.image_to_string(img) full_text += f"\n\n--- Page {i + 1} ---\n\n" full_text += text + "\n" full_text += "[OCR Text]\n" + ocr_text return {"filename": file.filename, "text": full_text} except Exception as e: return {"error": str(e)} @app.post("/extract-text-structured") async def extract_text_structured(file: UploadFile = File(...)): try: contents = await file.read() # Save to temp file to use with extract_pages import tempfile with tempfile.NamedTemporaryFile(delete=False, suffix=".pdf") as tmp_file: tmp_file.write(contents) temp_pdf_path = tmp_file.name structured_text = "" for i, page_layout in enumerate(extract_pages(temp_pdf_path)): structured_text += f"\n\n--- Page {i + 1} ---\n\n" for element in page_layout: if isinstance(element, LTTextContainer): structured_text += element.get_text() return {"filename": file.filename, "text": structured_text} except Exception as e: return {"error": str(e)}