블로그로 돌아가기
Terminal window showing a Gemfile entry for the PolyLingo gem alongside a short Ruby translate call and its output hash.

PolyLingo 젬으로 Ruby에서 구조화된 콘텐츠 번역하기

By Robert M

PolyLingo gem으로 Ruby에서 구조화된 콘텐츠 번역하기

PolyLingo Ruby gem이 이제 RubyGems에서 제공됩니다. 동기 번역, 배치 요청, 폴링이 포함된 비동기 작업 및 모든 유틸리티 엔드포인트를 모두 포함합니다. 런타임 의존성이 없으며 Ruby 2.7 이상이 필요합니다.

이 게시물에서는 설치, 클라이언트 설정 및 gem에서 사용할 수 있는 모든 메서드를 안내합니다.


설치

Gemfile에 추가하세요:

gem "polylingo"

그런 다음 실행하세요:

bundle install

또는 직접 설치:

gem install polylingo

런타임 의존성이 없습니다. gem은 HTTP에 대해 Ruby 표준 라이브러리만 사용합니다.


클라이언트 설정

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"로 전달할 수도 있습니다.

형식 보존은 다른 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 "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 람다는 각 폴링 시 호출되며 현재 대기열 위치를 정수로 받거나 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 "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를 알려줍니다(알려진 경우).


빠른 참조

메서드엔드포인트인증 필요
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 키 받기