Spaces:
Sleeping
Sleeping
| import base64 | |
| import httpx | |
| from api.config import settings | |
| LLM_URL = settings.llm.groq_url | |
| LLM_API_KEY = settings.llm.groq_token | |
| LLM_MODEL = settings.llm.ocr_model | |
| LLM_TEMPERATURE = settings.llm.ocr_temperature | |
| LLM_MAX_TOKENS = settings.llm.max_tokens | |
| def _ocr_mock_response() -> str: | |
| return "J'ai mal à la tête et de la fièvre depuis 3 jours, je tousse beaucoup et j'ai du mal à respirer." | |
| def _ocr_robust_fallback_response(status_code: int, error_text: str) -> str: | |
| return f"Le service d'extraction de texte est temporairement indisponible (erreur {status_code}). Veuillez contacter votre administrateur ou réessayer plus tard." | |
| def _ocr_debug_response(status_code: int, error_text: str) -> str: | |
| return f"DEBUG: OCR extraction failed with status {status_code}. {error_text}" | |
| async def extract_text_from_image(image_bytes: bytes) -> str: | |
| # encodage en base 64 pour envoyer l'image dans le payload JSON | |
| image_b64 = base64.b64encode(image_bytes).decode("utf-8") | |
| headers = { | |
| "Authorization": f"Bearer {LLM_API_KEY}", | |
| "Content-Type": "application/json", | |
| } | |
| messages = [ | |
| { | |
| "role": "user", | |
| "content": [ | |
| { | |
| "type": "text", | |
| "text": "Extract all text from this image. Return only the extracted text, nothing else." | |
| }, | |
| { | |
| "type": "image_url", | |
| "image_url": { | |
| "url": f"data:image/jpeg;base64,{image_b64}" | |
| } | |
| } | |
| ] | |
| } | |
| ] | |
| payload = { | |
| "model": LLM_MODEL, | |
| "messages": messages, | |
| "max_tokens": LLM_MAX_TOKENS, | |
| "temperature": LLM_TEMPERATURE, # low temp for extraction (deterministic, not creative) | |
| } | |
| try: | |
| async with httpx.AsyncClient(timeout=30) as client: | |
| response = await client.post(LLM_URL, json=payload, headers=headers) | |
| except httpx.HTTPError as exc: | |
| error_text = str(exc) | |
| print("HF ERROR: HTTP exception during OCR request:", error_text) | |
| if settings.debug_mode: | |
| return _ocr_debug_response(-1, error_text) | |
| if settings.robust_mode: | |
| return _ocr_robust_fallback_response(-1, error_text) | |
| raise | |
| if response.status_code == 200: | |
| try: | |
| generated = response.json()["choices"][0]["message"]["content"] | |
| return generated.strip() | |
| except Exception as exc: | |
| error_text = str(exc) | |
| print("HF ERROR: malformed OCR response:", error_text) | |
| if settings.debug_mode: | |
| return _ocr_debug_response(response.status_code, error_text) | |
| if settings.robust_mode: | |
| return _ocr_robust_fallback_response(response.status_code, error_text) | |
| raise | |
| print("HF ERROR:", response.status_code, response.text) | |
| if settings.debug_mode: | |
| return _ocr_debug_response(response.status_code, response.text) | |
| if settings.robust_mode: | |
| if response.status_code == 402: | |
| return _ocr_mock_response() | |
| return _ocr_robust_fallback_response(response.status_code, response.text) | |
| response.raise_for_status() | |
| return "" |