
Переклад структурованого контенту з Ruby за допомогою бібліотеки PolyLingo
By Robert M
Переклад структурованого контенту з Ruby за допомогою PolyLingo gem
PolyLingo Ruby gem тепер доступний на RubyGems. Він охоплює повний API PolyLingo: синхронний переклад, пакетні запити, асинхронні завдання з опитуванням та всі допоміжні кінцеві точки. Не має залежностей під час виконання і вимагає Ruby 2.7 або новішої версії.
Цей допис проходить через встановлення, налаштування клієнта та кожен метод, доступний у gem.
Встановлення
Додайте до вашого Gemfile:
gem "polylingo"
Потім виконайте:
bundle install
Або встановіть безпосередньо:
gem install polylingo
Немає залежностей під час виконання. Gem використовує лише стандартну бібліотеку Ruby для HTTP.
Налаштування клієнта
require "polylingo"
client = PolyLingo.new(api_key: ENV.fetch("POLYLINGO_API_KEY"))
Доступні два необов’язкові параметри:
client = PolyLingo.new(
api_key: ENV.fetch("POLYLINGO_API_KEY"),
base_url: "https://api.usepolylingo.com/v1", # за замовчуванням, змінити для власних інстансів
timeout: 120, # секунди (відкриття + читання), за замовчуванням 120
)
Зберігайте ваш API ключ у змінній середовища. Ніколи не хардкодьте його і не комітьте у систему контролю версій.
Переклад контенту
Одиночний запит
Передайте ваш контент, масив кодів цільових мов та необов’язковий формат:
result = client.translate(
content: "# Hello\n\nThis is **structured** content.",
targets: %w[es fr de],
format: "markdown"
)
puts result["translations"]["es"]
puts result["usage"]["total_tokens"]
Параметр format приймає plain, markdown, json або html. Якщо пропущено, API автоматично визначає формат. Ви також можете передати source як підказку мови та model як "standard" (за замовчуванням) або "advanced".
Збереження формату працює так само, як і в решті API PolyLingo. Для json перекладаються лише рядкові значення, ключі, вкладені структури та не рядкові типи залишаються без змін. Для markdown заголовки залишаються заголовками, а блоки коду залишаються без змін. Для html теги та атрибути зберігаються, перекладаються лише текстові вузли.
Переклад JSON locale файлу
require "json"
source = JSON.parse(File.read("config/locales/en.yml"))
result = client.translate(
content: source.to_json,
format: "json",
targets: %w[fr de ja]
)
%w[fr de ja].each do |locale|
translated = JSON.parse(result["translations"][locale])
File.write(
"config/locales/#{locale}.json",
JSON.pretty_generate(translated)
)
puts "Wrote config/locales/#{locale}.json"
end
Один запит обробляє всі три локалі. Ключі ідентичні джерелу у кожному вихідному файлі.
Пакетні запити
Надішліть до 100 елементів контенту в одному запиті, кожен з власним id та необов’язковим format:
result = client.batch(
items: [
{ id: "hero_title", content: "Welcome back", format: "plain" },
{ id: "hero_subtitle", content: "Here is what changed today", format: "plain" },
{ id: "cta", content: "Get started", format: "plain" },
],
targets: %w[es fr de]
)
result["results"].each do |row|
puts "#{row["id"]}: #{row["translations"]["es"]}"
end
Всі елементи використовують один і той же масив targets. id, який ви передаєте, зберігається у відповіді, щоб ви могли зіставити результати з вашими вихідними даними без залежності від порядку.
Асинхронні завдання
Для довготривалих перекладів API завдань приймає запит, негайно повертає job_id і дозволяє опитувати результат. Gem підтримує це двома способами.
Поміщення в чергу та ручне опитування
accepted = client.jobs.create(
content: File.read("content/long-article.md"),
targets: %w[es fr de ja zh],
format: "markdown"
)
job_id = accepted["job_id"]
loop do
sleep 5
state = client.jobs.get(job_id)
break if %w[complete failed].include?(state["status"])
end
if state["status"] == "complete"
translations = state["translations"]
end
Один виклик, що опитує до завершення
done = client.jobs.translate(
content: File.read("content/long-article.md"),
targets: %w[es fr de],
format: "markdown",
# Необов’язкові перевизначення (показані за замовчуванням):
poll_interval: 5, # секунди між опитуваннями, за замовчуванням 5
timeout: 1200, # загальний час очікування у секундах, за замовчуванням 1200 (20 хвилин)
on_progress: ->(queue_position) { puts "Queue position: #{queue_position.inspect}" }
)
translations = done["translations"]
usage = done["usage"]
Усі часові значення в Ruby gem використовують секунди, відповідно до конвенцій Ruby. Лямбда on_progress виконується при кожному опитуванні і отримує поточну позицію в черзі як ціле число або nil, якщо API не повертає її.
Допоміжні кінцеві точки
health = client.health
# => { "status" => "ok", "timestamp" => "..." }
languages = client.languages
# => { "languages" => [{ "code" => "en", "name" => "English", "rtl" => false }, ...] }
usage = client.usage
# => { "usage" => { "tokens_used" => 12000, "tokens_remaining" => 38000, ... } }
health та languages не потребують API ключа. usage повертає споживання токенів за поточний календарний місяць для автентифікованого акаунта.
Обробка помилок
Всі помилки наслідують від PolyLingo::PolyLingoError. Ловіть конкретні підкласи, які хочете обробити:
begin
result = client.translate(
content: "# Hello",
targets: %w[es],
format: "markdown"
)
rescue PolyLingo::AuthError => e
# HTTP 401 — недійсний, відсутній або відкликаний API ключ
puts "Auth failed: #{e.message}"
rescue PolyLingo::RateLimitError => e
# HTTP 429 — досягнуто ліміт за хвилину
retry_after = e.retry_after # ціле число секунд або nil
sleep retry_after if retry_after
retry
rescue PolyLingo::JobFailedError => e
# Асинхронне завдання досягло статусу помилки або опитування вичерпало час
puts "Job failed: #{e.job_id}"
rescue PolyLingo::PolyLingoError => e
# Всі інші помилки API
puts "#{e.status}: #{e.error} — #{e.message}"
end
RateLimitError#retry_after повертає ціле число з тіла JSON відповіді або заголовка Retry-After, якщо є, або nil, якщо ні. JobFailedError#job_id дає ID невдалого завдання, якщо він відомий.
Швидкий довідник
| Method | Endpoint | Потрібен Auth |
|---|---|---|
client.health | GET /health | Ні |
client.languages | GET /languages | Ні |
client.translate(...) | POST /translate | Так |
client.batch(...) | POST /translate/batch | Так |
client.usage | GET /usage | Так |
client.jobs.create(...) | POST /jobs | Так |
client.jobs.get(job_id) | GET /jobs/:id | Так |
client.jobs.translate(...) | POST /jobs + polling | Так |
Початок роботи
Gem доступний на RubyGems за адресою rubygems.org/gems/polylingo. Вихідний код на github.com/UsePolyLingo/polylingo-ruby. Повна документація API на usepolylingo.com/docs.
Безкоштовний рівень включає 50 000 токенів на місяць. Кредитна картка не потрібна.
gem install polylingo