math2latex / api /app.py
msdkhairi's picture
Upload folder using huggingface_hub
fce5ca7 verified
Raw History Blame Contribute Delete
2.2 kB
"""Inference API for local use and Docker Spaces. No training imports."""
import io
import os
from contextlib import asynccontextmanager
from fastapi import FastAPI, File, HTTPException, UploadFile
from PIL import Image, UnidentifiedImageError
MAX_UPLOAD = 8 * 1024 * 1024
def create_app(recognizer=None):
@asynccontextmanager
async def lifespan(app):
if recognizer is None:
threads = int(os.getenv("MATH2LATEX_THREADS", "2"))
if os.getenv("MATH2LATEX_BACKEND", "formulanet") == "formulanet":
from image_to_latex.formulanet import FormulaNetRecognizer
app.state.recognizer = FormulaNetRecognizer(
os.getenv("MATH2LATEX_MODEL_DIR", "artifacts/formulanet"), threads
)
else:
from image_to_latex.inference import Recognizer
app.state.recognizer = Recognizer(
os.getenv("MATH2LATEX_MODEL_DIR", "artifacts/latex-ocr"),
threads,
max_tokens=int(os.getenv("MATH2LATEX_MAX_TOKENS", "192")),
quantized=os.getenv("MATH2LATEX_INT8", "0") == "1",
)
else:
app.state.recognizer = recognizer
yield
app = FastAPI(
title="Math2LaTeX",
description="Convert a cropped formula into LaTeX.",
lifespan=lifespan,
)
@app.get("/")
def health():
return {"status": "ready", "backend": app.state.recognizer.backend}
@app.post("/predict/")
def predict(file: UploadFile = File(...)):
payload = file.file.read(MAX_UPLOAD + 1)
if len(payload) > MAX_UPLOAD:
raise HTTPException(413, "Maximum upload size is 8 MiB")
try:
with Image.open(io.BytesIO(payload)) as image:
result = app.state.recognizer.predict(image)
return {"data": {"pred": result["latex"], **result}}
except (
UnidentifiedImageError,
ValueError,
OSError,
Image.DecompressionBombError,
) as exc:
raise HTTPException(400, str(exc)) from exc
return app
app = create_app()