| from fastapi import FastAPI, UploadFile, File |
| from fastapi.responses import JSONResponse |
| from paddleocr import PaddleOCR |
| import numpy as np |
| from PIL import Image |
| from io import BytesIO |
| import requests |
|
|
| app = FastAPI( |
| title="PaddleOCR API", |
| description="OCR via URL or File Upload", |
| version="1.0.0" |
| ) |
|
|
| ocr = PaddleOCR( |
| lang="en", |
| det_model_dir=None, |
| rec_model_dir=None, |
| use_angle_cls=False |
| ) |
|
|
|
|
| def run_ocr(image_bytes: bytes): |
| img = Image.open(BytesIO(image_bytes)).convert("RGB") |
| img_np = np.array(img) |
|
|
| result = ocr.predict(img_np) |
|
|
| outputs = [] |
| parsed_texts = [] |
|
|
| for res in result: |
| boxes = res.get("rec_boxes", []) |
| texts = res.get("rec_texts", []) |
| scores = res.get("rec_scores", []) |
|
|
| for box, text, score in zip(boxes, texts, scores): |
| parsed_texts.append(text) |
| outputs.append({ |
| "text": text, |
| "confidence": float(score), |
| "bounding_box": box.tolist() |
| }) |
|
|
| return { |
| "results": outputs, |
| "parsedText": parsed_texts, |
| "finalText": " ".join(parsed_texts) |
| } |
|
|
| @app.get("/ocr") |
| async def ocr_from_url(url: str): |
| try: |
| response = requests.get(url, timeout=15) |
| response.raise_for_status() |
| data = run_ocr(response.content) |
| return JSONResponse({ |
| "success": True, |
| **data |
| }) |
| except Exception as e: |
| return JSONResponse( |
| status_code=400, |
| content={ |
| "success": False, |
| "error": str(e) |
| } |
| ) |
|
|
| @app.post("/ocr") |
| async def ocr_from_file(file: UploadFile = File(...)): |
| try: |
| image_bytes = await file.read() |
| data = run_ocr(image_bytes) |
| return JSONResponse({ |
| "success": True, |
| **data |
| }) |
| except Exception as e: |
| return JSONResponse( |
| status_code=400, |
| content={ |
| "success": False, |
| "error": str(e) |
| } |
| ) |
|
|