Saltar al contenido principal
Guía para desarrolladores

Ejecuta Tesseract como API
o servicio autoalojado.

Envuelve Tesseract en un servicio HTTP con confianza: un endpoint FastAPI de producción, concurrencia con pool de procesos, una imagen Docker con paquetes de idioma y comprobaciones de estado, escalado y contrapresión, y despliegue serverless, con los compromisos de privacidad y coste frente a las API OCR gestionadas.

TL;DR — un servicio mínimo

Envuelve la CLI o el enlace pytesseract detrás de HTTP. La imagen nunca sale de tu infraestructura.

bash
pip install fastapi uvicorn python-multipart pytesseract pillow
# instala primero el motor + los paquetes de idioma (ver la guía de instalación)
uvicorn app:app --host 0.0.0.0 --port 8000

Luego llámalo: curl -F "file=@factura.png" "http://localhost:8000/ocr?lang=spa". Tesseract se instala según la guía de instalación.

Primero, las decisiones de diseño

Tres elecciones definen todo el servicio.

DecisiónOpcionesGuía
Síncrono vs asíncronoPetición bloqueante vs cola de trabajosSíncrono para imágenes individuales de pocos segundos; IDs de trabajo asíncronos para documentos grandes o por lotes.
EntradaSubida multipart vs JSON base64Prefiere multipart para imágenes binarias; base64 solo cuando el cliente no puede subir archivos (añade ~33% de tamaño).
SalidaTexto plano, JSON, hOCR/ALTO, PDF con búsquedaDevuelve JSON por defecto; ofrece hOCR para el diseño y una URL de descarga de PDF para archivos.

Una intención principal por endpoint. Mantén /ocr devolviendo texto y añade endpoints separados para PDFs y datos de diseño en lugar de sobrecargar una respuesta.

Un servicio Python de producción (FastAPI)

Validación, límites de tamaño, un tiempo de espera y OCR fuera del bucle de eventos.

app.py
import asyncio, io
from concurrent.futures import ProcessPoolExecutor
from fastapi import FastAPI, File, UploadFile, HTTPException, Query
from PIL import Image
import pytesseract

app = FastAPI(title="Tesseract OCR API")
pool = ProcessPoolExecutor(max_workers=4)
MAX_BYTES = 10 * 1024 * 1024  # 10 MB
LANGS = {"eng", "deu", "fra", "spa"}

def _ocr(data: bytes, lang: str) -> str:
    image = Image.open(io.BytesIO(data))
    return pytesseract.image_to_string(image, lang=lang)

@app.get("/health")
def health():
    return {"status": "ok"}

@app.post("/ocr")
async def ocr(file: UploadFile = File(...), lang: str = Query("spa")):
    if lang not in LANGS:
        raise HTTPException(400, "Idioma no soportado")
    data = await file.read()
    if len(data) > MAX_BYTES:
        raise HTTPException(413, "Archivo demasiado grande")
    loop = asyncio.get_running_loop()
    try:
        text = await asyncio.wait_for(loop.run_in_executor(pool, _ocr, data, lang), timeout=30)
    except asyncio.TimeoutError:
        raise HTTPException(504, "El OCR agotó el tiempo")
    return {"text": text, "lang": lang}

Detalles clave: lista blanca de idiomas, aplica un límite de bytes antes de decodificar, ejecuta el OCR en un pool de procesos y limita el tiempo de reloj. Consulta la guía de Python para la API completa de pytesseract.

Contenerízalo

Incluye Tesseract y los paquetes de idioma en la imagen para que las réplicas sean idénticas.

Dockerfile
FROM python:3.12-slim
RUN apt-get update && apt-get install -y --no-install-recommends \
      tesseract-ocr tesseract-ocr-eng tesseract-ocr-spa \
      libgl1 libglib2.0-0 && rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY app.py .
EXPOSE 8000
HEALTHCHECK CMD python -c "import urllib.request;urllib.request.urlopen('http://localhost:8000/health')"
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000", "--workers", "2"]

Añade solo los paquetes de idioma que necesites para mantener la imagen pequeña. La guía de instalación cubre Docker y la ubicación de tessdata con más detalle.

Concurrencia y escalado

El OCR es intensivo en CPU: paraleliza con procesos, no con hilos.

Seguridad y privacidad

El autoalojamiento es la razón principal por la que los equipos eligen Tesseract.

Plataformas serverless y de contenedores

Tesseract autoalojado vs API OCR gestionadas

DimensiónTesseract autoalojadoAPI OCR gestionada
CosteInfraestructura fija; sin tarifa por páginaPago por petición/página; escala con el volumen
PrivacidadLos documentos nunca salen de tu redLos documentos se envían a un tercero
PrecisiónSólido en impresión limpia; ajustable por dominioA menudo más fuerte en escaneos difíciles y escritura a mano
ControlTotal: versiones, idiomas, modelos personalizadosHoja de ruta y cuotas del proveedor
OperacionesTú lo ejecutas: escalado, actualizaciones, monitorizaciónTotalmente gestionado

Muchos equipos autoalojan Tesseract para trabajos de gran volumen y sensibles a la privacidad y recurren a una API gestionada solo para la minoría difícil de documentos.

Preguntas frecuentes sobre la API

¿Cómo ejecuto Tesseract OCR como API?

Envuelve la CLI o pytesseract en FastAPI/Flask, expón POST /ocr y contenerízalo. Las imágenes permanecen en tu infraestructura.

¿Hilos o procesos?

Procesos. El OCR es intensivo en CPU y el GIL bloquea el paralelismo de hilos; usa ProcessPoolExecutor o subprocesos de la CLI.

¿Es privada una API autoalojada?

Sí: las imágenes subidas se procesan localmente y nunca se envían a terceros, a diferencia de las API OCR gestionadas.

¿Puede ejecutarse serverless?

Sí, en plataformas de contenedores como Cloud Run, imágenes de contenedor de Lambda o Fly.io; cuida los arranques en frío y el tamaño de la imagen con paquetes de idioma.

¿Qué formatos puedo devolver?

Texto plano, JSON con confianza, hOCR/ALTO o un PDF con búsqueda mediante una URL de descarga.