Translator API key management.

This commit is contained in:
2026-09-03 19:23:56 +00:00
parent eb2e8f8273
commit 38af57218a
5 changed files with 178 additions and 46 deletions
+3
View File
@@ -298,6 +298,7 @@ class SettingsIn(BaseModel):
brand_html: str = ""
transition: str = "cube"
translate_langs: list[str] | None = None # None keeps the current set
translate_keys: dict[str, str] | None = None # None keeps the current keys
@router.put("/_api/settings", status_code=204)
@@ -318,6 +319,8 @@ async def put_settings(settings: SettingsIn, request: Request) -> None:
for lang in settings.translate_langs
if (tag := i18n.base_tag(lang))
}
if settings.translate_keys is not None:
data.translate_keys = settings.translate_keys
_invalidate_pages()
+2 -2
View File
@@ -104,8 +104,8 @@ class Data(msgspec.Struct):
#: API keys gating the translator service WebSocket (/_translate/{key};
#: the external forward-auth does not cover that route): key -> display
#: name. Keys are 12 lowercase alphanumeric characters; the first is
#: generated at database bootstrap (see app.py), multiple keys are a
#: future reservation (e.g. managed via a web interface).
#: generated at database bootstrap, more are managed in the editor
#: shell's lang tab (via /_api/settings).
translate_keys: dict[str, str] = {}
#: Wanted target languages for the translator service (presence-keys,
#: value always True). The dispatcher offers jobs only in the
+3 -4
View File
@@ -342,6 +342,7 @@ def _seed(data: Data) -> None:
#: Translator key format: 12 lowercase alphanumeric characters — not
#: brute-forceable over a WebSocket handshake, still human-manageable.
#: The editor's lang tab generates further keys in the same format.
_KEY_ALPHABET = "abcdefghijklmnopqrstuvwxyz0123456789"
@@ -349,10 +350,8 @@ _KEY_ALPHABET = "abcdefghijklmnopqrstuvwxyz0123456789"
def _translator_defaults(data: Data) -> None:
"""Translator defaults on database creation: the first service key and
the wanted target languages (Spanish and Chinese — English is the
original language, never a translation target).
Keys are a dict (key -> display name) with the future reservation that
multiple keys could be managed (e.g. via a web interface)."""
original language, never a translation target). Further keys are
managed in the editor shell's lang tab."""
key = "".join(secrets.choice(_KEY_ALPHABET) for _ in range(12))
data.translate_keys[key] = "default"
data.translate_langs = {"es": True, "zh": True}