diff --git a/CHANGELOG.md b/CHANGELOG.md index 68320c1..c15d19e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -125,6 +125,12 @@ described below. Everything here is relative to `deepl_diff` 2.2.0. ### Added +- Five more providers, all on the same base class and the same transport: + `:google` (Cloud Translation v2), `:azure` (Azure AI Translator v3.0), + `:modernmt`, `:libretranslate` and `:amazon` (Amazon Translate). Each + declares its own options, its own limits, and what it can actually do -- + see the provider table in the README, which is written from the same + capabilities the library reads at runtime. - A Google provider: `config.provider = :google` translates through Cloud Translation v2 (Basic) over HTTP directly, with no Google gem installed. It declares `google_api_key`, `google_project_id` and `google_api_base`; an API diff --git a/README.md b/README.md index e8c2177..0f4bae0 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,8 @@ See [Getting started](#getting-started) below. ## Installation +Ruby 3.4 or newer is required. + Add this line to your application's Gemfile: ```ruby @@ -189,6 +191,120 @@ runtime: | LibreTranslate | `:libretranslate` | `libretranslate_api_base` | 50 | 5,000 | yes (`format`) | no | yes | no | | Amazon | `:amazon` | `amazon_access_key_id`, `amazon_secret_access_key`, `amazon_region` | 1 | 10,000 | no | no | yes | no | +### Configuring each provider + +Every example below is complete: set the options shown and +`TranslationDiff.translate` works. The option names, and which of them are +required, come from the provider itself -- see [Configuration +options](#configuration-options) for the full list and the environment +variables each one falls back to. + +**DeepL** is the default, so `config.provider` may be omitted. A key ending +in `:fx` is a free-plan key and selects the free host on its own. + +```ruby +TranslationDiff.configure do |config| + config.provider = :deepl + config.deepl_api_key = ENV["DEEPL_AUTH_KEY"] +end + +TranslationDiff.translate("Hello there. Second sentence.", from: "en", to: "ru") +``` + +**Google Cloud Translation** needs an API key and nothing else -- no project, +no service account. + +```ruby +TranslationDiff.configure do |config| + config.provider = :google + config.google_api_key = ENV["TRANSLATE_KEY"] +end +``` + +**Azure AI Translator** wants the region as well when the key belongs to a +multi-service Cognitive Services resource; a single-service Translator +resource needs no region. + +```ruby +TranslationDiff.configure do |config| + config.provider = :azure + config.azure_api_key = ENV["AZURE_TRANSLATOR_KEY"] + config.azure_region = "westeurope" +end +``` + +**ModernMT** takes a key and can be pointed at an adaptive memory per call, +since every unrecognised keyword reaches the provider untouched. + +```ruby +TranslationDiff.configure do |config| + config.provider = :modernmt + config.modernmt_api_key = ENV["MMT_API_KEY"] +end + +TranslationDiff.translate(text, from: "en", to: "ru", hints: "1234") +``` + +**LibreTranslate** inverts the usual arrangement: the base URL is required +because every instance is someone's own, and the key is optional because most +instances ask for none. It is also the only provider here you can run +yourself, which makes it the one to develop against. + +```ruby +TranslationDiff.configure do |config| + config.provider = :libretranslate + config.libretranslate_api_base = "http://localhost:5000" + config.libretranslate_api_key = ENV["LIBRETRANSLATE_KEY"] # optional +end +``` + +```bash +docker run -d --rm -p 5000:5000 libretranslate/libretranslate --load-only en,ru +``` + +**Amazon Translate** is signed rather than keyed, so it takes credentials and +a region. There is no environment fallback: this library does not implement +the AWS credential chain, so `AWS_ACCESS_KEY_ID` and friends are not read -- +pass them explicitly. + +```ruby +TranslationDiff.configure do |config| + config.provider = :amazon + config.amazon_access_key_id = ENV.fetch("AWS_ACCESS_KEY_ID") + config.amazon_secret_access_key = ENV.fetch("AWS_SECRET_ACCESS_KEY") + config.amazon_region = "eu-central-1" +end +``` + +Add `gem "aws-sigv4"` to your Gemfile for this one. It is Amazon's own +signing library and nothing more -- no clients, no service models -- and it +is required lazily, so an application on any other provider never installs it. + +**Null** translates nothing and returns what it was given. It exists so a +pipeline can be wired up, and its cache and instrumentation exercised, before +anyone has paid for a key. + +```ruby +TranslationDiff.configure { |config| config.provider = :null } +``` + +Different providers can be used side by side without disturbing the global +configuration -- `TranslationDiff.context` yields an isolated copy, and +`provider:` overrides one call: + +```ruby +formal = TranslationDiff.context do |config| + config.provider = :deepl + config.deepl_api_key = ENV["DEEPL_AUTH_KEY"] +end +formal.translate(contract, from: "en", to: "de", formality: :more) + +TranslationDiff.translate(blog_post, from: "en", to: "de", provider: :google) +``` + +Both read and write the same cache, keyed per provider, so switching one +never serves you the other's translations. + **Every keyword other than `from:`, `to:`, `provider:` and `config:` is forwarded to the provider, and every provider applies them the same way: its own defaults first, then your options, then the fields the request cannot