Class: TranslationDiff::Providers::Amazon

Inherits:
HTTPProvider
  • Object
show all
Defined in:
lib/translation_diff/providers/amazon.rb

Overview

Amazon Translate: no batch API (one text per call), no HTML mode, and requests are signed, not just headed.

Constant Summary collapse

SERVICE =
"translate".freeze
TARGET =
"AWSShineFrontendService_20170701.TranslateText".freeze
LIST_LANGUAGES =
"AWSShineFrontendService_20170701.ListLanguages".freeze
CONTENT_TYPE =
"application/x-amz-json-1.1".freeze
AUTO =

Amazon's own way of asking for detection; reaches Comprehend under the hood, in regions that have it.

"auto".freeze

Constants inherited from HTTPProvider

HTTPProvider::RETRY_STATUSES, HTTPProvider::TRANSPORT_FAILURES

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from HTTPProvider

#connection, #headers, #parse_translate_response, #render_translate_payload, #translate_url

Class Method Details

.capabilities ⇒ Object



11
12
13
14
15
16
# File 'lib/translation_diff/providers/amazon.rb', line 11

def self.capabilities
  TranslationDiff::Capabilities.new(
    max_request_size: 10_000, max_batch_size: 1, max_text_size: 10_000,
    html: :none, notranslate: false, detects_language: true, reports_billing: false
  )
end

.configuration_options ⇒ Object

Deliberately no environment fallback: this library does not implement the AWS credential chain.



19
20
21
22
# File 'lib/translation_diff/providers/amazon.rb', line 19

def self.configuration_options
  %i[amazon_access_key_id amazon_secret_access_key amazon_session_token
     amazon_region amazon_api_base]
end

.configuration_requirements ⇒ Object



24
25
26
# File 'lib/translation_diff/providers/amazon.rb', line 24

def self.configuration_requirements
  %i[amazon_access_key_id amazon_secret_access_key amazon_region]
end

Instance Method Details

#api_base ⇒ Object



28
# File 'lib/translation_diff/providers/amazon.rb', line 28

def api_base = config.amazon_api_base || "https://#{SERVICE}.#{config.amazon_region}.amazonaws.com"

#detect(text) ⇒ Object



45
46
47
48
# File 'lib/translation_diff/providers/amazon.rb', line 45

def detect(text)
  call(text, TranslationDiff::Translation::Request.new(texts: [text], from: nil, to: "en"))
    .fetch("SourceLanguageCode", nil)&.downcase
end

#languages ⇒ Object

ListLanguages is a signed POST like every other Amazon call; the list serves both directions.



51
52
53
54
55
56
# File 'lib/translation_diff/providers/amazon.rb', line 51

def languages
  body = post_signed(JSON.generate({}), target: LIST_LANGUAGES).body
  codes = Array(body["Languages"]).map { |entry| entry["LanguageCode"] }

  { source: codes, target: codes }
end

#languages_endpoint ⇒ Object

There is no distinct languages URL: every Amazon call, ListLanguages included, is a signed POST to the root.



59
# File 'lib/translation_diff/providers/amazon.rb', line 59

def languages_endpoint = "#{api_base}/"

#translate(request) ⇒ Object

Detected language is the first one Amazon reported: every text in a chunk shares a source language.



31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/translation_diff/providers/amazon.rb', line 31

def translate(request)
  detected = nil
  texts = request.texts.map do |text|
    body = call(text, request)
    detected ||= body["SourceLanguageCode"]&.downcase
    body["TranslatedText"]
  end

  TranslationDiff::Translation::Response.build(
    request: request, texts: texts, detected_source: detected,
    usage: TranslationDiff::Translation::Usage.new(characters: request.texts.sum(&:size))
  )
end