Spaces:
Sleeping
Sleeping
| import os | |
| import tempfile | |
| import asyncio | |
| from fastapi import FastAPI, UploadFile, File, Request, HTTPException | |
| from fastapi.middleware.cors import CORSMiddleware | |
| from paddleocr import PaddleOCR | |
| MAX_FILE_SIZE = 900 * 1024 | |
| MAX_CONCURRENT_REQUESTS = 6 | |
| ALLOWED_ORIGINS = { | |
| "https://delivqr.com", | |
| "https://www.delivqr.com", | |
| "https://kreeboo.com", | |
| "https://www.kreeboo.com", | |
| } | |
| app = FastAPI(title="Paddle OCR API") | |
| app.add_middleware( | |
| CORSMiddleware, | |
| allow_origins=list(ALLOWED_ORIGINS), | |
| allow_credentials=True, | |
| allow_methods=["POST"], | |
| allow_headers=["*"], | |
| ) | |
| semaphore = asyncio.Semaphore(MAX_CONCURRENT_REQUESTS) | |
| ocr_models = {} | |
| def load_model(): | |
| ocr_models["en"] = PaddleOCR( | |
| lang="en", | |
| use_angle_cls=False, | |
| show_log=False | |
| ) | |
| async def restrict_domain(request: Request, call_next): | |
| origin = request.headers.get("origin") | |
| referer = request.headers.get("referer") | |
| if origin not in ALLOWED_ORIGINS and not ( | |
| referer and any(referer.startswith(o) for o in ALLOWED_ORIGINS) | |
| ): | |
| raise HTTPException(status_code=403, detail="Access denied") | |
| return await call_next(request) | |
| async def ocr_api(file: UploadFile = File(...)): | |
| async with semaphore: | |
| data = await file.read() | |
| if len(data) > MAX_FILE_SIZE: | |
| raise HTTPException(413, "Image too large") | |
| if not file.content_type or not file.content_type.startswith("image/"): | |
| raise HTTPException(400, "Only image files allowed") | |
| with tempfile.NamedTemporaryFile(delete=False) as tmp: | |
| tmp.write(data) | |
| tmp_path = tmp.name | |
| try: | |
| result = ocr_models["en"].ocr(tmp_path) | |
| except Exception as e: | |
| raise HTTPException(500, f"OCR failed: {str(e)}") | |
| finally: | |
| os.remove(tmp_path) | |
| return { | |
| "language": "en", | |
| "lines": [line[1][0] for line in result[0]] | |
| } | |