pdf-text-api / app.py
Rivalcoder
Add application file
45a9a23
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 = """
<!DOCTYPE html>
<html>
<head>
<title>PDF Text Extraction API</title>
<style>
body { font-family: Arial, sans-serif; padding: 2rem; background: #f0f0f0; }
.container { max-width: 600px; margin: auto; background: white; padding: 2rem; border-radius: 8px; box-shadow: 0 0 10px rgba(0,0,0,0.1);}
h1 { color: #333; }
p { color: #555; }
a { color: #1a73e8; text-decoration: none; }
a:hover { text-decoration: underline; }
</style>
</head>
<body>
<div class="container">
<h1>Welcome to PDF Text Extraction API</h1>
<p>This API allows you to upload PDFs and extract text β€” including optional OCR for images.</p>
<h2>Available endpoints:</h2>
<ul>
<li><b>POST /extract-text</b> - Extract plain text from PDF pages.</li>
<li><b>POST /extract-text-ocr</b> - Extract text including OCR from image-based PDFs.</li>
<li><b>POST /extract-text-structured</b> - Extract structured text using pdfminer.</li>
</ul>
<p>Use a tool like <a href="https://www.postman.com/" target="_blank">Postman</a> or write your own client to send PDF files to the endpoints.</p>
</div>
</body>
</html>
"""
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)}