47 lines
1.6 KiB
Python
47 lines
1.6 KiB
Python
from __future__ import annotations
|
|
|
|
import base64
|
|
from pathlib import Path
|
|
|
|
import requests
|
|
|
|
from backend.app.config import settings
|
|
|
|
|
|
class MistralClient:
|
|
endpoint = "https://api.mistral.ai/v1/ocr"
|
|
|
|
def ocr_image(self, image_path: Path) -> str:
|
|
if not settings.mistral_api_key:
|
|
raise RuntimeError("MISTRAL_API_KEY no esta configurada")
|
|
data_url = self._image_data_url(image_path)
|
|
response = requests.post(
|
|
self.endpoint,
|
|
headers={
|
|
"Content-Type": "application/json",
|
|
"Authorization": f"Bearer {settings.mistral_api_key}",
|
|
},
|
|
json={
|
|
"model": settings.mistral_ocr_model,
|
|
"document": {"type": "image_url", "image_url": data_url},
|
|
"include_image_base64": False,
|
|
},
|
|
timeout=180,
|
|
)
|
|
if response.status_code == 401:
|
|
raise RuntimeError("API Key de Mistral invalida")
|
|
if not response.ok:
|
|
raise RuntimeError(f"Mistral error {response.status_code}: {response.text}")
|
|
data = response.json()
|
|
pages = data.get("pages") or []
|
|
markdown_pages = [page.get("markdown", "").strip() for page in pages if page.get("markdown")]
|
|
if markdown_pages:
|
|
return "\n\n".join(markdown_pages)
|
|
if data.get("markdown"):
|
|
return data["markdown"].strip()
|
|
raise RuntimeError("Mistral OCR no devolvio Markdown")
|
|
|
|
def _image_data_url(self, image_path: Path) -> str:
|
|
encoded = base64.b64encode(image_path.read_bytes()).decode("ascii")
|
|
return f"data:image/jpeg;base64,{encoded}"
|