API переводчика

Офлайн-переводчик HomServer. Два движка:

Адреса: в локальной сети http://192.168.3.2:12010, снаружи https://translate.cybercidor.keenetic.link.

Авторизация

Ключ создаётся в веб-интерфейсе на вкладке «API-ключи». Передать можно любым способом: заголовок Authorization: Bearer tr_…, заголовок X-API-Key: tr_… или поле api_key в теле запроса (как в LibreTranslate). Лимит — запросов в минуту на ключ (по умолчанию 120), при превышении — 429.

Ошибки возвращаются в формате LibreTranslate: {"error": "текст"} с кодом 400/401/413/429/503.

Совместимость с LibreTranslate

Эндпоинты /translate, /detect, /languages, /translate_file принимают те же параметры, что LibreTranslate, поэтому подходят готовые клиенты и плагины (в т.ч. интеграция Nextcloud с LibreTranslate): указываете адрес сервиса и ключ. Дополнительный параметр engine=quality включает LLM.

МетодПутьОписание
POST/translateq (строка или массив), source (код или auto), target, format (text|html), engine
POST/detectq → [{"language":"ru","confidence":90}]
GET/languagesязыки движка fast (?engine=quality — языки LLM), без ключа
POST/translate_filemultipart file, source, target, engine → ждёт окончания, {"translatedFileUrl": "…"}

API v1

МетодПутьОписание
POST/api/v1/translateJSON {"text", "source", "target", "engine", "format"} → {"translatedText", "source", "detectedLanguage", "engine", "seconds"}. text может быть массивом.
POST/api/v1/translate/streamто же, ответ — Server-Sent Events: meta, delta ({"t": "кусок"}), done или error
GET/api/v1/languagesязыки обоих движков, форматы файлов, лимиты (без ключа)
POST/api/v1/filesmultipart file, target, source, engine → задача {"id", "status", …}
GET/api/v1/jobs/{id}статус: queued/running/done/error, progress (%), download_url
GET/api/v1/jobs/{id}/downloadскачать результат (ключ не нужен, ссылка случайная; хранится 24 ч)
GET/api/v1/jobsзадачи этого ключа
DELETE/api/v1/jobs/{id}удалить завершённую задачу
GET/api/v1/statusдоступность движков, занятость LLM, очередь
GET/healthпроверка живости (без ключа)

Форматы файлов: txt, md, srt, vtt, html, xhtml, docx, pptx, xlsx, odt, odp, ods, epub, pdf (PDF → текст без вёрстки, сканы не поддерживаются). До 25 МБ.

Длинные запросы к quality: если ответ готовится дольше 15 с, сервер начинает слать пробелы перед JSON, чтобы прокси роутера не оборвал соединение (JSON-парсеры их игнорируют). Ставьте таймаут клиента от 5 минут или используйте файлы/стрим.

Машиночитаемая схема: /api/openapi.json.

Примеры

curl

curl -s http://192.168.3.2:12010/api/v1/translate \
  -H "Authorization: Bearer tr_ВАШ_КЛЮЧ" -H "Content-Type: application/json" \
  -d '{"text": "Привет, мир!", "source": "ru", "target": "en"}'

# качественный перевод
curl -s http://192.168.3.2:12010/api/v1/translate -H "Authorization: Bearer tr_ВАШ_КЛЮЧ" \
  -H "Content-Type: application/json" --max-time 600 \
  -d '{"text": "Замена ремня ГРМ на Ford Focus 2", "target": "en", "engine": "quality"}'

# файл
curl -s http://192.168.3.2:12010/api/v1/files -H "Authorization: Bearer tr_ВАШ_КЛЮЧ" \
  -F file=@doc.docx -F target=en -F engine=fast
curl -s http://192.168.3.2:12010/api/v1/jobs/ID -H "Authorization: Bearer tr_ВАШ_КЛЮЧ"
curl -sOJ http://192.168.3.2:12010/api/v1/jobs/ID/download

PHP

function translate(string $text, string $target = 'en', string $engine = 'fast'): string {
    $ch = curl_init('http://192.168.3.2:12010/api/v1/translate');
    curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => $engine === 'quality' ? 600 : 30,
        CURLOPT_HTTPHEADER => ['Content-Type: application/json', 'Authorization: Bearer ' . getenv('TRANSLATOR_KEY')],
        CURLOPT_POSTFIELDS => json_encode(['text' => $text, 'target' => $target, 'engine' => $engine]),
    ]);
    $res = json_decode(curl_exec($ch), true);
    if (!empty($res['error'])) throw new RuntimeException($res['error']);
    return $res['translatedText'];
}

Python

import httpx
r = httpx.post("http://192.168.3.2:12010/api/v1/translate",
               headers={"Authorization": "Bearer tr_ВАШ_КЛЮЧ"},
               json={"text": ["Первая строка", "Вторая"], "target": "en"}, timeout=600)
print(r.json()["translatedText"])

JavaScript (стрим)

const r = await fetch(BASE + "/api/v1/translate/stream", {
  method: "POST",
  headers: {"Content-Type": "application/json", "Authorization": "Bearer " + KEY},
  body: JSON.stringify({text, target: "en", engine: "quality"}),
});
// читать r.body построчно: события "event: delta\ndata: {"t": "..."}"

← В переводчик