Spaces:
Sleeping
Sleeping
| import io | |
| import os | |
| import tempfile | |
| from fastapi import FastAPI, File, UploadFile, HTTPException, Query | |
| from PIL import Image | |
| import pytesseract | |
| import pypdfium2 as pdfium | |
| app = FastAPI(title="Scholarform OCR Service") | |
| def root(): | |
| return {"ok": True, "service": "ocr"} | |
| def health(): | |
| return {"ok": True, "service": "ocr"} | |
| def ocr_image_bytes(data: bytes, lang: str) -> str: | |
| image = Image.open(io.BytesIO(data)).convert("RGB") | |
| return pytesseract.image_to_string(image, lang=lang) | |
| def ocr_pdf_file(path: str, lang: str, max_pages: int) -> str: | |
| pdf = pdfium.PdfDocument(path) | |
| pages = min(len(pdf), max_pages) | |
| texts = [] | |
| for i in range(pages): | |
| page = pdf[i] | |
| pil_img = page.render(scale=2).to_pil() | |
| texts.append(pytesseract.image_to_string(pil_img, lang=lang)) | |
| return "\n".join(texts) | |
| async def ocr( | |
| file: UploadFile = File(...), | |
| lang: str = Query("eng"), | |
| max_pages: int = Query(10, ge=1, le=200), | |
| ): | |
| name = (file.filename or "").lower() | |
| content = await file.read() | |
| if not content: | |
| raise HTTPException(status_code=400, detail="Empty file") | |
| try: | |
| if name.endswith(".pdf"): | |
| with tempfile.NamedTemporaryFile(delete=False, suffix=".pdf") as tmp: | |
| tmp.write(content) | |
| path = tmp.name | |
| try: | |
| text = ocr_pdf_file(path, lang=lang, max_pages=max_pages) | |
| finally: | |
| try: | |
| os.remove(path) | |
| except Exception: | |
| pass | |
| return {"ok": True, "type": "pdf", "text": text} | |
| if name.endswith((".png", ".jpg", ".jpeg", ".webp", ".bmp", ".tiff")): | |
| text = ocr_image_bytes(content, lang=lang) | |
| return {"ok": True, "type": "image", "text": text} | |
| raise HTTPException(status_code=400, detail="Supported: PDF or image") | |
| except HTTPException: | |
| raise | |
| except Exception as e: | |
| raise HTTPException(status_code=500, detail=f"OCR failed: {e}") | |