Align translation client with GenieHive auth
This commit is contained in:
parent
7aa4c3f50e
commit
8e5c4ae551
|
|
@ -34,7 +34,7 @@ Recommended meaning of the fields:
|
||||||
- `provider`: translation backend. The supported provider is currently
|
- `provider`: translation backend. The supported provider is currently
|
||||||
`geniehive`.
|
`geniehive`.
|
||||||
- `model`: a GenieHive role ID or directly addressable model name.
|
- `model`: a GenieHive role ID or directly addressable model name.
|
||||||
- `api_key`: the GenieHive client key.
|
- `api_key`: the GenieHive client key, sent as the `X-Api-Key` request header.
|
||||||
- `timeout`: request timeout in seconds.
|
- `timeout`: request timeout in seconds.
|
||||||
- `system_prompt`: the translation policy for the client.
|
- `system_prompt`: the translation policy for the client.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,14 @@
|
||||||
{ "code": "hi", "name": "हिन्दी" }
|
{ "code": "hi", "name": "हिन्दी" }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"translation": {
|
||||||
|
"provider": "geniehive",
|
||||||
|
"base_url": "http://127.0.0.1:8800",
|
||||||
|
"model": "scientific_translator",
|
||||||
|
"api_key": "change-me-client-key",
|
||||||
|
"timeout": 120,
|
||||||
|
"system_prompt": "You are a careful scientific translator. Preserve meaning, structure, citations, and technical terms. Return only the translation."
|
||||||
|
},
|
||||||
"navigation": [
|
"navigation": [
|
||||||
{ "label": "Start Here", "href": "#start" },
|
{ "label": "Start Here", "href": "#start" },
|
||||||
{ "label": "Key Resources", "href": "#resources" },
|
{ "label": "Key Resources", "href": "#resources" },
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ class GenieHiveTranslator:
|
||||||
data = json.dumps(payload).encode("utf-8")
|
data = json.dumps(payload).encode("utf-8")
|
||||||
headers = {"Content-Type": "application/json"}
|
headers = {"Content-Type": "application/json"}
|
||||||
if self.config.api_key:
|
if self.config.api_key:
|
||||||
headers["Authorization"] = f"Bearer {self.config.api_key}"
|
headers["X-Api-Key"] = self.config.api_key
|
||||||
req = request.Request(url, data=data, headers=headers, method="POST")
|
req = request.Request(url, data=data, headers=headers, method="POST")
|
||||||
try:
|
try:
|
||||||
with request.urlopen(req, timeout=self.config.timeout) as resp:
|
with request.urlopen(req, timeout=self.config.timeout) as resp:
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import unittest
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from types import SimpleNamespace
|
from types import SimpleNamespace
|
||||||
import sys
|
import sys
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
ROOT = Path(__file__).resolve().parents[1]
|
ROOT = Path(__file__).resolve().parents[1]
|
||||||
sys.path.insert(0, str(ROOT))
|
sys.path.insert(0, str(ROOT))
|
||||||
|
|
@ -313,6 +314,34 @@ class SciSiteForgeTests(unittest.TestCase):
|
||||||
self.assertIn("Spanish", user_text)
|
self.assertIn("Spanish", user_text)
|
||||||
self.assertIn("evolución", user_text)
|
self.assertIn("evolución", user_text)
|
||||||
|
|
||||||
|
def test_geniehive_translator_uses_geniehive_api_key_header(self) -> None:
|
||||||
|
translator = GenieHiveTranslator(
|
||||||
|
TranslationConfig(base_url="http://geniehive.local:8800", model="translation-role", api_key="abc123")
|
||||||
|
)
|
||||||
|
captured: dict[str, object] = {}
|
||||||
|
|
||||||
|
class FakeResponse:
|
||||||
|
def __enter__(self):
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __exit__(self, exc_type, exc, tb):
|
||||||
|
return False
|
||||||
|
|
||||||
|
def read(self):
|
||||||
|
return b'{"choices":[{"message":{"content":"Hola"}}]}'
|
||||||
|
|
||||||
|
def fake_urlopen(req, timeout):
|
||||||
|
captured["headers"] = dict(req.header_items())
|
||||||
|
captured["timeout"] = timeout
|
||||||
|
return FakeResponse()
|
||||||
|
|
||||||
|
with patch("scisiteforge.translations.request.urlopen", fake_urlopen):
|
||||||
|
self.assertEqual(translator.translate("Hello", "Spanish"), "Hola")
|
||||||
|
|
||||||
|
headers = captured["headers"]
|
||||||
|
self.assertEqual(headers["X-api-key"], "abc123")
|
||||||
|
self.assertNotIn("Authorization", headers)
|
||||||
|
|
||||||
def test_translate_site_builds_translator_from_config(self) -> None:
|
def test_translate_site_builds_translator_from_config(self) -> None:
|
||||||
from tempfile import TemporaryDirectory
|
from tempfile import TemporaryDirectory
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue