Download studio.py from failed09/bashkir-trocr-base: direct link, hf CLI and curl.
- Browser
- Download file 2.77 kB
-
https://huggingface.co/failed09/bashkir-trocr-base/resolve/main/studio.py
- Command line
-
hf download hf://failed09/bashkir-trocr-base/studio.py
-
curl -L -o studio.py https://huggingface.co/failed09/bashkir-trocr-base/resolve/main/studio.py
2.77 kB
| """Local browser UI. Uploaded images live only in request memory.""" | |
| import argparse | |
| import io | |
| import threading | |
| import time | |
| import webbrowser | |
| from pathlib import Path | |
| from fastapi import FastAPI, HTTPException, UploadFile | |
| from fastapi.responses import FileResponse | |
| from PIL import Image, UnidentifiedImageError | |
| from starlette.concurrency import run_in_threadpool | |
| from runtime.engine import OCR | |
| def create_app(ocr): | |
| app=FastAPI(title='Bashkir OCR Studio',docs_url=None,redoc_url=None) | |
| lock=threading.Lock() | |
| def index():return FileResponse(Path(__file__).parent/'runtime/index.html',headers={'Cache-Control':'no-store, no-cache, must-revalidate','Pragma':'no-cache','Expires':'0'}) | |
| def status():return dict(ready=True,backend=ocr.backend) | |
| async def recognize(file:UploadFile): | |
| data=await file.read(25*1024*1024+1) | |
| if len(data)>25*1024*1024:raise HTTPException(413,'Изображение слишком большое: предел 25 МБ.') | |
| try: | |
| image=Image.open(io.BytesIO(data)) | |
| if image.width*image.height>25_000_000:raise HTTPException(413,'Предел — 25 миллионов пикселей.') | |
| image.load() | |
| except (UnidentifiedImageError,OSError,Image.DecompressionBombError):raise HTTPException(400,'Не удалось открыть изображение.') | |
| if not lock.acquire(blocking=False):raise HTTPException(409,'Дождитесь завершения текущего изображения.') | |
| try:return await run_in_threadpool(ocr.recognize,image) | |
| finally:lock.release() | |
| return app | |
| def main(): | |
| parser=argparse.ArgumentParser(description=__doc__) | |
| parser.add_argument('--backend',choices=['cpu','gpu','auto'],default='cpu') | |
| parser.add_argument('--port',type=int,default=8001) | |
| parser.add_argument('--no-browser',action='store_true') | |
| parser.add_argument('--model-dir',type=Path,help='Optional directory containing config.json and model files') | |
| args=parser.parse_args() | |
| ocr=OCR(root=args.model_dir,backend=args.backend) | |
| if not args.no_browser: | |
| def open_ready(): | |
| import urllib.request | |
| for _ in range(60): | |
| try: | |
| with urllib.request.urlopen(f'http://127.0.0.1:{args.port}/status',timeout=1) as r: | |
| if r.status==200:webbrowser.open(f'http://127.0.0.1:{args.port}/?v={int(time.time())}');return | |
| except OSError:time.sleep(.5) | |
| threading.Thread(target=open_ready,daemon=True).start() | |
| import uvicorn | |
| uvicorn.run(create_app(ocr),host='127.0.0.1',port=args.port,access_log=False) | |
| if __name__=='__main__':main() | |