返回博客
Terminal window showing a Gemfile entry for the PolyLingo gem alongside a short Ruby translate call and its output hash.

使用 PolyLingo gem 从 Ruby 翻译结构化内容

By Robert M

使用 PolyLingo gem 翻译结构化内容

PolyLingo Ruby gem 现已在 RubyGems 上发布。它涵盖了完整的 PolyLingo API 功能:同步翻译、批量请求、带轮询的异步任务以及所有实用端点。它没有运行时依赖,要求 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 参数接受 plainmarkdownjsonhtml。如果省略,API 会自动检测格式。你也可以传入 source 作为语言提示,model 可选 "standard"(默认)或 "advanced"。

格式保留与 PolyLingo API 其他部分相同。对于 json,仅翻译字符串值,键、嵌套和非字符串类型保持不变。对于 markdown,标题保持标题,代码块保持原样。对于 html,标签和属性保留,仅翻译文本节点。

翻译 JSON 本地化文件

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 "写入 config/locales/#{locale}.json"
end

一次请求处理所有三个语言。每个输出文件中的键与源文件相同。


批量请求

单次请求最多发送 100 条内容,每条带有自己的 id 和可选 format

result = client.batch(
  items: [
    { id: "hero_title",    content: "欢迎回来",   format: "plain" },
    { id: "hero_subtitle", content: "今天的变化", format: "plain" },
    { id: "cta",           content: "开始使用",    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.inspect}" }
)

translations = done["translations"]
usage        = done["usage"]

Ruby gem 中所有时间值均以秒为单位,符合 Ruby 习惯。on_progress lambda 在每次轮询时触发,接收当前队列位置(整数),如果 API 未返回则为 nil


实用端点

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, ... } }

healthlanguages 不需要 API 密钥。usage 返回当前日历月认证账户的令牌使用情况。


错误处理

所有错误均继承自 PolyLingo::PolyLingoError。捕获你想处理的具体子类:

begin
  result = client.translate(
    content: "# Hello",
    targets: %w[es],
    format:  "markdown"
  )
rescue PolyLingo::AuthError => e
  # HTTP 401 — 无效、缺失或被撤销的 API 密钥
  puts "认证失败: #{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 "任务失败: #{e.job_id}"
rescue PolyLingo::PolyLingoError => e
  # 其他所有 API 错误
  puts "#{e.status}: #{e.error} — #{e.message}"
end

RateLimitError#retry_after 返回 JSON 响应体或 Retry-After 头中存在的整数秒,若都无则为 nilJobFailedError#job_id 在已知失败任务时返回该任务 ID。


快速参考

方法端点是否需要认证
client.healthGET /health
client.languagesGET /languages
client.translate(...)POST /translate
client.batch(...)POST /translate/batch
client.usageGET /usage
client.jobs.create(...)POST /jobs
client.jobs.get(job_id)GET /jobs/:id
client.jobs.translate(...)POST /jobs + 轮询

开始使用

该 gem 可在 RubyGems 获取:rubygems.org/gems/polylingo。源代码在 github.com/UsePolyLingo/polylingo-ruby。完整 API 文档见 usepolylingo.com/docs

免费套餐每月包含 50,000 令牌,无需信用卡。

gem install polylingo

获取你的 API 密钥