Spaces:
Sleeping
Sleeping
| """ | |
| Production-friendly client for the NMT HTTP API. | |
| Always sends POST /translate with Content-Type: application/json and body {"text": "..."}. | |
| Use this from services, jobs, and tests to avoid format mistakes. | |
| """ | |
| from __future__ import annotations | |
| import json | |
| import ssl | |
| import urllib.error | |
| import urllib.request | |
| from dataclasses import dataclass | |
| from typing import Any | |
| class TranslateResult: | |
| translation: str | |
| latency_ms: float | |
| request_id: str | |
| raw: dict[str, Any] | |
| def translate( | |
| base_url: str, | |
| text: str, | |
| *, | |
| api_key: str | None = None, | |
| timeout_s: float = 120.0, | |
| request_id: str | None = None, | |
| ) -> TranslateResult: | |
| """ | |
| Translate English text to Italian via POST /translate. | |
| base_url: e.g. "https://marconolimits-nmt.hf.space" (no trailing slash) | |
| api_key: sent as X-API-Key when set (match Space secrets). | |
| """ | |
| root = base_url.rstrip("/") | |
| url = f"{root}/translate" | |
| payload = json.dumps({"text": text}, ensure_ascii=False).encode("utf-8") | |
| headers = { | |
| "Content-Type": "application/json; charset=utf-8", | |
| "Accept": "application/json", | |
| } | |
| if api_key: | |
| headers["X-API-Key"] = api_key | |
| if request_id: | |
| headers["X-Request-Id"] = request_id | |
| req = urllib.request.Request(url, data=payload, headers=headers, method="POST") | |
| ctx = ssl.create_default_context() | |
| try: | |
| with urllib.request.urlopen(req, timeout=timeout_s, context=ctx) as resp: | |
| raw_body = resp.read().decode("utf-8") | |
| data = json.loads(raw_body) | |
| except urllib.error.HTTPError as e: | |
| err_body = e.read().decode("utf-8", errors="replace") | |
| raise RuntimeError(f"HTTP {e.code}: {err_body}") from e | |
| if not isinstance(data, dict): | |
| raise RuntimeError(f"Unexpected response: {data!r}") | |
| if "translation" not in data: | |
| raise RuntimeError(f"Missing translation in response: {data!r}") | |
| return TranslateResult( | |
| translation=str(data["translation"]), | |
| latency_ms=float(data.get("latency_ms", 0.0)), | |
| request_id=str(data.get("request_id", "")), | |
| raw=data, | |
| ) | |
| def healthz(base_url: str, *, timeout_s: float = 30.0) -> bool: | |
| root = base_url.rstrip("/") | |
| req = urllib.request.Request(f"{root}/healthz", method="GET") | |
| ctx = ssl.create_default_context() | |
| try: | |
| with urllib.request.urlopen(req, timeout=timeout_s, context=ctx) as resp: | |
| return resp.status == 200 | |
| except OSError: | |
| return False | |