fairytail100/fastapi
1
1from fastapi import FastAPI, HTTPException, Header2from pydantic import BaseModel3import base644import ddddocr5import os6from PIL import Image, ImageOps7import io8 9app = FastAPI()10ocr = ddddocr.DdddOcr(show_ad=False)11OCR_SECRET = os.environ.get("OCR_SECRET", "")12 13class CaptchaRequest(BaseModel):14 image_base64: str15 16@app.get("/")17def root():18 return {"status": "ok"}19 20@app.get("/health")21def health():22 return {"status": "ok"}23 24@app.post("/solve")25def solve_captcha(req: CaptchaRequest, x_api_key: str = Header(None)):26 if not OCR_SECRET or x_api_key != OCR_SECRET:27 raise HTTPException(status_code=401, detail="Unauthorized")28 try:29 img_bytes = base64.b64decode(req.image_base64.split(",")[-1])30 img = Image.open(io.BytesIO(img_bytes)).convert("RGB")31 32 # Scale up 3x for better recognition33 img = img.resize((img.width * 3, img.height * 3), Image.LANCZOS)34 35 # Invert: pink on dark → dark on white36 img = ImageOps.invert(img)37 38 buf = io.BytesIO()39 img.save(buf, format="PNG")40 41 result = ocr.classification(buf.getvalue())42 43 # Post-process: lowercase letters only, no numbers, no symbols44 cleaned = ''.join(c for c in result.lower() if c.isalpha())45 46 return {"code": cleaned}47 except Exception as e:48 raise HTTPException(status_code=500, detail=str(e))