Repository files navigation

Gem Version

DeepL Ruby Library

The DeepL API is a language translation API that allows other computer programs to send texts and documents to DeepL's servers and receive high-quality translations. This opens a whole universe of opportunities for developers: any translation product you can imagine can now be built on top of DeepL's best-in-class translation technology.

The DeepL Ruby library offers a convenient way for applications written in Ruby to interact with the DeepL API. We intend to support all API functions with the library, though support for new features may be added to the library after they’re added to the API.

Getting an authentication key

To use the DeepL Ruby Library, you'll need an API authentication key. To get a key, please create an account here. With a DeepL API Free account you can translate up to 500,000 characters/month for free.

Installation

Install this gem with

gem install deepl-rb
# Load it in your ruby file using `require 'deepl'`

Or add it to your Gemfile:

gem'deepl-rb',require: 'deepl'

Usage

Setup an environment variable named DEEPL_AUTH_KEY with your authentication key:

export DEEPL_AUTH_KEY="your-api-token"

Alternatively, you can configure the API client within a ruby block:

DeepL.configuredo |config|
config.auth_key='your-api-token'end

You can also configure the API host and the API version:

DeepL.configuredo |config|
config.auth_key='your-api-token'config.host='https://api-free.deepl.com'# Default value is 'https://api.deepl.com'config.version='v1'# Default value is 'v2'end

Available languages

Available languages can be retrieved via API:

languages=DeepL.languagesputslanguages.class# => Arrayputslanguages.first.class# => DeepL::Resources::Languageputs"#{languages.first.code} -> #{languages.first.name}"# => "ES -> Spanish"

Note that source and target languages may be different, which can be retrieved by using the type option:

putsDeepL.languages(type: :source).count# => 24putsDeepL.languages(type: :target).count# => 26

All languages are also defined on the official API documentation.

Note that target languages may include the supports_formality flag, which may be checked using the DeepL::Resources::Language#supports_formality?.

Translate

To translate a simple text, use the translate method:

translation=DeepL.translate'This is my text','EN','ES'putstranslation.class# => DeepL::Resources::Textputstranslation.text# => 'Este es mi texto'

Enable auto-detect source language by skipping the source language with nil:

translation=DeepL.translate'This is my text',nil,'ES'putstranslation.detected_source_language# => 'EN'

Translate a list of texts by passing an array as an argument:

texts=['Sample text','Another text']translations=DeepL.translatetexts,'EN','ES'putstranslations.class# => Arrayputstranslations.first.class# => DeepL::Resources::Text

You can also use custom query parameters, like tag_handling, split_sentences, non_splitting_tags or ignore_tags:

translation=DeepL.translate'<p>A sample</p>','EN','ES',tag_handling: 'xml',split_sentences: false,non_splitting_tags: 'h1',ignore_tags: %w[codepre]putstranslation.text# => "<p>Una muestra</p>"

To specify which version of the tag handling algorithm to use, you can use the tag_handling_version parameter:

translation=DeepL.translate'<p>A sample</p>','EN','ES',tag_handling: 'xml',tag_handling_version: 'v2'putstranslation.text# => "<p>Una muestra</p>"

The available values are 'v1' and 'v2'.

To translate with context, simply supply the context parameter:

translation=DeepL.translate'That is hot!','EN','ES',context: 'He did not like the jalapenos in his meal.'putstranslation.text# => "¡Eso es picante!"

To specify a type of translation model to use, you can use the model_type option:

translation=DeepL.translate'That is hot!','EN','DE',model_type: 'quality_optimized'

This would use next-gen translation models for the translation. The available values are

  • 'quality_optimized': use a translation model that maximizes translation quality, at the cost of response time. This option may be unavailable for some language pairs.
  • 'prefer_quality_optimized': use the highest-quality translation model for the given language pair.
  • 'latency_optimized': use a translation model that minimizes response time, at the cost of translation quality.

To translate with custom instructions, supply the custom_instructions parameter:

translation=DeepL.translate'Hello, world!','EN','DE',custom_instructions: ['Use informal language','Be concise']putstranslation.text

Up to 10 custom instructions can be specified, each with a maximum of 300 characters. The target language must be de, en, es, fr, it, ja, ko, zh or any variants. Note that using custom_instructions will automatically use quality_optimized models, and cannot be combined with model_type: 'latency_optimized'.

The following parameters will be automatically converted:

ParameterConversion
preserve_formattingConverts false to '0' and true to '1'
split_sentencesConverts false to '0' and true to '1'
outline_detectionConverts false to '0' and true to '1'
splitting_tagsConverts arrays to strings joining by commas
non_splitting_tagsConverts arrays to strings joining by commas
ignore_tagsConverts arrays to strings joining by commas
formalityNo conversion applied
glossary_idNo conversion applied
style_ruleNo conversion applied (can be a string ID or a StyleRule object)
translation_memoryNo conversion applied (can be a string ID or a TranslationMemory object)
translation_memory_thresholdNo conversion applied (integer 0-100, recommended minimum 75)
contextNo conversion applied
custom_instructionsNo conversion applied
tag_handling_versionNo conversion applied
extra_body_parametersHash of extra parameters to pass in the body of the HTTP request. Can be used to access beta features, or to override built-in parameters for testing purposes. Extra parameters can override keys explicitly set by the client.

Rephrase Text

To rephrase or improve text, including changing the writing style or tone of the text, use the rephrase method:

rephrased_text=DeepL.rephrase'you will acquire new rephrased text','EN'putsrephrased_text.class# => DeepL::Resources::Textputsrephrased_text.text# => 'You get new rephrased text.'

As with translate, the text input can be a single string or an array of strings.

You can use the additional arguments to specify the writing style or tone you want for the rephrased text:

rephrased_text=DeepL.rephrase'you will acquire new rephrased text','EN','casual'putsrephrased_text.text# => 'You'll get new, rephrased text.'
rephrased_text=DeepL.rephrase'you will acquire new rephrased text','EN',nil,'friendly'putsrephrased_text.text# => 'You'll get to enjoy new, rephrased text!'

Glossaries

To create a glossary, use the glossaries.create method. The glossary entries argument should be an array of text pairs. Each pair includes the source and the target translations.

entries=[['Hello World','Hola Tierra'],['car','auto']]glossary=DeepL.glossaries.create'Mi Glosario','EN','ES',entriesputsglossary.class# => DeepL::Resources::Glossaryputsglossary.id# => 'aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e'putsglossary.entry_count# => 2

Created glossaries can be used in the translate method by specifying the glossary_id option:

translation=DeepL.translate'Hello World','EN','ES',glossary_id: 'aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e'putstranslation.class# => DeepL::Resources::Textputstranslation.text# => 'Hola Tierra'translation=DeepL.translate"I wish we had a car.",'EN','ES',glossary_id: 'aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e'putstranslation.class# => DeepL::Resources::Textputstranslation.text# => Ojalá tuviéramos un auto.

To use more than one glossary at once, specify the glossary_ids option with an array of up to 5 glossary IDs (as strings or DeepL::Resources::Glossary objects) instead of glossary_id. This works for both text and document translation. glossary_ids requires source_lang to be set, cannot be combined with glossary_id, and raises ArgumentError if these rules are violated or more than 5 IDs are provided:

# Text translation with multiple glossariestranslation=DeepL.translate'Hello World','EN','ES',glossary_ids: ['aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e','bb59d8g1-1e13-524f-9b17-e6ccg1db8b7f']# Document translation with multiple glossarieshandle=DeepL.document.upload'my_document.docx','EN','ES','my_document.docx',glossary_ids: ['aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e','bb59d8g1-1e13-524f-9b17-e6ccg1db8b7f']

To list all the glossaries available, use the glossaries.list method:

glossaries=DeepL.glossaries.listputsglossaries.class# => Arrayputsglossaries.first.class# => DeepL::Resources::Glossary

To find an existing glossary, use the glossaries.find method:

glossary=DeepL.glossaries.find'aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e'putsglossary.class# => DeepL::Resources::Glossary

The glossary resource does not include the glossary entries. To list the glossary entries, use the glossaries.entries method:

entries=DeepL.glossaries.entries'aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e'putsentries.class# => Arrayputsentries.size# => 2ppentries.first# => ["Hello World", "Hola Tierra"]

To delete an existing glossary, use the glossaries.destroy method:

glossary_id=DeepL.glossaries.destroy'aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e'putsglossary_id# => aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e

You can list all the language pairs supported by glossaries using the glossaries.language_pairs method:

language_pairs=DeepL.glossaries.language_pairsputslanguage_pairs.class# => Arrayputslanguage_pairs.first.class# => DeepL::Resources::LanguagePairputslanguage_pairs.first.source_lang# => enputslanguage_pairs.first.target_lang# => de

Style Rules

Style rules allow you to customize your translations using a managed, shared list of rules for style, formatting, and more. Multiple style rules can be stored with your account, each with a user-specified name and a uniquely-assigned ID.

Creating a style rule

Use create to create a new style rule with a name and language code. You can optionally provide configured_rules and custom_instructions.

# Simple creation with just a name and languagestyle_rule=DeepL.style_rules.create('My Style Rule','en')puts"Created: #{style_rule.name} (#{style_rule.style_id})"# Creation with configured rules and custom instructionsstyle_rule=DeepL.style_rules.create('Formal English','en',configured_rules: {style_and_tone: {formality: 'formal'}},custom_instructions: [{label: 'Tone',prompt: 'Always use formal language'}])

Retrieving and listing style rules

Use find to retrieve a single style rule by ID, or list to list all style rules.

list returns a list of StyleRule objects corresponding to all of your stored style rules. The method accepts optional parameters: page (page number for pagination, 0-indexed), page_size (number of items per page), and detailed. When true, the response includes configured_rules and custom_instructions for each style rule. When false (default), these fields are omitted for faster responses.

# Get a single style rule by IDstyle_rule=DeepL.style_rules.find('YOUR_STYLE_ID')puts"#{style_rule.name} (#{style_rule.language})"# List all style rulesstyle_rules=DeepL.style_rules.liststyle_rules.eachdo |rule|
puts"#{rule.name} (#{rule.style_id})"end# List with paginationstyle_rules=DeepL.style_rules.list(page: 0,page_size: 10)# List with detailed configurationstyle_rules=DeepL.style_rules.list(detailed: true)style_rules.eachdo |rule|
ifrule.configured_rulesputs" Number formatting: #{rule.configured_rules.numbers.keys.join(', ')}"endend

Updating a style rule

Use update_name to rename a style rule, and update_configured_rules to update its configured rules.

# Update the nameupdated=DeepL.style_rules.update_name('YOUR_STYLE_ID','New Name')# Update configured rulesupdated=DeepL.style_rules.update_configured_rules('YOUR_STYLE_ID',{style_and_tone: {formality: 'formal'}})

The configured_rules hash supports the following categories: dates_and_times, formatting, numbers, punctuation, spelling_and_grammar, style_and_tone, and vocabulary.

Managing custom instructions

Custom instructions allow you to add free-text prompts to a style rule. Each instruction has an id, label, prompt, and source_language. Use create_custom_instruction, find_custom_instruction, update_custom_instruction, and destroy_custom_instruction to manage them.

# Create a custom instructioninstruction=DeepL.style_rules.create_custom_instruction('YOUR_STYLE_ID','Formal tone','Always use formal language')puts"Created instruction: #{instruction.id}"# Create with an optional source languageinstruction=DeepL.style_rules.create_custom_instruction('YOUR_STYLE_ID','Formal tone','Always use formal language','en')# Get a custom instructioninstruction=DeepL.style_rules.find_custom_instruction('YOUR_STYLE_ID',instruction.id)# Update a custom instructionupdated=DeepL.style_rules.update_custom_instruction('YOUR_STYLE_ID',instruction.id,'Updated label','Use very formal language')# Delete a custom instructionDeepL.style_rules.destroy_custom_instruction('YOUR_STYLE_ID',instruction.id)

Deleting a style rule

Use destroy to delete a style rule by ID.

DeepL.style_rules.destroy('YOUR_STYLE_ID')

Using style rules in translations

Style rules can be used in the translate method by specifying the style_rule option with either a style rule ID string or a StyleRule object:

# Using a style rule IDtranslation=DeepL.translate'Hello World','EN','ES',style_rule: 'dca2e053-8ae5-45e6-a0d2-881156e7f4e4'# Or using a StyleRule objectstyle_rules=DeepL.style_rules.listtranslation=DeepL.translate'Hello World','EN','ES',style_rule: style_rules.first

The same style_rule option can be passed to document translation via DeepL.document.upload (or DeepL.document.translate_document), accepting either a style rule ID string or a StyleRule object:

handle=DeepL.document.upload'my_document.docx','EN','ES','my_document.docx',style_rule: 'dca2e053-8ae5-45e6-a0d2-881156e7f4e4'

Translation Memories

Translation memories allow you to store and reuse previously created translations. They can be used in text translation requests to improve consistency by matching against stored segments. Multiple translation memories can be stored with your account, each with a source language and one or more target languages.

Translation memories can also be managed in the DeepL UI via https://www.deepl.com/translation-memory.

Every method that takes a translation memory accepts either a string containing the translation memory ID or a TranslationMemory object.

Listing translation memories

translation_memories.list returns a list of TranslationMemory objects for your stored translation memories. The method accepts optional parameters: page (page number for pagination, 0-indexed) and page_size (number of items per page, max 25).

# List translation memoriestranslation_memories=DeepL.translation_memories.listtranslation_memories.eachdo |tm|
puts"#{tm.name} (#{tm.translation_memory_id})"puts" Source: #{tm.source_language}, Targets: #{tm.target_languages.join(', ')}"puts" Segments: #{tm.segment_count}"end# List with paginationtranslation_memories=DeepL.translation_memories.list(page: 0,page_size: 10)

Retrieving a single translation memory

translation_memories.find retrieves one translation memory by ID. In addition to the fields returned by list, the resource carries the creation_time and updated_time timestamps.

tm=DeepL.translation_memories.find'YOUR_TM_ID'putstm.class# => DeepL::Resources::TranslationMemoryputstm.name# => 'Legal'putstm.segment_count# => 12putstm.creation_time.class# => Time

Listing the segments of a translation memory

translation_memories.segments returns one page of the segments of a translation memory as a TranslationMemorySegments object. Each segment holds the source text and one target per target language of the translation memory.

Pagination is cursor-based: omit page_cursor on the first call, then pass the next_page_cursor of the previous response until next_page? is false. The method also accepts page_size (1-100, defaults to 50), filter_text (a substring matched against the source and target texts, at least 2 characters) and filter_case_sensitive (defaults to false).

Note that segment_count is the number of segments stored in the translation memory; a text filter does not reduce it.

page=DeepL.translation_memories.segments'YOUR_TM_ID',page_size: 50putspage.class# => DeepL::Resources::TranslationMemorySegmentsputspage.segment_count# => 12putspage.segments.first.source_text# => 'Quelltext Nummer 0'putspage.segments.first.targets.first.target_text# => 'Source text number 0'# Walk through every page of segmentswhilepage.next_page?page=DeepL.translation_memories.segments'YOUR_TM_ID',page_size: 50,page_cursor: page.next_page_cursorend# Only the segments matching a textpage=DeepL.translation_memories.segments'YOUR_TM_ID',filter_text: 'Nummer 1',filter_case_sensitive: true

Importing a translation memory

translation_memories.import_from_filepath creates a new translation memory from a TMX file. It creates the import job, uploads the file and waits for the processing to finish, and returns the finished TranslationMemoryJob. Its result carries the ID of the newly created translation memory.

job=DeepL.translation_memories.import_from_filepath'legal.tmx',display_name: 'Legal',timeout_s: 300putsjob.class# => DeepL::Resources::TranslationMemoryJobputsjob.status# => 'completed'putsjob.result.translation_memory_id# => 'a74d88fb-ed2a-4943-a664-a4512398b994'putsjob.result.skipped_segment_count# => 0

The three steps can also be performed separately, for example to upload a file that is not available on the local file system. The upload URL is a pre-signed storage URL outside of the DeepL API, so no authorization header is sent with the upload.

content=File.binread'legal.tmx'created=DeepL.translation_memories.create_import'legal.tmx',content.bytesize,content_type: 'application/xml',display_name: 'Legal'putscreated.upload_url# => 'https://...'DeepL.translation_memories.upload_filecreated,contentjob=DeepL.translation_memories.wait_until_job_donecreated.job_id

Until the file is uploaded the job stays in the awaiting_input status and result.required_action describes what is missing. The API detects the upload asynchronously, so the job keeps reporting awaiting_input for a while afterwards, typically around half a minute, before it completes. wait_until_job_done therefore polls through that status like any other non-terminal one. A job whose file is never uploaded does not finish on its own, so pass timeout_s when that is a possibility.

Exporting a translation memory

translation_memories.export_to_filepath writes a translation memory to a TMX file. It creates the export job, waits for it to finish and downloads the result, overwriting the output file if it already exists.

job=DeepL.translation_memories.export_to_filepath'YOUR_TM_ID','export.tmx'putsjob.status# => 'completed'

The steps can be performed separately as well. Repeating the export of an unchanged translation memory reuses the previously completed job instead of starting a new one, which reused_existing? reports. Just like the upload URL, the download URL is a pre-signed storage URL and is requested without an authorization header.

created=DeepL.translation_memories.create_export'YOUR_TM_ID'putscreated.reused_existing?# => falsejob=DeepL.translation_memories.wait_until_job_donecreated.job_idputsjob.result.download_url# => 'https://...'DeepL.translation_memories.download_exportjob,'export.tmx'

Tracking import and export jobs

translation_memories.find_job returns the current status of an import or export job, and translation_memories.wait_until_job_done polls it every five seconds until it finished, raising if the job failed or expired. Pass timeout_s to give up after a number of seconds instead of waiting forever.

job=DeepL.translation_memories.find_job'YOUR_JOB_ID'putsjob.operation# => 'import'putsjob.status# => 'processing'putsjob.finished?# => false

The status is one of awaiting_input, processing, completed, downloaded, failed or expired.

Deleting a translation memory

translation_memories.destroy deletes a translation memory and returns its ID.

DeepL.translation_memories.destroy'YOUR_TM_ID'# => 'YOUR_TM_ID'

Using a translation memory in translations

Pass the translation_memory parameter to translate to use a translation memory. You can pass either a string containing the translation memory ID, or a TranslationMemory object. Use translation_memory_threshold to control the minimum matching percentage for fuzzy matches (0-100, recommended minimum of 75%).

# Using a translation memory IDtranslation=DeepL.translate'Hello, world!','EN','DE',translation_memory: 'YOUR_TM_ID',translation_memory_threshold: 80# Or using a TranslationMemory objecttranslation_memories=DeepL.translation_memories.listtranslation=DeepL.translate'Hello, world!','EN','DE',translation_memory: translation_memories.first

The same translation_memory and translation_memory_threshold options can be passed to document translation via DeepL.document.upload (or DeepL.document.translate_document). The translation_memory option accepts either a translation memory ID string or a TranslationMemory object:

handle=DeepL.document.upload'my_document.docx','EN','DE','my_document.docx',translation_memory: 'YOUR_TM_ID',translation_memory_threshold: 80

Monitor usage

To check current API usage, use:

usage=DeepL.usageputsusage.character_count# => 180118putsusage.character_limit# => 1250000

Translate documents

To translate a document, use the document.translate_document method. Example:

DeepL.document.translate_document('/path/to/spanish_document.pdf','/path/to/translated_document.pdf','ES','EN')

The lower level upload, get_status and download methods are also exposed, as well as the convenience method wait_until_document_translation_finished on the DocumentHandle object, which would replace get_status:

doc_handle=DeepL.document.upload('/path/to/spanish_document.pdf','ES','EN')doc_status=doc_handle.wait_until_document_translation_finished# alternatively poll `DeepL.document.get_status`# until the `doc_status.successful?`DeepL.document.download(doc_handle,'/path/to/translated_document.pdf')unlessdoc_status.error?

You can also pass additional options to document translation methods, including extra_body_parameters:

options={formality: 'more',extra_body_parameters: {example_param: 'true'}}doc_handle=DeepL.document.upload('/path/to/spanish_document.pdf','ES','EN',nil,options)

The extra_body_parameters option allows you to pass arbitrary parameters in the request body. This can be used to access beta features by adding new parameters, or to override built-in parameters (such as target_lang, source_lang, etc.) for testing purposes.

Sending additional HTTP headers

You can pass additional HTTP headers to translate, rephrase, and the document methods. For example, to send the X-DeepL-Reporting-Tag header for usage reporting (see the cookbook entry):

additional_headers={'X-DeepL-Reporting-Tag'=>'my-tag'}translation=DeepL.translate'Hello, world!','EN','DE',{},additional_headersrephrased=DeepL.rephrase'Hello, world!','EN',nil,nil,{},additional_headers

Handle exceptions

You can capture and process exceptions that may be raised during API calls. These are all the possible exceptions:

Exception classDescription
DeepL::Exceptions::AuthorizationFailedThe authorization process has failed. Check your auth_key value.
DeepL::Exceptions::BadRequestSomething is wrong in your request. Check exception.message for more information.
DeepL::Exceptions::DocumentTranslationErrorAn error occured during document translation. Check exception.message for more information.
DeepL::Exceptions::LimitExceededYou've reached the API's call limit.
DeepL::Exceptions::QuotaExceededYou've reached the API's character limit.
DeepL::Exceptions::RequestErrorAn unkown request error. Check exception.response and exception.request for more information.
DeepL::Exceptions::NotSupportedThe requested method or API endpoint is not supported.
DeepL::Exceptions::RequestEntityTooLargeYour request is too large, reduce the amount of data you are sending. The API has a request size limit of 128 KiB.
DeepL::Exceptions::ServerErrorAn error occured in the DeepL API, wait a short amount of time and retry.

An exampling of handling a generic exception:

defmy_methoditem=DeepL.translate'This is my text',nil,'ES'rescueDeepL::Exceptions::RequestError=>eputs'Oops!'puts"Code: #{e.response.code}"puts"Response body: #{e.response.body}"puts"Request body: #{e.request.body}"end

Logging

To enable logging, pass a suitable logging object (e.g. the default Logger from the Ruby standard library) when configuring the library. The library logs HTTP requests to INFO and debug information to DEBUG. Example:

require'logger'logger=Logger.new(STDOUT)logger.level=Logger::INFOdeepl.configuredo |config|
config.auth_key=configuration.auth_keyconfig.logger=loggerend

Proxy configuration

To use HTTP proxies, a session needs to be used. The proxy can then be configured as part of the HTTP client options:

client_options=HTTPClientOptions.new({'proxy_addr'=>'http://localhost','proxy_port'=>80})deepl.with_session(client_options)do |session|
# ...end

Anonymous platform information

By default, we send some basic information about the platform the client library is running on with each request, see here for an explanation. This data is completely anonymous and only used to improve our product, not track any individual users. If you do not wish to send this data, you can opt-out by setting the send_platform_info flag in the configuration to false like so:

deepl.configure({},nil,nil,false)do |config|
# ...end

You can also complete customize the User-Agent header like so:

deepl.configuredo |config|
config.user_agent='myCustomUserAgent'end

Sending multiple requests

When writing an application that send multiple requests, using a HTTP session will give better performance through HTTP Keep-Alive. You can use it by simply wrapping your requests in a with_session block:

deepl.with_sessiondo |session|
deepl.translate(sentence1,'DE','EN-GB')deepl.translate(sentence2,'DE','EN-GB')deepl.translate(sentence3,'DE','EN-GB')end

Writing a plugin

If you use this library in an application, please identify the application by setting the name and version of the plugin:

deepl.configure({},'MyTranslationPlugin','1.0.1')do |config|
# ...end

This information is passed along when the library makes calls to the DeepL API. Both name and version are required. Please note that setting the User-Agent header via deepl.configure will override this setting, if you need to use this, please manually identify your Application in the User-Agent header.

Options Constants

The available values for various possible options are provided under the DeepL::Constants namespace. The currently available options are

TagHandlingSplitSentencesModelTypeFormalityWritingStyleTone

To view all the possible options for a given constant, call options:

all_available_tones=DeepL::Constants::Tones.options

To check if a given string is a possible option for a given constant, call valid?:

DeepL::Constants::Tones.valid?('friendly')# trueDeepL::Constants::Tones.valid?('rude')# false

Integrations

Ruby on Rails

You may use this gem as a standalone service by creating an initializer on your config/initializers folder with your DeepL configuration. For example:

# config/initializers/deepl.rbDeepL.configuredo |config|
# Your configuration goes hereend

Since the DeepL service is defined globally, you can use service anywhere in your code (controllers, models, views, jobs, plain ruby objects… you name it).

i18n-tasks

You may also take a look at i18n-tasks, which is a gem that helps you find and manage missing and unused translations. deepl-rb is used as one of the backend services to translate content.

Development

Clone the repository, and install its dependencies:

git clone https://github.com/DeepLcom/deepl-rb
cd deepl-rb
bundle install

To run tests (rspec and rubocop), use

bundle exec rake test

Acknowledgements

This library was originally developed by Daniel Herzog, we are grateful for his contributions. Beginning with v3.0.0, DeepL took over development and officially supports and maintains the library together with Daniel.

About

Official Ruby library for the DeepL language translation API.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

19 stars

Watchers

1 watching

Forks

Releases

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

Gem Version

DeepL Ruby Library

The DeepL API is a language translation API that allows other computer programs to send texts and documents to DeepL's servers and receive high-quality translations. This opens a whole universe of opportunities for developers: any translation product you can imagine can now be built on top of DeepL's best-in-class translation technology.

The DeepL Ruby library offers a convenient way for applications written in Ruby to interact with the DeepL API. We intend to support all API functions with the library, though support for new features may be added to the library after they’re added to the API.

Getting an authentication key

To use the DeepL Ruby Library, you'll need an API authentication key. To get a key, please create an account here. With a DeepL API Free account you can translate up to 500,000 characters/month for free.

Installation

Install this gem with

gem install deepl-rb
# Load it in your ruby file using `require 'deepl'`

Or add it to your Gemfile:

gem'deepl-rb',require: 'deepl'

Usage

Setup an environment variable named DEEPL_AUTH_KEY with your authentication key:

export DEEPL_AUTH_KEY="your-api-token"

Alternatively, you can configure the API client within a ruby block:

DeepL.configuredo |config|
config.auth_key='your-api-token'end

You can also configure the API host and the API version:

DeepL.configuredo |config|
config.auth_key='your-api-token'config.host='https://api-free.deepl.com'# Default value is 'https://api.deepl.com'config.version='v1'# Default value is 'v2'end

Available languages

Available languages can be retrieved via API:

languages=DeepL.languagesputslanguages.class# => Arrayputslanguages.first.class# => DeepL::Resources::Languageputs"#{languages.first.code} -> #{languages.first.name}"# => "ES -> Spanish"

Note that source and target languages may be different, which can be retrieved by using the type option:

putsDeepL.languages(type: :source).count# => 24putsDeepL.languages(type: :target).count# => 26

All languages are also defined on the official API documentation.

Note that target languages may include the supports_formality flag, which may be checked using the DeepL::Resources::Language#supports_formality?.

Translate

To translate a simple text, use the translate method:

translation=DeepL.translate'This is my text','EN','ES'putstranslation.class# => DeepL::Resources::Textputstranslation.text# => 'Este es mi texto'

Enable auto-detect source language by skipping the source language with nil:

translation=DeepL.translate'This is my text',nil,'ES'putstranslation.detected_source_language# => 'EN'

Translate a list of texts by passing an array as an argument:

texts=['Sample text','Another text']translations=DeepL.translatetexts,'EN','ES'putstranslations.class# => Arrayputstranslations.first.class# => DeepL::Resources::Text

You can also use custom query parameters, like tag_handling, split_sentences, non_splitting_tags or ignore_tags:

translation=DeepL.translate'<p>A sample</p>','EN','ES',tag_handling: 'xml',split_sentences: false,non_splitting_tags: 'h1',ignore_tags: %w[codepre]putstranslation.text# => "<p>Una muestra</p>"

To specify which version of the tag handling algorithm to use, you can use the tag_handling_version parameter:

translation=DeepL.translate'<p>A sample</p>','EN','ES',tag_handling: 'xml',tag_handling_version: 'v2'putstranslation.text# => "<p>Una muestra</p>"

The available values are 'v1' and 'v2'.

To translate with context, simply supply the context parameter:

translation=DeepL.translate'That is hot!','EN','ES',context: 'He did not like the jalapenos in his meal.'putstranslation.text# => "¡Eso es picante!"

To specify a type of translation model to use, you can use the model_type option:

translation=DeepL.translate'That is hot!','EN','DE',model_type: 'quality_optimized'

This would use next-gen translation models for the translation. The available values are

  • 'quality_optimized': use a translation model that maximizes translation quality, at the cost of response time. This option may be unavailable for some language pairs.
  • 'prefer_quality_optimized': use the highest-quality translation model for the given language pair.
  • 'latency_optimized': use a translation model that minimizes response time, at the cost of translation quality.

To translate with custom instructions, supply the custom_instructions parameter:

translation=DeepL.translate'Hello, world!','EN','DE',custom_instructions: ['Use informal language','Be concise']putstranslation.text

Up to 10 custom instructions can be specified, each with a maximum of 300 characters. The target language must be de, en, es, fr, it, ja, ko, zh or any variants. Note that using custom_instructions will automatically use quality_optimized models, and cannot be combined with model_type: 'latency_optimized'.

The following parameters will be automatically converted:

ParameterConversion
preserve_formattingConverts false to '0' and true to '1'
split_sentencesConverts false to '0' and true to '1'
outline_detectionConverts false to '0' and true to '1'
splitting_tagsConverts arrays to strings joining by commas
non_splitting_tagsConverts arrays to strings joining by commas
ignore_tagsConverts arrays to strings joining by commas
formalityNo conversion applied
glossary_idNo conversion applied
style_ruleNo conversion applied (can be a string ID or a StyleRule object)
translation_memoryNo conversion applied (can be a string ID or a TranslationMemory object)
translation_memory_thresholdNo conversion applied (integer 0-100, recommended minimum 75)
contextNo conversion applied
custom_instructionsNo conversion applied
tag_handling_versionNo conversion applied
extra_body_parametersHash of extra parameters to pass in the body of the HTTP request. Can be used to access beta features, or to override built-in parameters for testing purposes. Extra parameters can override keys explicitly set by the client.

Rephrase Text

To rephrase or improve text, including changing the writing style or tone of the text, use the rephrase method:

rephrased_text=DeepL.rephrase'you will acquire new rephrased text','EN'putsrephrased_text.class# => DeepL::Resources::Textputsrephrased_text.text# => 'You get new rephrased text.'

As with translate, the text input can be a single string or an array of strings.

You can use the additional arguments to specify the writing style or tone you want for the rephrased text:

rephrased_text=DeepL.rephrase'you will acquire new rephrased text','EN','casual'putsrephrased_text.text# => 'You'll get new, rephrased text.'
rephrased_text=DeepL.rephrase'you will acquire new rephrased text','EN',nil,'friendly'putsrephrased_text.text# => 'You'll get to enjoy new, rephrased text!'

Glossaries

To create a glossary, use the glossaries.create method. The glossary entries argument should be an array of text pairs. Each pair includes the source and the target translations.

entries=[['Hello World','Hola Tierra'],['car','auto']]glossary=DeepL.glossaries.create'Mi Glosario','EN','ES',entriesputsglossary.class# => DeepL::Resources::Glossaryputsglossary.id# => 'aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e'putsglossary.entry_count# => 2

Created glossaries can be used in the translate method by specifying the glossary_id option:

translation=DeepL.translate'Hello World','EN','ES',glossary_id: 'aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e'putstranslation.class# => DeepL::Resources::Textputstranslation.text# => 'Hola Tierra'translation=DeepL.translate"I wish we had a car.",'EN','ES',glossary_id: 'aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e'putstranslation.class# => DeepL::Resources::Textputstranslation.text# => Ojalá tuviéramos un auto.

To use more than one glossary at once, specify the glossary_ids option with an array of up to 5 glossary IDs (as strings or DeepL::Resources::Glossary objects) instead of glossary_id. This works for both text and document translation. glossary_ids requires source_lang to be set, cannot be combined with glossary_id, and raises ArgumentError if these rules are violated or more than 5 IDs are provided:

# Text translation with multiple glossariestranslation=DeepL.translate'Hello World','EN','ES',glossary_ids: ['aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e','bb59d8g1-1e13-524f-9b17-e6ccg1db8b7f']# Document translation with multiple glossarieshandle=DeepL.document.upload'my_document.docx','EN','ES','my_document.docx',glossary_ids: ['aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e','bb59d8g1-1e13-524f-9b17-e6ccg1db8b7f']

To list all the glossaries available, use the glossaries.list method:

glossaries=DeepL.glossaries.listputsglossaries.class# => Arrayputsglossaries.first.class# => DeepL::Resources::Glossary

To find an existing glossary, use the glossaries.find method:

glossary=DeepL.glossaries.find'aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e'putsglossary.class# => DeepL::Resources::Glossary

The glossary resource does not include the glossary entries. To list the glossary entries, use the glossaries.entries method:

entries=DeepL.glossaries.entries'aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e'putsentries.class# => Arrayputsentries.size# => 2ppentries.first# => ["Hello World", "Hola Tierra"]

To delete an existing glossary, use the glossaries.destroy method:

glossary_id=DeepL.glossaries.destroy'aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e'putsglossary_id# => aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e

You can list all the language pairs supported by glossaries using the glossaries.language_pairs method:

language_pairs=DeepL.glossaries.language_pairsputslanguage_pairs.class# => Arrayputslanguage_pairs.first.class# => DeepL::Resources::LanguagePairputslanguage_pairs.first.source_lang# => enputslanguage_pairs.first.target_lang# => de

Style Rules

Style rules allow you to customize your translations using a managed, shared list of rules for style, formatting, and more. Multiple style rules can be stored with your account, each with a user-specified name and a uniquely-assigned ID.

Creating a style rule

Use create to create a new style rule with a name and language code. You can optionally provide configured_rules and custom_instructions.

# Simple creation with just a name and languagestyle_rule=DeepL.style_rules.create('My Style Rule','en')puts"Created: #{style_rule.name} (#{style_rule.style_id})"# Creation with configured rules and custom instructionsstyle_rule=DeepL.style_rules.create('Formal English','en',configured_rules: {style_and_tone: {formality: 'formal'}},custom_instructions: [{label: 'Tone',prompt: 'Always use formal language'}])

Retrieving and listing style rules

Use find to retrieve a single style rule by ID, or list to list all style rules.

list returns a list of StyleRule objects corresponding to all of your stored style rules. The method accepts optional parameters: page (page number for pagination, 0-indexed), page_size (number of items per page), and detailed. When true, the response includes configured_rules and custom_instructions for each style rule. When false (default), these fields are omitted for faster responses.

# Get a single style rule by IDstyle_rule=DeepL.style_rules.find('YOUR_STYLE_ID')puts"#{style_rule.name} (#{style_rule.language})"# List all style rulesstyle_rules=DeepL.style_rules.liststyle_rules.eachdo |rule|
puts"#{rule.name} (#{rule.style_id})"end# List with paginationstyle_rules=DeepL.style_rules.list(page: 0,page_size: 10)# List with detailed configurationstyle_rules=DeepL.style_rules.list(detailed: true)style_rules.eachdo |rule|
ifrule.configured_rulesputs" Number formatting: #{rule.configured_rules.numbers.keys.join(', ')}"endend

Updating a style rule

Use update_name to rename a style rule, and update_configured_rules to update its configured rules.

# Update the nameupdated=DeepL.style_rules.update_name('YOUR_STYLE_ID','New Name')# Update configured rulesupdated=DeepL.style_rules.update_configured_rules('YOUR_STYLE_ID',{style_and_tone: {formality: 'formal'}})

The configured_rules hash supports the following categories: dates_and_times, formatting, numbers, punctuation, spelling_and_grammar, style_and_tone, and vocabulary.

Managing custom instructions

Custom instructions allow you to add free-text prompts to a style rule. Each instruction has an id, label, prompt, and source_language. Use create_custom_instruction, find_custom_instruction, update_custom_instruction, and destroy_custom_instruction to manage them.

# Create a custom instructioninstruction=DeepL.style_rules.create_custom_instruction('YOUR_STYLE_ID','Formal tone','Always use formal language')puts"Created instruction: #{instruction.id}"# Create with an optional source languageinstruction=DeepL.style_rules.create_custom_instruction('YOUR_STYLE_ID','Formal tone','Always use formal language','en')# Get a custom instructioninstruction=DeepL.style_rules.find_custom_instruction('YOUR_STYLE_ID',instruction.id)# Update a custom instructionupdated=DeepL.style_rules.update_custom_instruction('YOUR_STYLE_ID',instruction.id,'Updated label','Use very formal language')# Delete a custom instructionDeepL.style_rules.destroy_custom_instruction('YOUR_STYLE_ID',instruction.id)

Deleting a style rule

Use destroy to delete a style rule by ID.

DeepL.style_rules.destroy('YOUR_STYLE_ID')

Using style rules in translations

Style rules can be used in the translate method by specifying the style_rule option with either a style rule ID string or a StyleRule object:

# Using a style rule IDtranslation=DeepL.translate'Hello World','EN','ES',style_rule: 'dca2e053-8ae5-45e6-a0d2-881156e7f4e4'# Or using a StyleRule objectstyle_rules=DeepL.style_rules.listtranslation=DeepL.translate'Hello World','EN','ES',style_rule: style_rules.first

The same style_rule option can be passed to document translation via DeepL.document.upload (or DeepL.document.translate_document), accepting either a style rule ID string or a StyleRule object:

handle=DeepL.document.upload'my_document.docx','EN','ES','my_document.docx',style_rule: 'dca2e053-8ae5-45e6-a0d2-881156e7f4e4'

Translation Memories

Translation memories allow you to store and reuse previously created translations. They can be used in text translation requests to improve consistency by matching against stored segments. Multiple translation memories can be stored with your account, each with a source language and one or more target languages.

Translation memories can also be managed in the DeepL UI via https://www.deepl.com/translation-memory.

Every method that takes a translation memory accepts either a string containing the translation memory ID or a TranslationMemory object.

Listing translation memories

translation_memories.list returns a list of TranslationMemory objects for your stored translation memories. The method accepts optional parameters: page (page number for pagination, 0-indexed) and page_size (number of items per page, max 25).

# List translation memoriestranslation_memories=DeepL.translation_memories.listtranslation_memories.eachdo |tm|
puts"#{tm.name} (#{tm.translation_memory_id})"puts" Source: #{tm.source_language}, Targets: #{tm.target_languages.join(', ')}"puts" Segments: #{tm.segment_count}"end# List with paginationtranslation_memories=DeepL.translation_memories.list(page: 0,page_size: 10)

Retrieving a single translation memory

translation_memories.find retrieves one translation memory by ID. In addition to the fields returned by list, the resource carries the creation_time and updated_time timestamps.

tm=DeepL.translation_memories.find'YOUR_TM_ID'putstm.class# => DeepL::Resources::TranslationMemoryputstm.name# => 'Legal'putstm.segment_count# => 12putstm.creation_time.class# => Time

Listing the segments of a translation memory

translation_memories.segments returns one page of the segments of a translation memory as a TranslationMemorySegments object. Each segment holds the source text and one target per target language of the translation memory.

Pagination is cursor-based: omit page_cursor on the first call, then pass the next_page_cursor of the previous response until next_page? is false. The method also accepts page_size (1-100, defaults to 50), filter_text (a substring matched against the source and target texts, at least 2 characters) and filter_case_sensitive (defaults to false).

Note that segment_count is the number of segments stored in the translation memory; a text filter does not reduce it.

page=DeepL.translation_memories.segments'YOUR_TM_ID',page_size: 50putspage.class# => DeepL::Resources::TranslationMemorySegmentsputspage.segment_count# => 12putspage.segments.first.source_text# => 'Quelltext Nummer 0'putspage.segments.first.targets.first.target_text# => 'Source text number 0'# Walk through every page of segmentswhilepage.next_page?page=DeepL.translation_memories.segments'YOUR_TM_ID',page_size: 50,page_cursor: page.next_page_cursorend# Only the segments matching a textpage=DeepL.translation_memories.segments'YOUR_TM_ID',filter_text: 'Nummer 1',filter_case_sensitive: true

Importing a translation memory

translation_memories.import_from_filepath creates a new translation memory from a TMX file. It creates the import job, uploads the file and waits for the processing to finish, and returns the finished TranslationMemoryJob. Its result carries the ID of the newly created translation memory.

job=DeepL.translation_memories.import_from_filepath'legal.tmx',display_name: 'Legal',timeout_s: 300putsjob.class# => DeepL::Resources::TranslationMemoryJobputsjob.status# => 'completed'putsjob.result.translation_memory_id# => 'a74d88fb-ed2a-4943-a664-a4512398b994'putsjob.result.skipped_segment_count# => 0

The three steps can also be performed separately, for example to upload a file that is not available on the local file system. The upload URL is a pre-signed storage URL outside of the DeepL API, so no authorization header is sent with the upload.

content=File.binread'legal.tmx'created=DeepL.translation_memories.create_import'legal.tmx',content.bytesize,content_type: 'application/xml',display_name: 'Legal'putscreated.upload_url# => 'https://...'DeepL.translation_memories.upload_filecreated,contentjob=DeepL.translation_memories.wait_until_job_donecreated.job_id

Until the file is uploaded the job stays in the awaiting_input status and result.required_action describes what is missing. The API detects the upload asynchronously, so the job keeps reporting awaiting_input for a while afterwards, typically around half a minute, before it completes. wait_until_job_done therefore polls through that status like any other non-terminal one. A job whose file is never uploaded does not finish on its own, so pass timeout_s when that is a possibility.

Exporting a translation memory

translation_memories.export_to_filepath writes a translation memory to a TMX file. It creates the export job, waits for it to finish and downloads the result, overwriting the output file if it already exists.

job=DeepL.translation_memories.export_to_filepath'YOUR_TM_ID','export.tmx'putsjob.status# => 'completed'

The steps can be performed separately as well. Repeating the export of an unchanged translation memory reuses the previously completed job instead of starting a new one, which reused_existing? reports. Just like the upload URL, the download URL is a pre-signed storage URL and is requested without an authorization header.

created=DeepL.translation_memories.create_export'YOUR_TM_ID'putscreated.reused_existing?# => falsejob=DeepL.translation_memories.wait_until_job_donecreated.job_idputsjob.result.download_url# => 'https://...'DeepL.translation_memories.download_exportjob,'export.tmx'

Tracking import and export jobs

translation_memories.find_job returns the current status of an import or export job, and translation_memories.wait_until_job_done polls it every five seconds until it finished, raising if the job failed or expired. Pass timeout_s to give up after a number of seconds instead of waiting forever.

job=DeepL.translation_memories.find_job'YOUR_JOB_ID'putsjob.operation# => 'import'putsjob.status# => 'processing'putsjob.finished?# => false

The status is one of awaiting_input, processing, completed, downloaded, failed or expired.

Deleting a translation memory

translation_memories.destroy deletes a translation memory and returns its ID.

DeepL.translation_memories.destroy'YOUR_TM_ID'# => 'YOUR_TM_ID'

Using a translation memory in translations

Pass the translation_memory parameter to translate to use a translation memory. You can pass either a string containing the translation memory ID, or a TranslationMemory object. Use translation_memory_threshold to control the minimum matching percentage for fuzzy matches (0-100, recommended minimum of 75%).

# Using a translation memory IDtranslation=DeepL.translate'Hello, world!','EN','DE',translation_memory: 'YOUR_TM_ID',translation_memory_threshold: 80# Or using a TranslationMemory objecttranslation_memories=DeepL.translation_memories.listtranslation=DeepL.translate'Hello, world!','EN','DE',translation_memory: translation_memories.first

The same translation_memory and translation_memory_threshold options can be passed to document translation via DeepL.document.upload (or DeepL.document.translate_document). The translation_memory option accepts either a translation memory ID string or a TranslationMemory object:

handle=DeepL.document.upload'my_document.docx','EN','DE','my_document.docx',translation_memory: 'YOUR_TM_ID',translation_memory_threshold: 80

Monitor usage

To check current API usage, use:

usage=DeepL.usageputsusage.character_count# => 180118putsusage.character_limit# => 1250000

Translate documents

To translate a document, use the document.translate_document method. Example:

DeepL.document.translate_document('/path/to/spanish_document.pdf','/path/to/translated_document.pdf','ES','EN')

The lower level upload, get_status and download methods are also exposed, as well as the convenience method wait_until_document_translation_finished on the DocumentHandle object, which would replace get_status:

doc_handle=DeepL.document.upload('/path/to/spanish_document.pdf','ES','EN')doc_status=doc_handle.wait_until_document_translation_finished# alternatively poll `DeepL.document.get_status`# until the `doc_status.successful?`DeepL.document.download(doc_handle,'/path/to/translated_document.pdf')unlessdoc_status.error?

You can also pass additional options to document translation methods, including extra_body_parameters:

options={formality: 'more',extra_body_parameters: {example_param: 'true'}}doc_handle=DeepL.document.upload('/path/to/spanish_document.pdf','ES','EN',nil,options)

The extra_body_parameters option allows you to pass arbitrary parameters in the request body. This can be used to access beta features by adding new parameters, or to override built-in parameters (such as target_lang, source_lang, etc.) for testing purposes.

Sending additional HTTP headers

You can pass additional HTTP headers to translate, rephrase, and the document methods. For example, to send the X-DeepL-Reporting-Tag header for usage reporting (see the cookbook entry):

additional_headers={'X-DeepL-Reporting-Tag'=>'my-tag'}translation=DeepL.translate'Hello, world!','EN','DE',{},additional_headersrephrased=DeepL.rephrase'Hello, world!','EN',nil,nil,{},additional_headers

Handle exceptions

You can capture and process exceptions that may be raised during API calls. These are all the possible exceptions:

Exception classDescription
DeepL::Exceptions::AuthorizationFailedThe authorization process has failed. Check your auth_key value.
DeepL::Exceptions::BadRequestSomething is wrong in your request. Check exception.message for more information.
DeepL::Exceptions::DocumentTranslationErrorAn error occured during document translation. Check exception.message for more information.
DeepL::Exceptions::LimitExceededYou've reached the API's call limit.
DeepL::Exceptions::QuotaExceededYou've reached the API's character limit.
DeepL::Exceptions::RequestErrorAn unkown request error. Check exception.response and exception.request for more information.
DeepL::Exceptions::NotSupportedThe requested method or API endpoint is not supported.
DeepL::Exceptions::RequestEntityTooLargeYour request is too large, reduce the amount of data you are sending. The API has a request size limit of 128 KiB.
DeepL::Exceptions::ServerErrorAn error occured in the DeepL API, wait a short amount of time and retry.

An exampling of handling a generic exception:

defmy_methoditem=DeepL.translate'This is my text',nil,'ES'rescueDeepL::Exceptions::RequestError=>eputs'Oops!'puts"Code: #{e.response.code}"puts"Response body: #{e.response.body}"puts"Request body: #{e.request.body}"end

Logging

To enable logging, pass a suitable logging object (e.g. the default Logger from the Ruby standard library) when configuring the library. The library logs HTTP requests to INFO and debug information to DEBUG. Example:

require'logger'logger=Logger.new(STDOUT)logger.level=Logger::INFOdeepl.configuredo |config|
config.auth_key=configuration.auth_keyconfig.logger=loggerend

Proxy configuration

To use HTTP proxies, a session needs to be used. The proxy can then be configured as part of the HTTP client options:

client_options=HTTPClientOptions.new({'proxy_addr'=>'http://localhost','proxy_port'=>80})deepl.with_session(client_options)do |session|
# ...end

Anonymous platform information

By default, we send some basic information about the platform the client library is running on with each request, see here for an explanation. This data is completely anonymous and only used to improve our product, not track any individual users. If you do not wish to send this data, you can opt-out by setting the send_platform_info flag in the configuration to false like so:

deepl.configure({},nil,nil,false)do |config|
# ...end

You can also complete customize the User-Agent header like so:

deepl.configuredo |config|
config.user_agent='myCustomUserAgent'end

Sending multiple requests

When writing an application that send multiple requests, using a HTTP session will give better performance through HTTP Keep-Alive. You can use it by simply wrapping your requests in a with_session block:

deepl.with_sessiondo |session|
deepl.translate(sentence1,'DE','EN-GB')deepl.translate(sentence2,'DE','EN-GB')deepl.translate(sentence3,'DE','EN-GB')end

Writing a plugin

If you use this library in an application, please identify the application by setting the name and version of the plugin:

deepl.configure({},'MyTranslationPlugin','1.0.1')do |config|
# ...end

This information is passed along when the library makes calls to the DeepL API. Both name and version are required. Please note that setting the User-Agent header via deepl.configure will override this setting, if you need to use this, please manually identify your Application in the User-Agent header.

Options Constants

The available values for various possible options are provided under the DeepL::Constants namespace. The currently available options are

TagHandlingSplitSentencesModelTypeFormalityWritingStyleTone

To view all the possible options for a given constant, call options:

all_available_tones=DeepL::Constants::Tones.options

To check if a given string is a possible option for a given constant, call valid?:

DeepL::Constants::Tones.valid?('friendly')# trueDeepL::Constants::Tones.valid?('rude')# false

Integrations

Ruby on Rails

You may use this gem as a standalone service by creating an initializer on your config/initializers folder with your DeepL configuration. For example:

# config/initializers/deepl.rbDeepL.configuredo |config|
# Your configuration goes hereend

Since the DeepL service is defined globally, you can use service anywhere in your code (controllers, models, views, jobs, plain ruby objects… you name it).

i18n-tasks

You may also take a look at i18n-tasks, which is a gem that helps you find and manage missing and unused translations. deepl-rb is used as one of the backend services to translate content.

Development

Clone the repository, and install its dependencies:

git clone https://github.com/DeepLcom/deepl-rb
cd deepl-rb
bundle install

To run tests (rspec and rubocop), use

bundle exec rake test

Acknowledgements

This library was originally developed by Daniel Herzog, we are grateful for his contributions. Beginning with v3.0.0, DeepL took over development and officially supports and maintains the library together with Daniel.

About

Official Ruby library for the DeepL language translation API.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

19 stars

Watchers

1 watching

Forks

Releases

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Gem Version

DeepL Ruby Library

The DeepL API is a language translation API that allows other computer programs to send texts and documents to DeepL's servers and receive high-quality translations. This opens a whole universe of opportunities for developers: any translation product you can imagine can now be built on top of DeepL's best-in-class translation technology.

The DeepL Ruby library offers a convenient way for applications written in Ruby to interact with the DeepL API. We intend to support all API functions with the library, though support for new features may be added to the library after they’re added to the API.

Getting an authentication key

To use the DeepL Ruby Library, you'll need an API authentication key. To get a key, please create an account here. With a DeepL API Free account you can translate up to 500,000 characters/month for free.

Installation

Install this gem with

gem install deepl-rb
# Load it in your ruby file using `require 'deepl'`

Or add it to your Gemfile:

gem'deepl-rb',require: 'deepl'

Usage

Setup an environment variable named DEEPL_AUTH_KEY with your authentication key:

export DEEPL_AUTH_KEY="your-api-token"

Alternatively, you can configure the API client within a ruby block:

DeepL.configuredo |config|
config.auth_key='your-api-token'end

You can also configure the API host and the API version:

DeepL.configuredo |config|
config.auth_key='your-api-token'config.host='https://api-free.deepl.com'# Default value is 'https://api.deepl.com'config.version='v1'# Default value is 'v2'end

Available languages

Available languages can be retrieved via API:

languages=DeepL.languagesputslanguages.class# => Arrayputslanguages.first.class# => DeepL::Resources::Languageputs"#{languages.first.code} -> #{languages.first.name}"# => "ES -> Spanish"

Note that source and target languages may be different, which can be retrieved by using the type option:

putsDeepL.languages(type: :source).count# => 24putsDeepL.languages(type: :target).count# => 26

All languages are also defined on the official API documentation.

Note that target languages may include the supports_formality flag, which may be checked using the DeepL::Resources::Language#supports_formality?.

Translate

To translate a simple text, use the translate method:

translation=DeepL.translate'This is my text','EN','ES'putstranslation.class# => DeepL::Resources::Textputstranslation.text# => 'Este es mi texto'

Enable auto-detect source language by skipping the source language with nil:

translation=DeepL.translate'This is my text',nil,'ES'putstranslation.detected_source_language# => 'EN'

Translate a list of texts by passing an array as an argument:

texts=['Sample text','Another text']translations=DeepL.translatetexts,'EN','ES'putstranslations.class# => Arrayputstranslations.first.class# => DeepL::Resources::Text

You can also use custom query parameters, like tag_handling, split_sentences, non_splitting_tags or ignore_tags:

translation=DeepL.translate'<p>A sample</p>','EN','ES',tag_handling: 'xml',split_sentences: false,non_splitting_tags: 'h1',ignore_tags: %w[codepre]putstranslation.text# => "<p>Una muestra</p>"

To specify which version of the tag handling algorithm to use, you can use the tag_handling_version parameter:

translation=DeepL.translate'<p>A sample</p>','EN','ES',tag_handling: 'xml',tag_handling_version: 'v2'putstranslation.text# => "<p>Una muestra</p>"

The available values are 'v1' and 'v2'.

To translate with context, simply supply the context parameter:

translation=DeepL.translate'That is hot!','EN','ES',context: 'He did not like the jalapenos in his meal.'putstranslation.text# => "¡Eso es picante!"

To specify a type of translation model to use, you can use the model_type option:

translation=DeepL.translate'That is hot!','EN','DE',model_type: 'quality_optimized'

This would use next-gen translation models for the translation. The available values are

  • 'quality_optimized': use a translation model that maximizes translation quality, at the cost of response time. This option may be unavailable for some language pairs.
  • 'prefer_quality_optimized': use the highest-quality translation model for the given language pair.
  • 'latency_optimized': use a translation model that minimizes response time, at the cost of translation quality.

To translate with custom instructions, supply the custom_instructions parameter:

translation=DeepL.translate'Hello, world!','EN','DE',custom_instructions: ['Use informal language','Be concise']putstranslation.text

Up to 10 custom instructions can be specified, each with a maximum of 300 characters. The target language must be de, en, es, fr, it, ja, ko, zh or any variants. Note that using custom_instructions will automatically use quality_optimized models, and cannot be combined with model_type: 'latency_optimized'.

The following parameters will be automatically converted:

ParameterConversion
preserve_formattingConverts false to '0' and true to '1'
split_sentencesConverts false to '0' and true to '1'
outline_detectionConverts false to '0' and true to '1'
splitting_tagsConverts arrays to strings joining by commas
non_splitting_tagsConverts arrays to strings joining by commas
ignore_tagsConverts arrays to strings joining by commas
formalityNo conversion applied
glossary_idNo conversion applied
style_ruleNo conversion applied (can be a string ID or a StyleRule object)
translation_memoryNo conversion applied (can be a string ID or a TranslationMemory object)
translation_memory_thresholdNo conversion applied (integer 0-100, recommended minimum 75)
contextNo conversion applied
custom_instructionsNo conversion applied
tag_handling_versionNo conversion applied
extra_body_parametersHash of extra parameters to pass in the body of the HTTP request. Can be used to access beta features, or to override built-in parameters for testing purposes. Extra parameters can override keys explicitly set by the client.

Rephrase Text

To rephrase or improve text, including changing the writing style or tone of the text, use the rephrase method:

rephrased_text=DeepL.rephrase'you will acquire new rephrased text','EN'putsrephrased_text.class# => DeepL::Resources::Textputsrephrased_text.text# => 'You get new rephrased text.'

As with translate, the text input can be a single string or an array of strings.

You can use the additional arguments to specify the writing style or tone you want for the rephrased text:

rephrased_text=DeepL.rephrase'you will acquire new rephrased text','EN','casual'putsrephrased_text.text# => 'You'll get new, rephrased text.'
rephrased_text=DeepL.rephrase'you will acquire new rephrased text','EN',nil,'friendly'putsrephrased_text.text# => 'You'll get to enjoy new, rephrased text!'

Glossaries

To create a glossary, use the glossaries.create method. The glossary entries argument should be an array of text pairs. Each pair includes the source and the target translations.

entries=[['Hello World','Hola Tierra'],['car','auto']]glossary=DeepL.glossaries.create'Mi Glosario','EN','ES',entriesputsglossary.class# => DeepL::Resources::Glossaryputsglossary.id# => 'aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e'putsglossary.entry_count# => 2

Created glossaries can be used in the translate method by specifying the glossary_id option:

translation=DeepL.translate'Hello World','EN','ES',glossary_id: 'aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e'putstranslation.class# => DeepL::Resources::Textputstranslation.text# => 'Hola Tierra'translation=DeepL.translate"I wish we had a car.",'EN','ES',glossary_id: 'aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e'putstranslation.class# => DeepL::Resources::Textputstranslation.text# => Ojalá tuviéramos un auto.

To use more than one glossary at once, specify the glossary_ids option with an array of up to 5 glossary IDs (as strings or DeepL::Resources::Glossary objects) instead of glossary_id. This works for both text and document translation. glossary_ids requires source_lang to be set, cannot be combined with glossary_id, and raises ArgumentError if these rules are violated or more than 5 IDs are provided:

# Text translation with multiple glossariestranslation=DeepL.translate'Hello World','EN','ES',glossary_ids: ['aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e','bb59d8g1-1e13-524f-9b17-e6ccg1db8b7f']# Document translation with multiple glossarieshandle=DeepL.document.upload'my_document.docx','EN','ES','my_document.docx',glossary_ids: ['aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e','bb59d8g1-1e13-524f-9b17-e6ccg1db8b7f']

To list all the glossaries available, use the glossaries.list method:

glossaries=DeepL.glossaries.listputsglossaries.class# => Arrayputsglossaries.first.class# => DeepL::Resources::Glossary

To find an existing glossary, use the glossaries.find method:

glossary=DeepL.glossaries.find'aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e'putsglossary.class# => DeepL::Resources::Glossary

The glossary resource does not include the glossary entries. To list the glossary entries, use the glossaries.entries method:

entries=DeepL.glossaries.entries'aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e'putsentries.class# => Arrayputsentries.size# => 2ppentries.first# => ["Hello World", "Hola Tierra"]

To delete an existing glossary, use the glossaries.destroy method:

glossary_id=DeepL.glossaries.destroy'aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e'putsglossary_id# => aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e

You can list all the language pairs supported by glossaries using the glossaries.language_pairs method:

language_pairs=DeepL.glossaries.language_pairsputslanguage_pairs.class# => Arrayputslanguage_pairs.first.class# => DeepL::Resources::LanguagePairputslanguage_pairs.first.source_lang# => enputslanguage_pairs.first.target_lang# => de

Style Rules

Style rules allow you to customize your translations using a managed, shared list of rules for style, formatting, and more. Multiple style rules can be stored with your account, each with a user-specified name and a uniquely-assigned ID.

Creating a style rule

Use create to create a new style rule with a name and language code. You can optionally provide configured_rules and custom_instructions.

# Simple creation with just a name and languagestyle_rule=DeepL.style_rules.create('My Style Rule','en')puts"Created: #{style_rule.name} (#{style_rule.style_id})"# Creation with configured rules and custom instructionsstyle_rule=DeepL.style_rules.create('Formal English','en',configured_rules: {style_and_tone: {formality: 'formal'}},custom_instructions: [{label: 'Tone',prompt: 'Always use formal language'}])

Retrieving and listing style rules

Use find to retrieve a single style rule by ID, or list to list all style rules.

list returns a list of StyleRule objects corresponding to all of your stored style rules. The method accepts optional parameters: page (page number for pagination, 0-indexed), page_size (number of items per page), and detailed. When true, the response includes configured_rules and custom_instructions for each style rule. When false (default), these fields are omitted for faster responses.

# Get a single style rule by IDstyle_rule=DeepL.style_rules.find('YOUR_STYLE_ID')puts"#{style_rule.name} (#{style_rule.language})"# List all style rulesstyle_rules=DeepL.style_rules.liststyle_rules.eachdo |rule|
puts"#{rule.name} (#{rule.style_id})"end# List with paginationstyle_rules=DeepL.style_rules.list(page: 0,page_size: 10)# List with detailed configurationstyle_rules=DeepL.style_rules.list(detailed: true)style_rules.eachdo |rule|
ifrule.configured_rulesputs" Number formatting: #{rule.configured_rules.numbers.keys.join(', ')}"endend

Updating a style rule

Use update_name to rename a style rule, and update_configured_rules to update its configured rules.

# Update the nameupdated=DeepL.style_rules.update_name('YOUR_STYLE_ID','New Name')# Update configured rulesupdated=DeepL.style_rules.update_configured_rules('YOUR_STYLE_ID',{style_and_tone: {formality: 'formal'}})

The configured_rules hash supports the following categories: dates_and_times, formatting, numbers, punctuation, spelling_and_grammar, style_and_tone, and vocabulary.

Managing custom instructions

Custom instructions allow you to add free-text prompts to a style rule. Each instruction has an id, label, prompt, and source_language. Use create_custom_instruction, find_custom_instruction, update_custom_instruction, and destroy_custom_instruction to manage them.

# Create a custom instructioninstruction=DeepL.style_rules.create_custom_instruction('YOUR_STYLE_ID','Formal tone','Always use formal language')puts"Created instruction: #{instruction.id}"# Create with an optional source languageinstruction=DeepL.style_rules.create_custom_instruction('YOUR_STYLE_ID','Formal tone','Always use formal language','en')# Get a custom instructioninstruction=DeepL.style_rules.find_custom_instruction('YOUR_STYLE_ID',instruction.id)# Update a custom instructionupdated=DeepL.style_rules.update_custom_instruction('YOUR_STYLE_ID',instruction.id,'Updated label','Use very formal language')# Delete a custom instructionDeepL.style_rules.destroy_custom_instruction('YOUR_STYLE_ID',instruction.id)

Deleting a style rule

Use destroy to delete a style rule by ID.

DeepL.style_rules.destroy('YOUR_STYLE_ID')

Using style rules in translations

Style rules can be used in the translate method by specifying the style_rule option with either a style rule ID string or a StyleRule object:

# Using a style rule IDtranslation=DeepL.translate'Hello World','EN','ES',style_rule: 'dca2e053-8ae5-45e6-a0d2-881156e7f4e4'# Or using a StyleRule objectstyle_rules=DeepL.style_rules.listtranslation=DeepL.translate'Hello World','EN','ES',style_rule: style_rules.first

The same style_rule option can be passed to document translation via DeepL.document.upload (or DeepL.document.translate_document), accepting either a style rule ID string or a StyleRule object:

handle=DeepL.document.upload'my_document.docx','EN','ES','my_document.docx',style_rule: 'dca2e053-8ae5-45e6-a0d2-881156e7f4e4'

Translation Memories

Translation memories allow you to store and reuse previously created translations. They can be used in text translation requests to improve consistency by matching against stored segments. Multiple translation memories can be stored with your account, each with a source language and one or more target languages.

Translation memories can also be managed in the DeepL UI via https://www.deepl.com/translation-memory.

Every method that takes a translation memory accepts either a string containing the translation memory ID or a TranslationMemory object.

Listing translation memories

translation_memories.list returns a list of TranslationMemory objects for your stored translation memories. The method accepts optional parameters: page (page number for pagination, 0-indexed) and page_size (number of items per page, max 25).

# List translation memoriestranslation_memories=DeepL.translation_memories.listtranslation_memories.eachdo |tm|
puts"#{tm.name} (#{tm.translation_memory_id})"puts" Source: #{tm.source_language}, Targets: #{tm.target_languages.join(', ')}"puts" Segments: #{tm.segment_count}"end# List with paginationtranslation_memories=DeepL.translation_memories.list(page: 0,page_size: 10)

Retrieving a single translation memory

translation_memories.find retrieves one translation memory by ID. In addition to the fields returned by list, the resource carries the creation_time and updated_time timestamps.

tm=DeepL.translation_memories.find'YOUR_TM_ID'putstm.class# => DeepL::Resources::TranslationMemoryputstm.name# => 'Legal'putstm.segment_count# => 12putstm.creation_time.class# => Time

Listing the segments of a translation memory

translation_memories.segments returns one page of the segments of a translation memory as a TranslationMemorySegments object. Each segment holds the source text and one target per target language of the translation memory.

Pagination is cursor-based: omit page_cursor on the first call, then pass the next_page_cursor of the previous response until next_page? is false. The method also accepts page_size (1-100, defaults to 50), filter_text (a substring matched against the source and target texts, at least 2 characters) and filter_case_sensitive (defaults to false).

Note that segment_count is the number of segments stored in the translation memory; a text filter does not reduce it.

page=DeepL.translation_memories.segments'YOUR_TM_ID',page_size: 50putspage.class# => DeepL::Resources::TranslationMemorySegmentsputspage.segment_count# => 12putspage.segments.first.source_text# => 'Quelltext Nummer 0'putspage.segments.first.targets.first.target_text# => 'Source text number 0'# Walk through every page of segmentswhilepage.next_page?page=DeepL.translation_memories.segments'YOUR_TM_ID',page_size: 50,page_cursor: page.next_page_cursorend# Only the segments matching a textpage=DeepL.translation_memories.segments'YOUR_TM_ID',filter_text: 'Nummer 1',filter_case_sensitive: true

Importing a translation memory

translation_memories.import_from_filepath creates a new translation memory from a TMX file. It creates the import job, uploads the file and waits for the processing to finish, and returns the finished TranslationMemoryJob. Its result carries the ID of the newly created translation memory.

job=DeepL.translation_memories.import_from_filepath'legal.tmx',display_name: 'Legal',timeout_s: 300putsjob.class# => DeepL::Resources::TranslationMemoryJobputsjob.status# => 'completed'putsjob.result.translation_memory_id# => 'a74d88fb-ed2a-4943-a664-a4512398b994'putsjob.result.skipped_segment_count# => 0

The three steps can also be performed separately, for example to upload a file that is not available on the local file system. The upload URL is a pre-signed storage URL outside of the DeepL API, so no authorization header is sent with the upload.

content=File.binread'legal.tmx'created=DeepL.translation_memories.create_import'legal.tmx',content.bytesize,content_type: 'application/xml',display_name: 'Legal'putscreated.upload_url# => 'https://...'DeepL.translation_memories.upload_filecreated,contentjob=DeepL.translation_memories.wait_until_job_donecreated.job_id

Until the file is uploaded the job stays in the awaiting_input status and result.required_action describes what is missing. The API detects the upload asynchronously, so the job keeps reporting awaiting_input for a while afterwards, typically around half a minute, before it completes. wait_until_job_done therefore polls through that status like any other non-terminal one. A job whose file is never uploaded does not finish on its own, so pass timeout_s when that is a possibility.

Exporting a translation memory

translation_memories.export_to_filepath writes a translation memory to a TMX file. It creates the export job, waits for it to finish and downloads the result, overwriting the output file if it already exists.

job=DeepL.translation_memories.export_to_filepath'YOUR_TM_ID','export.tmx'putsjob.status# => 'completed'

The steps can be performed separately as well. Repeating the export of an unchanged translation memory reuses the previously completed job instead of starting a new one, which reused_existing? reports. Just like the upload URL, the download URL is a pre-signed storage URL and is requested without an authorization header.

created=DeepL.translation_memories.create_export'YOUR_TM_ID'putscreated.reused_existing?# => falsejob=DeepL.translation_memories.wait_until_job_donecreated.job_idputsjob.result.download_url# => 'https://...'DeepL.translation_memories.download_exportjob,'export.tmx'

Tracking import and export jobs

translation_memories.find_job returns the current status of an import or export job, and translation_memories.wait_until_job_done polls it every five seconds until it finished, raising if the job failed or expired. Pass timeout_s to give up after a number of seconds instead of waiting forever.

job=DeepL.translation_memories.find_job'YOUR_JOB_ID'putsjob.operation# => 'import'putsjob.status# => 'processing'putsjob.finished?# => false

The status is one of awaiting_input, processing, completed, downloaded, failed or expired.

Deleting a translation memory

translation_memories.destroy deletes a translation memory and returns its ID.

DeepL.translation_memories.destroy'YOUR_TM_ID'# => 'YOUR_TM_ID'

Using a translation memory in translations

Pass the translation_memory parameter to translate to use a translation memory. You can pass either a string containing the translation memory ID, or a TranslationMemory object. Use translation_memory_threshold to control the minimum matching percentage for fuzzy matches (0-100, recommended minimum of 75%).

# Using a translation memory IDtranslation=DeepL.translate'Hello, world!','EN','DE',translation_memory: 'YOUR_TM_ID',translation_memory_threshold: 80# Or using a TranslationMemory objecttranslation_memories=DeepL.translation_memories.listtranslation=DeepL.translate'Hello, world!','EN','DE',translation_memory: translation_memories.first

The same translation_memory and translation_memory_threshold options can be passed to document translation via DeepL.document.upload (or DeepL.document.translate_document). The translation_memory option accepts either a translation memory ID string or a TranslationMemory object:

handle=DeepL.document.upload'my_document.docx','EN','DE','my_document.docx',translation_memory: 'YOUR_TM_ID',translation_memory_threshold: 80

Monitor usage

To check current API usage, use:

usage=DeepL.usageputsusage.character_count# => 180118putsusage.character_limit# => 1250000

Translate documents

To translate a document, use the document.translate_document method. Example:

DeepL.document.translate_document('/path/to/spanish_document.pdf','/path/to/translated_document.pdf','ES','EN')

The lower level upload, get_status and download methods are also exposed, as well as the convenience method wait_until_document_translation_finished on the DocumentHandle object, which would replace get_status:

doc_handle=DeepL.document.upload('/path/to/spanish_document.pdf','ES','EN')doc_status=doc_handle.wait_until_document_translation_finished# alternatively poll `DeepL.document.get_status`# until the `doc_status.successful?`DeepL.document.download(doc_handle,'/path/to/translated_document.pdf')unlessdoc_status.error?

You can also pass additional options to document translation methods, including extra_body_parameters:

options={formality: 'more',extra_body_parameters: {example_param: 'true'}}doc_handle=DeepL.document.upload('/path/to/spanish_document.pdf','ES','EN',nil,options)

The extra_body_parameters option allows you to pass arbitrary parameters in the request body. This can be used to access beta features by adding new parameters, or to override built-in parameters (such as target_lang, source_lang, etc.) for testing purposes.

Sending additional HTTP headers

You can pass additional HTTP headers to translate, rephrase, and the document methods. For example, to send the X-DeepL-Reporting-Tag header for usage reporting (see the cookbook entry):

additional_headers={'X-DeepL-Reporting-Tag'=>'my-tag'}translation=DeepL.translate'Hello, world!','EN','DE',{},additional_headersrephrased=DeepL.rephrase'Hello, world!','EN',nil,nil,{},additional_headers

Handle exceptions

You can capture and process exceptions that may be raised during API calls. These are all the possible exceptions:

Exception classDescription
DeepL::Exceptions::AuthorizationFailedThe authorization process has failed. Check your auth_key value.
DeepL::Exceptions::BadRequestSomething is wrong in your request. Check exception.message for more information.
DeepL::Exceptions::DocumentTranslationErrorAn error occured during document translation. Check exception.message for more information.
DeepL::Exceptions::LimitExceededYou've reached the API's call limit.
DeepL::Exceptions::QuotaExceededYou've reached the API's character limit.
DeepL::Exceptions::RequestErrorAn unkown request error. Check exception.response and exception.request for more information.
DeepL::Exceptions::NotSupportedThe requested method or API endpoint is not supported.
DeepL::Exceptions::RequestEntityTooLargeYour request is too large, reduce the amount of data you are sending. The API has a request size limit of 128 KiB.
DeepL::Exceptions::ServerErrorAn error occured in the DeepL API, wait a short amount of time and retry.

An exampling of handling a generic exception:

defmy_methoditem=DeepL.translate'This is my text',nil,'ES'rescueDeepL::Exceptions::RequestError=>eputs'Oops!'puts"Code: #{e.response.code}"puts"Response body: #{e.response.body}"puts"Request body: #{e.request.body}"end

Logging

To enable logging, pass a suitable logging object (e.g. the default Logger from the Ruby standard library) when configuring the library. The library logs HTTP requests to INFO and debug information to DEBUG. Example:

require'logger'logger=Logger.new(STDOUT)logger.level=Logger::INFOdeepl.configuredo |config|
config.auth_key=configuration.auth_keyconfig.logger=loggerend

Proxy configuration

To use HTTP proxies, a session needs to be used. The proxy can then be configured as part of the HTTP client options:

client_options=HTTPClientOptions.new({'proxy_addr'=>'http://localhost','proxy_port'=>80})deepl.with_session(client_options)do |session|
# ...end

Anonymous platform information

By default, we send some basic information about the platform the client library is running on with each request, see here for an explanation. This data is completely anonymous and only used to improve our product, not track any individual users. If you do not wish to send this data, you can opt-out by setting the send_platform_info flag in the configuration to false like so:

deepl.configure({},nil,nil,false)do |config|
# ...end

You can also complete customize the User-Agent header like so:

deepl.configuredo |config|
config.user_agent='myCustomUserAgent'end

Sending multiple requests

When writing an application that send multiple requests, using a HTTP session will give better performance through HTTP Keep-Alive. You can use it by simply wrapping your requests in a with_session block:

deepl.with_sessiondo |session|
deepl.translate(sentence1,'DE','EN-GB')deepl.translate(sentence2,'DE','EN-GB')deepl.translate(sentence3,'DE','EN-GB')end

Writing a plugin

If you use this library in an application, please identify the application by setting the name and version of the plugin:

deepl.configure({},'MyTranslationPlugin','1.0.1')do |config|
# ...end

This information is passed along when the library makes calls to the DeepL API. Both name and version are required. Please note that setting the User-Agent header via deepl.configure will override this setting, if you need to use this, please manually identify your Application in the User-Agent header.

Options Constants

The available values for various possible options are provided under the DeepL::Constants namespace. The currently available options are

TagHandlingSplitSentencesModelTypeFormalityWritingStyleTone

To view all the possible options for a given constant, call options:

all_available_tones=DeepL::Constants::Tones.options

To check if a given string is a possible option for a given constant, call valid?:

DeepL::Constants::Tones.valid?('friendly')# trueDeepL::Constants::Tones.valid?('rude')# false

Integrations

Ruby on Rails

You may use this gem as a standalone service by creating an initializer on your config/initializers folder with your DeepL configuration. For example:

# config/initializers/deepl.rbDeepL.configuredo |config|
# Your configuration goes hereend

Since the DeepL service is defined globally, you can use service anywhere in your code (controllers, models, views, jobs, plain ruby objects… you name it).

i18n-tasks

You may also take a look at i18n-tasks, which is a gem that helps you find and manage missing and unused translations. deepl-rb is used as one of the backend services to translate content.

Development

Clone the repository, and install its dependencies:

git clone https://github.com/DeepLcom/deepl-rb
cd deepl-rb
bundle install

To run tests (rspec and rubocop), use

bundle exec rake test

Acknowledgements

This library was originally developed by Daniel Herzog, we are grateful for his contributions. Beginning with v3.0.0, DeepL took over development and officially supports and maintains the library together with Daniel.

About

Official Ruby library for the DeepL language translation API.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

19 stars

Watchers

1 watching

Forks

Releases

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Gem Version

DeepL Ruby Library

The DeepL API is a language translation API that allows other computer programs to send texts and documents to DeepL's servers and receive high-quality translations. This opens a whole universe of opportunities for developers: any translation product you can imagine can now be built on top of DeepL's best-in-class translation technology.

The DeepL Ruby library offers a convenient way for applications written in Ruby to interact with the DeepL API. We intend to support all API functions with the library, though support for new features may be added to the library after they’re added to the API.

Getting an authentication key

To use the DeepL Ruby Library, you'll need an API authentication key. To get a key, please create an account here. With a DeepL API Free account you can translate up to 500,000 characters/month for free.

Installation

Install this gem with

gem install deepl-rb
# Load it in your ruby file using `require 'deepl'`

Or add it to your Gemfile:

gem'deepl-rb',require: 'deepl'

Usage

Setup an environment variable named DEEPL_AUTH_KEY with your authentication key:

export DEEPL_AUTH_KEY="your-api-token"

Alternatively, you can configure the API client within a ruby block:

DeepL.configuredo |config|
config.auth_key='your-api-token'end

You can also configure the API host and the API version:

DeepL.configuredo |config|
config.auth_key='your-api-token'config.host='https://api-free.deepl.com'# Default value is 'https://api.deepl.com'config.version='v1'# Default value is 'v2'end

Available languages

Available languages can be retrieved via API:

languages=DeepL.languagesputslanguages.class# => Arrayputslanguages.first.class# => DeepL::Resources::Languageputs"#{languages.first.code} -> #{languages.first.name}"# => "ES -> Spanish"

Note that source and target languages may be different, which can be retrieved by using the type option:

putsDeepL.languages(type: :source).count# => 24putsDeepL.languages(type: :target).count# => 26

All languages are also defined on the official API documentation.

Note that target languages may include the supports_formality flag, which may be checked using the DeepL::Resources::Language#supports_formality?.

Translate

To translate a simple text, use the translate method:

translation=DeepL.translate'This is my text','EN','ES'putstranslation.class# => DeepL::Resources::Textputstranslation.text# => 'Este es mi texto'

Enable auto-detect source language by skipping the source language with nil:

translation=DeepL.translate'This is my text',nil,'ES'putstranslation.detected_source_language# => 'EN'

Translate a list of texts by passing an array as an argument:

texts=['Sample text','Another text']translations=DeepL.translatetexts,'EN','ES'putstranslations.class# => Arrayputstranslations.first.class# => DeepL::Resources::Text

You can also use custom query parameters, like tag_handling, split_sentences, non_splitting_tags or ignore_tags:

translation=DeepL.translate'<p>A sample</p>','EN','ES',tag_handling: 'xml',split_sentences: false,non_splitting_tags: 'h1',ignore_tags: %w[codepre]putstranslation.text# => "<p>Una muestra</p>"

To specify which version of the tag handling algorithm to use, you can use the tag_handling_version parameter:

translation=DeepL.translate'<p>A sample</p>','EN','ES',tag_handling: 'xml',tag_handling_version: 'v2'putstranslation.text# => "<p>Una muestra</p>"

The available values are 'v1' and 'v2'.

To translate with context, simply supply the context parameter:

translation=DeepL.translate'That is hot!','EN','ES',context: 'He did not like the jalapenos in his meal.'putstranslation.text# => "¡Eso es picante!"

To specify a type of translation model to use, you can use the model_type option:

translation=DeepL.translate'That is hot!','EN','DE',model_type: 'quality_optimized'

This would use next-gen translation models for the translation. The available values are

  • 'quality_optimized': use a translation model that maximizes translation quality, at the cost of response time. This option may be unavailable for some language pairs.
  • 'prefer_quality_optimized': use the highest-quality translation model for the given language pair.
  • 'latency_optimized': use a translation model that minimizes response time, at the cost of translation quality.

To translate with custom instructions, supply the custom_instructions parameter:

translation=DeepL.translate'Hello, world!','EN','DE',custom_instructions: ['Use informal language','Be concise']putstranslation.text

Up to 10 custom instructions can be specified, each with a maximum of 300 characters. The target language must be de, en, es, fr, it, ja, ko, zh or any variants. Note that using custom_instructions will automatically use quality_optimized models, and cannot be combined with model_type: 'latency_optimized'.

The following parameters will be automatically converted:

ParameterConversion
preserve_formattingConverts false to '0' and true to '1'
split_sentencesConverts false to '0' and true to '1'
outline_detectionConverts false to '0' and true to '1'
splitting_tagsConverts arrays to strings joining by commas
non_splitting_tagsConverts arrays to strings joining by commas
ignore_tagsConverts arrays to strings joining by commas
formalityNo conversion applied
glossary_idNo conversion applied
style_ruleNo conversion applied (can be a string ID or a StyleRule object)
translation_memoryNo conversion applied (can be a string ID or a TranslationMemory object)
translation_memory_thresholdNo conversion applied (integer 0-100, recommended minimum 75)
contextNo conversion applied
custom_instructionsNo conversion applied
tag_handling_versionNo conversion applied
extra_body_parametersHash of extra parameters to pass in the body of the HTTP request. Can be used to access beta features, or to override built-in parameters for testing purposes. Extra parameters can override keys explicitly set by the client.

Rephrase Text

To rephrase or improve text, including changing the writing style or tone of the text, use the rephrase method:

rephrased_text=DeepL.rephrase'you will acquire new rephrased text','EN'putsrephrased_text.class# => DeepL::Resources::Textputsrephrased_text.text# => 'You get new rephrased text.'

As with translate, the text input can be a single string or an array of strings.

You can use the additional arguments to specify the writing style or tone you want for the rephrased text:

rephrased_text=DeepL.rephrase'you will acquire new rephrased text','EN','casual'putsrephrased_text.text# => 'You'll get new, rephrased text.'
rephrased_text=DeepL.rephrase'you will acquire new rephrased text','EN',nil,'friendly'putsrephrased_text.text# => 'You'll get to enjoy new, rephrased text!'

Glossaries

To create a glossary, use the glossaries.create method. The glossary entries argument should be an array of text pairs. Each pair includes the source and the target translations.

entries=[['Hello World','Hola Tierra'],['car','auto']]glossary=DeepL.glossaries.create'Mi Glosario','EN','ES',entriesputsglossary.class# => DeepL::Resources::Glossaryputsglossary.id# => 'aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e'putsglossary.entry_count# => 2

Created glossaries can be used in the translate method by specifying the glossary_id option:

translation=DeepL.translate'Hello World','EN','ES',glossary_id: 'aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e'putstranslation.class# => DeepL::Resources::Textputstranslation.text# => 'Hola Tierra'translation=DeepL.translate"I wish we had a car.",'EN','ES',glossary_id: 'aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e'putstranslation.class# => DeepL::Resources::Textputstranslation.text# => Ojalá tuviéramos un auto.

To use more than one glossary at once, specify the glossary_ids option with an array of up to 5 glossary IDs (as strings or DeepL::Resources::Glossary objects) instead of glossary_id. This works for both text and document translation. glossary_ids requires source_lang to be set, cannot be combined with glossary_id, and raises ArgumentError if these rules are violated or more than 5 IDs are provided:

# Text translation with multiple glossariestranslation=DeepL.translate'Hello World','EN','ES',glossary_ids: ['aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e','bb59d8g1-1e13-524f-9b17-e6ccg1db8b7f']# Document translation with multiple glossarieshandle=DeepL.document.upload'my_document.docx','EN','ES','my_document.docx',glossary_ids: ['aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e','bb59d8g1-1e13-524f-9b17-e6ccg1db8b7f']

To list all the glossaries available, use the glossaries.list method:

glossaries=DeepL.glossaries.listputsglossaries.class# => Arrayputsglossaries.first.class# => DeepL::Resources::Glossary

To find an existing glossary, use the glossaries.find method:

glossary=DeepL.glossaries.find'aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e'putsglossary.class# => DeepL::Resources::Glossary

The glossary resource does not include the glossary entries. To list the glossary entries, use the glossaries.entries method:

entries=DeepL.glossaries.entries'aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e'putsentries.class# => Arrayputsentries.size# => 2ppentries.first# => ["Hello World", "Hola Tierra"]

To delete an existing glossary, use the glossaries.destroy method:

glossary_id=DeepL.glossaries.destroy'aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e'putsglossary_id# => aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e

You can list all the language pairs supported by glossaries using the glossaries.language_pairs method:

language_pairs=DeepL.glossaries.language_pairsputslanguage_pairs.class# => Arrayputslanguage_pairs.first.class# => DeepL::Resources::LanguagePairputslanguage_pairs.first.source_lang# => enputslanguage_pairs.first.target_lang# => de

Style Rules

Style rules allow you to customize your translations using a managed, shared list of rules for style, formatting, and more. Multiple style rules can be stored with your account, each with a user-specified name and a uniquely-assigned ID.

Creating a style rule

Use create to create a new style rule with a name and language code. You can optionally provide configured_rules and custom_instructions.

# Simple creation with just a name and languagestyle_rule=DeepL.style_rules.create('My Style Rule','en')puts"Created: #{style_rule.name} (#{style_rule.style_id})"# Creation with configured rules and custom instructionsstyle_rule=DeepL.style_rules.create('Formal English','en',configured_rules: {style_and_tone: {formality: 'formal'}},custom_instructions: [{label: 'Tone',prompt: 'Always use formal language'}])

Retrieving and listing style rules

Use find to retrieve a single style rule by ID, or list to list all style rules.

list returns a list of StyleRule objects corresponding to all of your stored style rules. The method accepts optional parameters: page (page number for pagination, 0-indexed), page_size (number of items per page), and detailed. When true, the response includes configured_rules and custom_instructions for each style rule. When false (default), these fields are omitted for faster responses.

# Get a single style rule by IDstyle_rule=DeepL.style_rules.find('YOUR_STYLE_ID')puts"#{style_rule.name} (#{style_rule.language})"# List all style rulesstyle_rules=DeepL.style_rules.liststyle_rules.eachdo |rule|
puts"#{rule.name} (#{rule.style_id})"end# List with paginationstyle_rules=DeepL.style_rules.list(page: 0,page_size: 10)# List with detailed configurationstyle_rules=DeepL.style_rules.list(detailed: true)style_rules.eachdo |rule|
ifrule.configured_rulesputs" Number formatting: #{rule.configured_rules.numbers.keys.join(', ')}"endend

Updating a style rule

Use update_name to rename a style rule, and update_configured_rules to update its configured rules.

# Update the nameupdated=DeepL.style_rules.update_name('YOUR_STYLE_ID','New Name')# Update configured rulesupdated=DeepL.style_rules.update_configured_rules('YOUR_STYLE_ID',{style_and_tone: {formality: 'formal'}})

The configured_rules hash supports the following categories: dates_and_times, formatting, numbers, punctuation, spelling_and_grammar, style_and_tone, and vocabulary.

Managing custom instructions

Custom instructions allow you to add free-text prompts to a style rule. Each instruction has an id, label, prompt, and source_language. Use create_custom_instruction, find_custom_instruction, update_custom_instruction, and destroy_custom_instruction to manage them.

# Create a custom instructioninstruction=DeepL.style_rules.create_custom_instruction('YOUR_STYLE_ID','Formal tone','Always use formal language')puts"Created instruction: #{instruction.id}"# Create with an optional source languageinstruction=DeepL.style_rules.create_custom_instruction('YOUR_STYLE_ID','Formal tone','Always use formal language','en')# Get a custom instructioninstruction=DeepL.style_rules.find_custom_instruction('YOUR_STYLE_ID',instruction.id)# Update a custom instructionupdated=DeepL.style_rules.update_custom_instruction('YOUR_STYLE_ID',instruction.id,'Updated label','Use very formal language')# Delete a custom instructionDeepL.style_rules.destroy_custom_instruction('YOUR_STYLE_ID',instruction.id)

Deleting a style rule

Use destroy to delete a style rule by ID.

DeepL.style_rules.destroy('YOUR_STYLE_ID')

Using style rules in translations

Style rules can be used in the translate method by specifying the style_rule option with either a style rule ID string or a StyleRule object:

# Using a style rule IDtranslation=DeepL.translate'Hello World','EN','ES',style_rule: 'dca2e053-8ae5-45e6-a0d2-881156e7f4e4'# Or using a StyleRule objectstyle_rules=DeepL.style_rules.listtranslation=DeepL.translate'Hello World','EN','ES',style_rule: style_rules.first

The same style_rule option can be passed to document translation via DeepL.document.upload (or DeepL.document.translate_document), accepting either a style rule ID string or a StyleRule object:

handle=DeepL.document.upload'my_document.docx','EN','ES','my_document.docx',style_rule: 'dca2e053-8ae5-45e6-a0d2-881156e7f4e4'

Translation Memories

Translation memories allow you to store and reuse previously created translations. They can be used in text translation requests to improve consistency by matching against stored segments. Multiple translation memories can be stored with your account, each with a source language and one or more target languages.

Translation memories can also be managed in the DeepL UI via https://www.deepl.com/translation-memory.

Every method that takes a translation memory accepts either a string containing the translation memory ID or a TranslationMemory object.

Listing translation memories

translation_memories.list returns a list of TranslationMemory objects for your stored translation memories. The method accepts optional parameters: page (page number for pagination, 0-indexed) and page_size (number of items per page, max 25).

# List translation memoriestranslation_memories=DeepL.translation_memories.listtranslation_memories.eachdo |tm|
puts"#{tm.name} (#{tm.translation_memory_id})"puts" Source: #{tm.source_language}, Targets: #{tm.target_languages.join(', ')}"puts" Segments: #{tm.segment_count}"end# List with paginationtranslation_memories=DeepL.translation_memories.list(page: 0,page_size: 10)

Retrieving a single translation memory

translation_memories.find retrieves one translation memory by ID. In addition to the fields returned by list, the resource carries the creation_time and updated_time timestamps.

tm=DeepL.translation_memories.find'YOUR_TM_ID'putstm.class# => DeepL::Resources::TranslationMemoryputstm.name# => 'Legal'putstm.segment_count# => 12putstm.creation_time.class# => Time

Listing the segments of a translation memory

translation_memories.segments returns one page of the segments of a translation memory as a TranslationMemorySegments object. Each segment holds the source text and one target per target language of the translation memory.

Pagination is cursor-based: omit page_cursor on the first call, then pass the next_page_cursor of the previous response until next_page? is false. The method also accepts page_size (1-100, defaults to 50), filter_text (a substring matched against the source and target texts, at least 2 characters) and filter_case_sensitive (defaults to false).

Note that segment_count is the number of segments stored in the translation memory; a text filter does not reduce it.

page=DeepL.translation_memories.segments'YOUR_TM_ID',page_size: 50putspage.class# => DeepL::Resources::TranslationMemorySegmentsputspage.segment_count# => 12putspage.segments.first.source_text# => 'Quelltext Nummer 0'putspage.segments.first.targets.first.target_text# => 'Source text number 0'# Walk through every page of segmentswhilepage.next_page?page=DeepL.translation_memories.segments'YOUR_TM_ID',page_size: 50,page_cursor: page.next_page_cursorend# Only the segments matching a textpage=DeepL.translation_memories.segments'YOUR_TM_ID',filter_text: 'Nummer 1',filter_case_sensitive: true

Importing a translation memory

translation_memories.import_from_filepath creates a new translation memory from a TMX file. It creates the import job, uploads the file and waits for the processing to finish, and returns the finished TranslationMemoryJob. Its result carries the ID of the newly created translation memory.

job=DeepL.translation_memories.import_from_filepath'legal.tmx',display_name: 'Legal',timeout_s: 300putsjob.class# => DeepL::Resources::TranslationMemoryJobputsjob.status# => 'completed'putsjob.result.translation_memory_id# => 'a74d88fb-ed2a-4943-a664-a4512398b994'putsjob.result.skipped_segment_count# => 0

The three steps can also be performed separately, for example to upload a file that is not available on the local file system. The upload URL is a pre-signed storage URL outside of the DeepL API, so no authorization header is sent with the upload.

content=File.binread'legal.tmx'created=DeepL.translation_memories.create_import'legal.tmx',content.bytesize,content_type: 'application/xml',display_name: 'Legal'putscreated.upload_url# => 'https://...'DeepL.translation_memories.upload_filecreated,contentjob=DeepL.translation_memories.wait_until_job_donecreated.job_id

Until the file is uploaded the job stays in the awaiting_input status and result.required_action describes what is missing. The API detects the upload asynchronously, so the job keeps reporting awaiting_input for a while afterwards, typically around half a minute, before it completes. wait_until_job_done therefore polls through that status like any other non-terminal one. A job whose file is never uploaded does not finish on its own, so pass timeout_s when that is a possibility.

Exporting a translation memory

translation_memories.export_to_filepath writes a translation memory to a TMX file. It creates the export job, waits for it to finish and downloads the result, overwriting the output file if it already exists.

job=DeepL.translation_memories.export_to_filepath'YOUR_TM_ID','export.tmx'putsjob.status# => 'completed'

The steps can be performed separately as well. Repeating the export of an unchanged translation memory reuses the previously completed job instead of starting a new one, which reused_existing? reports. Just like the upload URL, the download URL is a pre-signed storage URL and is requested without an authorization header.

created=DeepL.translation_memories.create_export'YOUR_TM_ID'putscreated.reused_existing?# => falsejob=DeepL.translation_memories.wait_until_job_donecreated.job_idputsjob.result.download_url# => 'https://...'DeepL.translation_memories.download_exportjob,'export.tmx'

Tracking import and export jobs

translation_memories.find_job returns the current status of an import or export job, and translation_memories.wait_until_job_done polls it every five seconds until it finished, raising if the job failed or expired. Pass timeout_s to give up after a number of seconds instead of waiting forever.

job=DeepL.translation_memories.find_job'YOUR_JOB_ID'putsjob.operation# => 'import'putsjob.status# => 'processing'putsjob.finished?# => false

The status is one of awaiting_input, processing, completed, downloaded, failed or expired.

Deleting a translation memory

translation_memories.destroy deletes a translation memory and returns its ID.

DeepL.translation_memories.destroy'YOUR_TM_ID'# => 'YOUR_TM_ID'

Using a translation memory in translations

Pass the translation_memory parameter to translate to use a translation memory. You can pass either a string containing the translation memory ID, or a TranslationMemory object. Use translation_memory_threshold to control the minimum matching percentage for fuzzy matches (0-100, recommended minimum of 75%).

# Using a translation memory IDtranslation=DeepL.translate'Hello, world!','EN','DE',translation_memory: 'YOUR_TM_ID',translation_memory_threshold: 80# Or using a TranslationMemory objecttranslation_memories=DeepL.translation_memories.listtranslation=DeepL.translate'Hello, world!','EN','DE',translation_memory: translation_memories.first

The same translation_memory and translation_memory_threshold options can be passed to document translation via DeepL.document.upload (or DeepL.document.translate_document). The translation_memory option accepts either a translation memory ID string or a TranslationMemory object:

handle=DeepL.document.upload'my_document.docx','EN','DE','my_document.docx',translation_memory: 'YOUR_TM_ID',translation_memory_threshold: 80

Monitor usage

To check current API usage, use:

usage=DeepL.usageputsusage.character_count# => 180118putsusage.character_limit# => 1250000

Translate documents

To translate a document, use the document.translate_document method. Example:

DeepL.document.translate_document('/path/to/spanish_document.pdf','/path/to/translated_document.pdf','ES','EN')

The lower level upload, get_status and download methods are also exposed, as well as the convenience method wait_until_document_translation_finished on the DocumentHandle object, which would replace get_status:

doc_handle=DeepL.document.upload('/path/to/spanish_document.pdf','ES','EN')doc_status=doc_handle.wait_until_document_translation_finished# alternatively poll `DeepL.document.get_status`# until the `doc_status.successful?`DeepL.document.download(doc_handle,'/path/to/translated_document.pdf')unlessdoc_status.error?

You can also pass additional options to document translation methods, including extra_body_parameters:

options={formality: 'more',extra_body_parameters: {example_param: 'true'}}doc_handle=DeepL.document.upload('/path/to/spanish_document.pdf','ES','EN',nil,options)

The extra_body_parameters option allows you to pass arbitrary parameters in the request body. This can be used to access beta features by adding new parameters, or to override built-in parameters (such as target_lang, source_lang, etc.) for testing purposes.

Sending additional HTTP headers

You can pass additional HTTP headers to translate, rephrase, and the document methods. For example, to send the X-DeepL-Reporting-Tag header for usage reporting (see the cookbook entry):

additional_headers={'X-DeepL-Reporting-Tag'=>'my-tag'}translation=DeepL.translate'Hello, world!','EN','DE',{},additional_headersrephrased=DeepL.rephrase'Hello, world!','EN',nil,nil,{},additional_headers

Handle exceptions

You can capture and process exceptions that may be raised during API calls. These are all the possible exceptions:

Exception classDescription
DeepL::Exceptions::AuthorizationFailedThe authorization process has failed. Check your auth_key value.
DeepL::Exceptions::BadRequestSomething is wrong in your request. Check exception.message for more information.
DeepL::Exceptions::DocumentTranslationErrorAn error occured during document translation. Check exception.message for more information.
DeepL::Exceptions::LimitExceededYou've reached the API's call limit.
DeepL::Exceptions::QuotaExceededYou've reached the API's character limit.
DeepL::Exceptions::RequestErrorAn unkown request error. Check exception.response and exception.request for more information.
DeepL::Exceptions::NotSupportedThe requested method or API endpoint is not supported.
DeepL::Exceptions::RequestEntityTooLargeYour request is too large, reduce the amount of data you are sending. The API has a request size limit of 128 KiB.
DeepL::Exceptions::ServerErrorAn error occured in the DeepL API, wait a short amount of time and retry.

An exampling of handling a generic exception:

defmy_methoditem=DeepL.translate'This is my text',nil,'ES'rescueDeepL::Exceptions::RequestError=>eputs'Oops!'puts"Code: #{e.response.code}"puts"Response body: #{e.response.body}"puts"Request body: #{e.request.body}"end

Logging

To enable logging, pass a suitable logging object (e.g. the default Logger from the Ruby standard library) when configuring the library. The library logs HTTP requests to INFO and debug information to DEBUG. Example:

require'logger'logger=Logger.new(STDOUT)logger.level=Logger::INFOdeepl.configuredo |config|
config.auth_key=configuration.auth_keyconfig.logger=loggerend

Proxy configuration

To use HTTP proxies, a session needs to be used. The proxy can then be configured as part of the HTTP client options:

client_options=HTTPClientOptions.new({'proxy_addr'=>'http://localhost','proxy_port'=>80})deepl.with_session(client_options)do |session|
# ...end

Anonymous platform information

By default, we send some basic information about the platform the client library is running on with each request, see here for an explanation. This data is completely anonymous and only used to improve our product, not track any individual users. If you do not wish to send this data, you can opt-out by setting the send_platform_info flag in the configuration to false like so:

deepl.configure({},nil,nil,false)do |config|
# ...end

You can also complete customize the User-Agent header like so:

deepl.configuredo |config|
config.user_agent='myCustomUserAgent'end

Sending multiple requests

When writing an application that send multiple requests, using a HTTP session will give better performance through HTTP Keep-Alive. You can use it by simply wrapping your requests in a with_session block:

deepl.with_sessiondo |session|
deepl.translate(sentence1,'DE','EN-GB')deepl.translate(sentence2,'DE','EN-GB')deepl.translate(sentence3,'DE','EN-GB')end

Writing a plugin

If you use this library in an application, please identify the application by setting the name and version of the plugin:

deepl.configure({},'MyTranslationPlugin','1.0.1')do |config|
# ...end

This information is passed along when the library makes calls to the DeepL API. Both name and version are required. Please note that setting the User-Agent header via deepl.configure will override this setting, if you need to use this, please manually identify your Application in the User-Agent header.

Options Constants

The available values for various possible options are provided under the DeepL::Constants namespace. The currently available options are

TagHandlingSplitSentencesModelTypeFormalityWritingStyleTone

To view all the possible options for a given constant, call options:

all_available_tones=DeepL::Constants::Tones.options

To check if a given string is a possible option for a given constant, call valid?:

DeepL::Constants::Tones.valid?('friendly')# trueDeepL::Constants::Tones.valid?('rude')# false

Integrations

Ruby on Rails

You may use this gem as a standalone service by creating an initializer on your config/initializers folder with your DeepL configuration. For example:

# config/initializers/deepl.rbDeepL.configuredo |config|
# Your configuration goes hereend

Since the DeepL service is defined globally, you can use service anywhere in your code (controllers, models, views, jobs, plain ruby objects… you name it).

i18n-tasks

You may also take a look at i18n-tasks, which is a gem that helps you find and manage missing and unused translations. deepl-rb is used as one of the backend services to translate content.

Development

Clone the repository, and install its dependencies:

git clone https://github.com/DeepLcom/deepl-rb
cd deepl-rb
bundle install

To run tests (rspec and rubocop), use

bundle exec rake test

Acknowledgements

This library was originally developed by Daniel Herzog, we are grateful for his contributions. Beginning with v3.0.0, DeepL took over development and officially supports and maintains the library together with Daniel.

About

Official Ruby library for the DeepL language translation API.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

19 stars

Watchers

1 watching

Forks

Releases

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

Gem Version

DeepL Ruby Library

The DeepL API is a language translation API that allows other computer programs to send texts and documents to DeepL's servers and receive high-quality translations. This opens a whole universe of opportunities for developers: any translation product you can imagine can now be built on top of DeepL's best-in-class translation technology.

The DeepL Ruby library offers a convenient way for applications written in Ruby to interact with the DeepL API. We intend to support all API functions with the library, though support for new features may be added to the library after they’re added to the API.

Getting an authentication key

To use the DeepL Ruby Library, you'll need an API authentication key. To get a key, please create an account here. With a DeepL API Free account you can translate up to 500,000 characters/month for free.

Installation

Install this gem with

gem install deepl-rb
# Load it in your ruby file using `require 'deepl'`

Or add it to your Gemfile:

gem'deepl-rb',require: 'deepl'

Usage

Setup an environment variable named DEEPL_AUTH_KEY with your authentication key:

export DEEPL_AUTH_KEY="your-api-token"

Alternatively, you can configure the API client within a ruby block:

DeepL.configuredo |config|
config.auth_key='your-api-token'end

You can also configure the API host and the API version:

DeepL.configuredo |config|
config.auth_key='your-api-token'config.host='https://api-free.deepl.com'# Default value is 'https://api.deepl.com'config.version='v1'# Default value is 'v2'end

Available languages

Available languages can be retrieved via API:

languages=DeepL.languagesputslanguages.class# => Arrayputslanguages.first.class# => DeepL::Resources::Languageputs"#{languages.first.code} -> #{languages.first.name}"# => "ES -> Spanish"

Note that source and target languages may be different, which can be retrieved by using the type option:

putsDeepL.languages(type: :source).count# => 24putsDeepL.languages(type: :target).count# => 26

All languages are also defined on the official API documentation.

Note that target languages may include the supports_formality flag, which may be checked using the DeepL::Resources::Language#supports_formality?.

Translate

To translate a simple text, use the translate method:

translation=DeepL.translate'This is my text','EN','ES'putstranslation.class# => DeepL::Resources::Textputstranslation.text# => 'Este es mi texto'

Enable auto-detect source language by skipping the source language with nil:

translation=DeepL.translate'This is my text',nil,'ES'putstranslation.detected_source_language# => 'EN'

Translate a list of texts by passing an array as an argument:

texts=['Sample text','Another text']translations=DeepL.translatetexts,'EN','ES'putstranslations.class# => Arrayputstranslations.first.class# => DeepL::Resources::Text

You can also use custom query parameters, like tag_handling, split_sentences, non_splitting_tags or ignore_tags:

translation=DeepL.translate'<p>A sample</p>','EN','ES',tag_handling: 'xml',split_sentences: false,non_splitting_tags: 'h1',ignore_tags: %w[codepre]putstranslation.text# => "<p>Una muestra</p>"

To specify which version of the tag handling algorithm to use, you can use the tag_handling_version parameter:

translation=DeepL.translate'<p>A sample</p>','EN','ES',tag_handling: 'xml',tag_handling_version: 'v2'putstranslation.text# => "<p>Una muestra</p>"

The available values are 'v1' and 'v2'.

To translate with context, simply supply the context parameter:

translation=DeepL.translate'That is hot!','EN','ES',context: 'He did not like the jalapenos in his meal.'putstranslation.text# => "¡Eso es picante!"

To specify a type of translation model to use, you can use the model_type option:

translation=DeepL.translate'That is hot!','EN','DE',model_type: 'quality_optimized'

This would use next-gen translation models for the translation. The available values are

  • 'quality_optimized': use a translation model that maximizes translation quality, at the cost of response time. This option may be unavailable for some language pairs.
  • 'prefer_quality_optimized': use the highest-quality translation model for the given language pair.
  • 'latency_optimized': use a translation model that minimizes response time, at the cost of translation quality.

To translate with custom instructions, supply the custom_instructions parameter:

translation=DeepL.translate'Hello, world!','EN','DE',custom_instructions: ['Use informal language','Be concise']putstranslation.text

Up to 10 custom instructions can be specified, each with a maximum of 300 characters. The target language must be de, en, es, fr, it, ja, ko, zh or any variants. Note that using custom_instructions will automatically use quality_optimized models, and cannot be combined with model_type: 'latency_optimized'.

The following parameters will be automatically converted:

ParameterConversion
preserve_formattingConverts false to '0' and true to '1'
split_sentencesConverts false to '0' and true to '1'
outline_detectionConverts false to '0' and true to '1'
splitting_tagsConverts arrays to strings joining by commas
non_splitting_tagsConverts arrays to strings joining by commas
ignore_tagsConverts arrays to strings joining by commas
formalityNo conversion applied
glossary_idNo conversion applied
style_ruleNo conversion applied (can be a string ID or a StyleRule object)
translation_memoryNo conversion applied (can be a string ID or a TranslationMemory object)
translation_memory_thresholdNo conversion applied (integer 0-100, recommended minimum 75)
contextNo conversion applied
custom_instructionsNo conversion applied
tag_handling_versionNo conversion applied
extra_body_parametersHash of extra parameters to pass in the body of the HTTP request. Can be used to access beta features, or to override built-in parameters for testing purposes. Extra parameters can override keys explicitly set by the client.

Rephrase Text

To rephrase or improve text, including changing the writing style or tone of the text, use the rephrase method:

rephrased_text=DeepL.rephrase'you will acquire new rephrased text','EN'putsrephrased_text.class# => DeepL::Resources::Textputsrephrased_text.text# => 'You get new rephrased text.'

As with translate, the text input can be a single string or an array of strings.

You can use the additional arguments to specify the writing style or tone you want for the rephrased text:

rephrased_text=DeepL.rephrase'you will acquire new rephrased text','EN','casual'putsrephrased_text.text# => 'You'll get new, rephrased text.'
rephrased_text=DeepL.rephrase'you will acquire new rephrased text','EN',nil,'friendly'putsrephrased_text.text# => 'You'll get to enjoy new, rephrased text!'

Glossaries

To create a glossary, use the glossaries.create method. The glossary entries argument should be an array of text pairs. Each pair includes the source and the target translations.

entries=[['Hello World','Hola Tierra'],['car','auto']]glossary=DeepL.glossaries.create'Mi Glosario','EN','ES',entriesputsglossary.class# => DeepL::Resources::Glossaryputsglossary.id# => 'aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e'putsglossary.entry_count# => 2

Created glossaries can be used in the translate method by specifying the glossary_id option:

translation=DeepL.translate'Hello World','EN','ES',glossary_id: 'aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e'putstranslation.class# => DeepL::Resources::Textputstranslation.text# => 'Hola Tierra'translation=DeepL.translate"I wish we had a car.",'EN','ES',glossary_id: 'aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e'putstranslation.class# => DeepL::Resources::Textputstranslation.text# => Ojalá tuviéramos un auto.

To use more than one glossary at once, specify the glossary_ids option with an array of up to 5 glossary IDs (as strings or DeepL::Resources::Glossary objects) instead of glossary_id. This works for both text and document translation. glossary_ids requires source_lang to be set, cannot be combined with glossary_id, and raises ArgumentError if these rules are violated or more than 5 IDs are provided:

# Text translation with multiple glossariestranslation=DeepL.translate'Hello World','EN','ES',glossary_ids: ['aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e','bb59d8g1-1e13-524f-9b17-e6ccg1db8b7f']# Document translation with multiple glossarieshandle=DeepL.document.upload'my_document.docx','EN','ES','my_document.docx',glossary_ids: ['aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e','bb59d8g1-1e13-524f-9b17-e6ccg1db8b7f']

To list all the glossaries available, use the glossaries.list method:

glossaries=DeepL.glossaries.listputsglossaries.class# => Arrayputsglossaries.first.class# => DeepL::Resources::Glossary

To find an existing glossary, use the glossaries.find method:

glossary=DeepL.glossaries.find'aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e'putsglossary.class# => DeepL::Resources::Glossary

The glossary resource does not include the glossary entries. To list the glossary entries, use the glossaries.entries method:

entries=DeepL.glossaries.entries'aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e'putsentries.class# => Arrayputsentries.size# => 2ppentries.first# => ["Hello World", "Hola Tierra"]

To delete an existing glossary, use the glossaries.destroy method:

glossary_id=DeepL.glossaries.destroy'aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e'putsglossary_id# => aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e

You can list all the language pairs supported by glossaries using the glossaries.language_pairs method:

language_pairs=DeepL.glossaries.language_pairsputslanguage_pairs.class# => Arrayputslanguage_pairs.first.class# => DeepL::Resources::LanguagePairputslanguage_pairs.first.source_lang# => enputslanguage_pairs.first.target_lang# => de

Style Rules

Style rules allow you to customize your translations using a managed, shared list of rules for style, formatting, and more. Multiple style rules can be stored with your account, each with a user-specified name and a uniquely-assigned ID.

Creating a style rule

Use create to create a new style rule with a name and language code. You can optionally provide configured_rules and custom_instructions.

# Simple creation with just a name and languagestyle_rule=DeepL.style_rules.create('My Style Rule','en')puts"Created: #{style_rule.name} (#{style_rule.style_id})"# Creation with configured rules and custom instructionsstyle_rule=DeepL.style_rules.create('Formal English','en',configured_rules: {style_and_tone: {formality: 'formal'}},custom_instructions: [{label: 'Tone',prompt: 'Always use formal language'}])

Retrieving and listing style rules

Use find to retrieve a single style rule by ID, or list to list all style rules.

list returns a list of StyleRule objects corresponding to all of your stored style rules. The method accepts optional parameters: page (page number for pagination, 0-indexed), page_size (number of items per page), and detailed. When true, the response includes configured_rules and custom_instructions for each style rule. When false (default), these fields are omitted for faster responses.

# Get a single style rule by IDstyle_rule=DeepL.style_rules.find('YOUR_STYLE_ID')puts"#{style_rule.name} (#{style_rule.language})"# List all style rulesstyle_rules=DeepL.style_rules.liststyle_rules.eachdo |rule|
puts"#{rule.name} (#{rule.style_id})"end# List with paginationstyle_rules=DeepL.style_rules.list(page: 0,page_size: 10)# List with detailed configurationstyle_rules=DeepL.style_rules.list(detailed: true)style_rules.eachdo |rule|
ifrule.configured_rulesputs" Number formatting: #{rule.configured_rules.numbers.keys.join(', ')}"endend

Updating a style rule

Use update_name to rename a style rule, and update_configured_rules to update its configured rules.

# Update the nameupdated=DeepL.style_rules.update_name('YOUR_STYLE_ID','New Name')# Update configured rulesupdated=DeepL.style_rules.update_configured_rules('YOUR_STYLE_ID',{style_and_tone: {formality: 'formal'}})

The configured_rules hash supports the following categories: dates_and_times, formatting, numbers, punctuation, spelling_and_grammar, style_and_tone, and vocabulary.

Managing custom instructions

Custom instructions allow you to add free-text prompts to a style rule. Each instruction has an id, label, prompt, and source_language. Use create_custom_instruction, find_custom_instruction, update_custom_instruction, and destroy_custom_instruction to manage them.

# Create a custom instructioninstruction=DeepL.style_rules.create_custom_instruction('YOUR_STYLE_ID','Formal tone','Always use formal language')puts"Created instruction: #{instruction.id}"# Create with an optional source languageinstruction=DeepL.style_rules.create_custom_instruction('YOUR_STYLE_ID','Formal tone','Always use formal language','en')# Get a custom instructioninstruction=DeepL.style_rules.find_custom_instruction('YOUR_STYLE_ID',instruction.id)# Update a custom instructionupdated=DeepL.style_rules.update_custom_instruction('YOUR_STYLE_ID',instruction.id,'Updated label','Use very formal language')# Delete a custom instructionDeepL.style_rules.destroy_custom_instruction('YOUR_STYLE_ID',instruction.id)

Deleting a style rule

Use destroy to delete a style rule by ID.

DeepL.style_rules.destroy('YOUR_STYLE_ID')

Using style rules in translations

Style rules can be used in the translate method by specifying the style_rule option with either a style rule ID string or a StyleRule object:

# Using a style rule IDtranslation=DeepL.translate'Hello World','EN','ES',style_rule: 'dca2e053-8ae5-45e6-a0d2-881156e7f4e4'# Or using a StyleRule objectstyle_rules=DeepL.style_rules.listtranslation=DeepL.translate'Hello World','EN','ES',style_rule: style_rules.first

The same style_rule option can be passed to document translation via DeepL.document.upload (or DeepL.document.translate_document), accepting either a style rule ID string or a StyleRule object:

handle=DeepL.document.upload'my_document.docx','EN','ES','my_document.docx',style_rule: 'dca2e053-8ae5-45e6-a0d2-881156e7f4e4'

Translation Memories

Translation memories allow you to store and reuse previously created translations. They can be used in text translation requests to improve consistency by matching against stored segments. Multiple translation memories can be stored with your account, each with a source language and one or more target languages.

Translation memories can also be managed in the DeepL UI via https://www.deepl.com/translation-memory.

Every method that takes a translation memory accepts either a string containing the translation memory ID or a TranslationMemory object.

Listing translation memories

translation_memories.list returns a list of TranslationMemory objects for your stored translation memories. The method accepts optional parameters: page (page number for pagination, 0-indexed) and page_size (number of items per page, max 25).

# List translation memoriestranslation_memories=DeepL.translation_memories.listtranslation_memories.eachdo |tm|
puts"#{tm.name} (#{tm.translation_memory_id})"puts" Source: #{tm.source_language}, Targets: #{tm.target_languages.join(', ')}"puts" Segments: #{tm.segment_count}"end# List with paginationtranslation_memories=DeepL.translation_memories.list(page: 0,page_size: 10)

Retrieving a single translation memory

translation_memories.find retrieves one translation memory by ID. In addition to the fields returned by list, the resource carries the creation_time and updated_time timestamps.

tm=DeepL.translation_memories.find'YOUR_TM_ID'putstm.class# => DeepL::Resources::TranslationMemoryputstm.name# => 'Legal'putstm.segment_count# => 12putstm.creation_time.class# => Time

Listing the segments of a translation memory

translation_memories.segments returns one page of the segments of a translation memory as a TranslationMemorySegments object. Each segment holds the source text and one target per target language of the translation memory.

Pagination is cursor-based: omit page_cursor on the first call, then pass the next_page_cursor of the previous response until next_page? is false. The method also accepts page_size (1-100, defaults to 50), filter_text (a substring matched against the source and target texts, at least 2 characters) and filter_case_sensitive (defaults to false).

Note that segment_count is the number of segments stored in the translation memory; a text filter does not reduce it.

page=DeepL.translation_memories.segments'YOUR_TM_ID',page_size: 50putspage.class# => DeepL::Resources::TranslationMemorySegmentsputspage.segment_count# => 12putspage.segments.first.source_text# => 'Quelltext Nummer 0'putspage.segments.first.targets.first.target_text# => 'Source text number 0'# Walk through every page of segmentswhilepage.next_page?page=DeepL.translation_memories.segments'YOUR_TM_ID',page_size: 50,page_cursor: page.next_page_cursorend# Only the segments matching a textpage=DeepL.translation_memories.segments'YOUR_TM_ID',filter_text: 'Nummer 1',filter_case_sensitive: true

Importing a translation memory

translation_memories.import_from_filepath creates a new translation memory from a TMX file. It creates the import job, uploads the file and waits for the processing to finish, and returns the finished TranslationMemoryJob. Its result carries the ID of the newly created translation memory.

job=DeepL.translation_memories.import_from_filepath'legal.tmx',display_name: 'Legal',timeout_s: 300putsjob.class# => DeepL::Resources::TranslationMemoryJobputsjob.status# => 'completed'putsjob.result.translation_memory_id# => 'a74d88fb-ed2a-4943-a664-a4512398b994'putsjob.result.skipped_segment_count# => 0

The three steps can also be performed separately, for example to upload a file that is not available on the local file system. The upload URL is a pre-signed storage URL outside of the DeepL API, so no authorization header is sent with the upload.

content=File.binread'legal.tmx'created=DeepL.translation_memories.create_import'legal.tmx',content.bytesize,content_type: 'application/xml',display_name: 'Legal'putscreated.upload_url# => 'https://...'DeepL.translation_memories.upload_filecreated,contentjob=DeepL.translation_memories.wait_until_job_donecreated.job_id

Until the file is uploaded the job stays in the awaiting_input status and result.required_action describes what is missing. The API detects the upload asynchronously, so the job keeps reporting awaiting_input for a while afterwards, typically around half a minute, before it completes. wait_until_job_done therefore polls through that status like any other non-terminal one. A job whose file is never uploaded does not finish on its own, so pass timeout_s when that is a possibility.

Exporting a translation memory

translation_memories.export_to_filepath writes a translation memory to a TMX file. It creates the export job, waits for it to finish and downloads the result, overwriting the output file if it already exists.

job=DeepL.translation_memories.export_to_filepath'YOUR_TM_ID','export.tmx'putsjob.status# => 'completed'

The steps can be performed separately as well. Repeating the export of an unchanged translation memory reuses the previously completed job instead of starting a new one, which reused_existing? reports. Just like the upload URL, the download URL is a pre-signed storage URL and is requested without an authorization header.

created=DeepL.translation_memories.create_export'YOUR_TM_ID'putscreated.reused_existing?# => falsejob=DeepL.translation_memories.wait_until_job_donecreated.job_idputsjob.result.download_url# => 'https://...'DeepL.translation_memories.download_exportjob,'export.tmx'

Tracking import and export jobs

translation_memories.find_job returns the current status of an import or export job, and translation_memories.wait_until_job_done polls it every five seconds until it finished, raising if the job failed or expired. Pass timeout_s to give up after a number of seconds instead of waiting forever.

job=DeepL.translation_memories.find_job'YOUR_JOB_ID'putsjob.operation# => 'import'putsjob.status# => 'processing'putsjob.finished?# => false

The status is one of awaiting_input, processing, completed, downloaded, failed or expired.

Deleting a translation memory

translation_memories.destroy deletes a translation memory and returns its ID.

DeepL.translation_memories.destroy'YOUR_TM_ID'# => 'YOUR_TM_ID'

Using a translation memory in translations

Pass the translation_memory parameter to translate to use a translation memory. You can pass either a string containing the translation memory ID, or a TranslationMemory object. Use translation_memory_threshold to control the minimum matching percentage for fuzzy matches (0-100, recommended minimum of 75%).

# Using a translation memory IDtranslation=DeepL.translate'Hello, world!','EN','DE',translation_memory: 'YOUR_TM_ID',translation_memory_threshold: 80# Or using a TranslationMemory objecttranslation_memories=DeepL.translation_memories.listtranslation=DeepL.translate'Hello, world!','EN','DE',translation_memory: translation_memories.first

The same translation_memory and translation_memory_threshold options can be passed to document translation via DeepL.document.upload (or DeepL.document.translate_document). The translation_memory option accepts either a translation memory ID string or a TranslationMemory object:

handle=DeepL.document.upload'my_document.docx','EN','DE','my_document.docx',translation_memory: 'YOUR_TM_ID',translation_memory_threshold: 80

Monitor usage

To check current API usage, use:

usage=DeepL.usageputsusage.character_count# => 180118putsusage.character_limit# => 1250000

Translate documents

To translate a document, use the document.translate_document method. Example:

DeepL.document.translate_document('/path/to/spanish_document.pdf','/path/to/translated_document.pdf','ES','EN')

The lower level upload, get_status and download methods are also exposed, as well as the convenience method wait_until_document_translation_finished on the DocumentHandle object, which would replace get_status:

doc_handle=DeepL.document.upload('/path/to/spanish_document.pdf','ES','EN')doc_status=doc_handle.wait_until_document_translation_finished# alternatively poll `DeepL.document.get_status`# until the `doc_status.successful?`DeepL.document.download(doc_handle,'/path/to/translated_document.pdf')unlessdoc_status.error?

You can also pass additional options to document translation methods, including extra_body_parameters:

options={formality: 'more',extra_body_parameters: {example_param: 'true'}}doc_handle=DeepL.document.upload('/path/to/spanish_document.pdf','ES','EN',nil,options)

The extra_body_parameters option allows you to pass arbitrary parameters in the request body. This can be used to access beta features by adding new parameters, or to override built-in parameters (such as target_lang, source_lang, etc.) for testing purposes.

Sending additional HTTP headers

You can pass additional HTTP headers to translate, rephrase, and the document methods. For example, to send the X-DeepL-Reporting-Tag header for usage reporting (see the cookbook entry):

additional_headers={'X-DeepL-Reporting-Tag'=>'my-tag'}translation=DeepL.translate'Hello, world!','EN','DE',{},additional_headersrephrased=DeepL.rephrase'Hello, world!','EN',nil,nil,{},additional_headers

Handle exceptions

You can capture and process exceptions that may be raised during API calls. These are all the possible exceptions:

Exception classDescription
DeepL::Exceptions::AuthorizationFailedThe authorization process has failed. Check your auth_key value.
DeepL::Exceptions::BadRequestSomething is wrong in your request. Check exception.message for more information.
DeepL::Exceptions::DocumentTranslationErrorAn error occured during document translation. Check exception.message for more information.
DeepL::Exceptions::LimitExceededYou've reached the API's call limit.
DeepL::Exceptions::QuotaExceededYou've reached the API's character limit.
DeepL::Exceptions::RequestErrorAn unkown request error. Check exception.response and exception.request for more information.
DeepL::Exceptions::NotSupportedThe requested method or API endpoint is not supported.
DeepL::Exceptions::RequestEntityTooLargeYour request is too large, reduce the amount of data you are sending. The API has a request size limit of 128 KiB.
DeepL::Exceptions::ServerErrorAn error occured in the DeepL API, wait a short amount of time and retry.

An exampling of handling a generic exception:

defmy_methoditem=DeepL.translate'This is my text',nil,'ES'rescueDeepL::Exceptions::RequestError=>eputs'Oops!'puts"Code: #{e.response.code}"puts"Response body: #{e.response.body}"puts"Request body: #{e.request.body}"end

Logging

To enable logging, pass a suitable logging object (e.g. the default Logger from the Ruby standard library) when configuring the library. The library logs HTTP requests to INFO and debug information to DEBUG. Example:

require'logger'logger=Logger.new(STDOUT)logger.level=Logger::INFOdeepl.configuredo |config|
config.auth_key=configuration.auth_keyconfig.logger=loggerend

Proxy configuration

To use HTTP proxies, a session needs to be used. The proxy can then be configured as part of the HTTP client options:

client_options=HTTPClientOptions.new({'proxy_addr'=>'http://localhost','proxy_port'=>80})deepl.with_session(client_options)do |session|
# ...end

Anonymous platform information

By default, we send some basic information about the platform the client library is running on with each request, see here for an explanation. This data is completely anonymous and only used to improve our product, not track any individual users. If you do not wish to send this data, you can opt-out by setting the send_platform_info flag in the configuration to false like so:

deepl.configure({},nil,nil,false)do |config|
# ...end

You can also complete customize the User-Agent header like so:

deepl.configuredo |config|
config.user_agent='myCustomUserAgent'end

Sending multiple requests

When writing an application that send multiple requests, using a HTTP session will give better performance through HTTP Keep-Alive. You can use it by simply wrapping your requests in a with_session block:

deepl.with_sessiondo |session|
deepl.translate(sentence1,'DE','EN-GB')deepl.translate(sentence2,'DE','EN-GB')deepl.translate(sentence3,'DE','EN-GB')end

Writing a plugin

If you use this library in an application, please identify the application by setting the name and version of the plugin:

deepl.configure({},'MyTranslationPlugin','1.0.1')do |config|
# ...end

This information is passed along when the library makes calls to the DeepL API. Both name and version are required. Please note that setting the User-Agent header via deepl.configure will override this setting, if you need to use this, please manually identify your Application in the User-Agent header.

Options Constants

The available values for various possible options are provided under the DeepL::Constants namespace. The currently available options are

TagHandlingSplitSentencesModelTypeFormalityWritingStyleTone

To view all the possible options for a given constant, call options:

all_available_tones=DeepL::Constants::Tones.options

To check if a given string is a possible option for a given constant, call valid?:

DeepL::Constants::Tones.valid?('friendly')# trueDeepL::Constants::Tones.valid?('rude')# false

Integrations

Ruby on Rails

You may use this gem as a standalone service by creating an initializer on your config/initializers folder with your DeepL configuration. For example:

# config/initializers/deepl.rbDeepL.configuredo |config|
# Your configuration goes hereend

Since the DeepL service is defined globally, you can use service anywhere in your code (controllers, models, views, jobs, plain ruby objects… you name it).

i18n-tasks

You may also take a look at i18n-tasks, which is a gem that helps you find and manage missing and unused translations. deepl-rb is used as one of the backend services to translate content.

Development

Clone the repository, and install its dependencies:

git clone https://github.com/DeepLcom/deepl-rb
cd deepl-rb
bundle install

To run tests (rspec and rubocop), use

bundle exec rake test

Acknowledgements

This library was originally developed by Daniel Herzog, we are grateful for his contributions. Beginning with v3.0.0, DeepL took over development and officially supports and maintains the library together with Daniel.

About

Official Ruby library for the DeepL language translation API.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

19 stars

Watchers

1 watching

Forks

Releases

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Gem Version

DeepL Ruby Library

The DeepL API is a language translation API that allows other computer programs to send texts and documents to DeepL's servers and receive high-quality translations. This opens a whole universe of opportunities for developers: any translation product you can imagine can now be built on top of DeepL's best-in-class translation technology.

The DeepL Ruby library offers a convenient way for applications written in Ruby to interact with the DeepL API. We intend to support all API functions with the library, though support for new features may be added to the library after they’re added to the API.

Getting an authentication key

To use the DeepL Ruby Library, you'll need an API authentication key. To get a key, please create an account here. With a DeepL API Free account you can translate up to 500,000 characters/month for free.

Installation

Install this gem with

gem install deepl-rb
# Load it in your ruby file using `require 'deepl'`

Or add it to your Gemfile:

gem'deepl-rb',require: 'deepl'

Usage

Setup an environment variable named DEEPL_AUTH_KEY with your authentication key:

export DEEPL_AUTH_KEY="your-api-token"

Alternatively, you can configure the API client within a ruby block:

DeepL.configuredo |config|
config.auth_key='your-api-token'end

You can also configure the API host and the API version:

DeepL.configuredo |config|
config.auth_key='your-api-token'config.host='https://api-free.deepl.com'# Default value is 'https://api.deepl.com'config.version='v1'# Default value is 'v2'end

Available languages

Available languages can be retrieved via API:

languages=DeepL.languagesputslanguages.class# => Arrayputslanguages.first.class# => DeepL::Resources::Languageputs"#{languages.first.code} -> #{languages.first.name}"# => "ES -> Spanish"

Note that source and target languages may be different, which can be retrieved by using the type option:

putsDeepL.languages(type: :source).count# => 24putsDeepL.languages(type: :target).count# => 26

All languages are also defined on the official API documentation.

Note that target languages may include the supports_formality flag, which may be checked using the DeepL::Resources::Language#supports_formality?.

Translate

To translate a simple text, use the translate method:

translation=DeepL.translate'This is my text','EN','ES'putstranslation.class# => DeepL::Resources::Textputstranslation.text# => 'Este es mi texto'

Enable auto-detect source language by skipping the source language with nil:

translation=DeepL.translate'This is my text',nil,'ES'putstranslation.detected_source_language# => 'EN'

Translate a list of texts by passing an array as an argument:

texts=['Sample text','Another text']translations=DeepL.translatetexts,'EN','ES'putstranslations.class# => Arrayputstranslations.first.class# => DeepL::Resources::Text

You can also use custom query parameters, like tag_handling, split_sentences, non_splitting_tags or ignore_tags:

translation=DeepL.translate'<p>A sample</p>','EN','ES',tag_handling: 'xml',split_sentences: false,non_splitting_tags: 'h1',ignore_tags: %w[codepre]putstranslation.text# => "<p>Una muestra</p>"

To specify which version of the tag handling algorithm to use, you can use the tag_handling_version parameter:

translation=DeepL.translate'<p>A sample</p>','EN','ES',tag_handling: 'xml',tag_handling_version: 'v2'putstranslation.text# => "<p>Una muestra</p>"

The available values are 'v1' and 'v2'.

To translate with context, simply supply the context parameter:

translation=DeepL.translate'That is hot!','EN','ES',context: 'He did not like the jalapenos in his meal.'putstranslation.text# => "¡Eso es picante!"

To specify a type of translation model to use, you can use the model_type option:

translation=DeepL.translate'That is hot!','EN','DE',model_type: 'quality_optimized'

This would use next-gen translation models for the translation. The available values are

  • 'quality_optimized': use a translation model that maximizes translation quality, at the cost of response time. This option may be unavailable for some language pairs.
  • 'prefer_quality_optimized': use the highest-quality translation model for the given language pair.
  • 'latency_optimized': use a translation model that minimizes response time, at the cost of translation quality.

To translate with custom instructions, supply the custom_instructions parameter:

translation=DeepL.translate'Hello, world!','EN','DE',custom_instructions: ['Use informal language','Be concise']putstranslation.text

Up to 10 custom instructions can be specified, each with a maximum of 300 characters. The target language must be de, en, es, fr, it, ja, ko, zh or any variants. Note that using custom_instructions will automatically use quality_optimized models, and cannot be combined with model_type: 'latency_optimized'.

The following parameters will be automatically converted:

ParameterConversion
preserve_formattingConverts false to '0' and true to '1'
split_sentencesConverts false to '0' and true to '1'
outline_detectionConverts false to '0' and true to '1'
splitting_tagsConverts arrays to strings joining by commas
non_splitting_tagsConverts arrays to strings joining by commas
ignore_tagsConverts arrays to strings joining by commas
formalityNo conversion applied
glossary_idNo conversion applied
style_ruleNo conversion applied (can be a string ID or a StyleRule object)
translation_memoryNo conversion applied (can be a string ID or a TranslationMemory object)
translation_memory_thresholdNo conversion applied (integer 0-100, recommended minimum 75)
contextNo conversion applied
custom_instructionsNo conversion applied
tag_handling_versionNo conversion applied
extra_body_parametersHash of extra parameters to pass in the body of the HTTP request. Can be used to access beta features, or to override built-in parameters for testing purposes. Extra parameters can override keys explicitly set by the client.

Rephrase Text

To rephrase or improve text, including changing the writing style or tone of the text, use the rephrase method:

rephrased_text=DeepL.rephrase'you will acquire new rephrased text','EN'putsrephrased_text.class# => DeepL::Resources::Textputsrephrased_text.text# => 'You get new rephrased text.'

As with translate, the text input can be a single string or an array of strings.

You can use the additional arguments to specify the writing style or tone you want for the rephrased text:

rephrased_text=DeepL.rephrase'you will acquire new rephrased text','EN','casual'putsrephrased_text.text# => 'You'll get new, rephrased text.'
rephrased_text=DeepL.rephrase'you will acquire new rephrased text','EN',nil,'friendly'putsrephrased_text.text# => 'You'll get to enjoy new, rephrased text!'

Glossaries

To create a glossary, use the glossaries.create method. The glossary entries argument should be an array of text pairs. Each pair includes the source and the target translations.

entries=[['Hello World','Hola Tierra'],['car','auto']]glossary=DeepL.glossaries.create'Mi Glosario','EN','ES',entriesputsglossary.class# => DeepL::Resources::Glossaryputsglossary.id# => 'aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e'putsglossary.entry_count# => 2

Created glossaries can be used in the translate method by specifying the glossary_id option:

translation=DeepL.translate'Hello World','EN','ES',glossary_id: 'aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e'putstranslation.class# => DeepL::Resources::Textputstranslation.text# => 'Hola Tierra'translation=DeepL.translate"I wish we had a car.",'EN','ES',glossary_id: 'aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e'putstranslation.class# => DeepL::Resources::Textputstranslation.text# => Ojalá tuviéramos un auto.

To use more than one glossary at once, specify the glossary_ids option with an array of up to 5 glossary IDs (as strings or DeepL::Resources::Glossary objects) instead of glossary_id. This works for both text and document translation. glossary_ids requires source_lang to be set, cannot be combined with glossary_id, and raises ArgumentError if these rules are violated or more than 5 IDs are provided:

# Text translation with multiple glossariestranslation=DeepL.translate'Hello World','EN','ES',glossary_ids: ['aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e','bb59d8g1-1e13-524f-9b17-e6ccg1db8b7f']# Document translation with multiple glossarieshandle=DeepL.document.upload'my_document.docx','EN','ES','my_document.docx',glossary_ids: ['aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e','bb59d8g1-1e13-524f-9b17-e6ccg1db8b7f']

To list all the glossaries available, use the glossaries.list method:

glossaries=DeepL.glossaries.listputsglossaries.class# => Arrayputsglossaries.first.class# => DeepL::Resources::Glossary

To find an existing glossary, use the glossaries.find method:

glossary=DeepL.glossaries.find'aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e'putsglossary.class# => DeepL::Resources::Glossary

The glossary resource does not include the glossary entries. To list the glossary entries, use the glossaries.entries method:

entries=DeepL.glossaries.entries'aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e'putsentries.class# => Arrayputsentries.size# => 2ppentries.first# => ["Hello World", "Hola Tierra"]

To delete an existing glossary, use the glossaries.destroy method:

glossary_id=DeepL.glossaries.destroy'aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e'putsglossary_id# => aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e

You can list all the language pairs supported by glossaries using the glossaries.language_pairs method:

language_pairs=DeepL.glossaries.language_pairsputslanguage_pairs.class# => Arrayputslanguage_pairs.first.class# => DeepL::Resources::LanguagePairputslanguage_pairs.first.source_lang# => enputslanguage_pairs.first.target_lang# => de

Style Rules

Style rules allow you to customize your translations using a managed, shared list of rules for style, formatting, and more. Multiple style rules can be stored with your account, each with a user-specified name and a uniquely-assigned ID.

Creating a style rule

Use create to create a new style rule with a name and language code. You can optionally provide configured_rules and custom_instructions.

# Simple creation with just a name and languagestyle_rule=DeepL.style_rules.create('My Style Rule','en')puts"Created: #{style_rule.name} (#{style_rule.style_id})"# Creation with configured rules and custom instructionsstyle_rule=DeepL.style_rules.create('Formal English','en',configured_rules: {style_and_tone: {formality: 'formal'}},custom_instructions: [{label: 'Tone',prompt: 'Always use formal language'}])

Retrieving and listing style rules

Use find to retrieve a single style rule by ID, or list to list all style rules.

list returns a list of StyleRule objects corresponding to all of your stored style rules. The method accepts optional parameters: page (page number for pagination, 0-indexed), page_size (number of items per page), and detailed. When true, the response includes configured_rules and custom_instructions for each style rule. When false (default), these fields are omitted for faster responses.

# Get a single style rule by IDstyle_rule=DeepL.style_rules.find('YOUR_STYLE_ID')puts"#{style_rule.name} (#{style_rule.language})"# List all style rulesstyle_rules=DeepL.style_rules.liststyle_rules.eachdo |rule|
puts"#{rule.name} (#{rule.style_id})"end# List with paginationstyle_rules=DeepL.style_rules.list(page: 0,page_size: 10)# List with detailed configurationstyle_rules=DeepL.style_rules.list(detailed: true)style_rules.eachdo |rule|
ifrule.configured_rulesputs" Number formatting: #{rule.configured_rules.numbers.keys.join(', ')}"endend

Updating a style rule

Use update_name to rename a style rule, and update_configured_rules to update its configured rules.

# Update the nameupdated=DeepL.style_rules.update_name('YOUR_STYLE_ID','New Name')# Update configured rulesupdated=DeepL.style_rules.update_configured_rules('YOUR_STYLE_ID',{style_and_tone: {formality: 'formal'}})

The configured_rules hash supports the following categories: dates_and_times, formatting, numbers, punctuation, spelling_and_grammar, style_and_tone, and vocabulary.

Managing custom instructions

Custom instructions allow you to add free-text prompts to a style rule. Each instruction has an id, label, prompt, and source_language. Use create_custom_instruction, find_custom_instruction, update_custom_instruction, and destroy_custom_instruction to manage them.

# Create a custom instructioninstruction=DeepL.style_rules.create_custom_instruction('YOUR_STYLE_ID','Formal tone','Always use formal language')puts"Created instruction: #{instruction.id}"# Create with an optional source languageinstruction=DeepL.style_rules.create_custom_instruction('YOUR_STYLE_ID','Formal tone','Always use formal language','en')# Get a custom instructioninstruction=DeepL.style_rules.find_custom_instruction('YOUR_STYLE_ID',instruction.id)# Update a custom instructionupdated=DeepL.style_rules.update_custom_instruction('YOUR_STYLE_ID',instruction.id,'Updated label','Use very formal language')# Delete a custom instructionDeepL.style_rules.destroy_custom_instruction('YOUR_STYLE_ID',instruction.id)

Deleting a style rule

Use destroy to delete a style rule by ID.

DeepL.style_rules.destroy('YOUR_STYLE_ID')

Using style rules in translations

Style rules can be used in the translate method by specifying the style_rule option with either a style rule ID string or a StyleRule object:

# Using a style rule IDtranslation=DeepL.translate'Hello World','EN','ES',style_rule: 'dca2e053-8ae5-45e6-a0d2-881156e7f4e4'# Or using a StyleRule objectstyle_rules=DeepL.style_rules.listtranslation=DeepL.translate'Hello World','EN','ES',style_rule: style_rules.first

The same style_rule option can be passed to document translation via DeepL.document.upload (or DeepL.document.translate_document), accepting either a style rule ID string or a StyleRule object:

handle=DeepL.document.upload'my_document.docx','EN','ES','my_document.docx',style_rule: 'dca2e053-8ae5-45e6-a0d2-881156e7f4e4'

Translation Memories

Translation memories allow you to store and reuse previously created translations. They can be used in text translation requests to improve consistency by matching against stored segments. Multiple translation memories can be stored with your account, each with a source language and one or more target languages.

Translation memories can also be managed in the DeepL UI via https://www.deepl.com/translation-memory.

Every method that takes a translation memory accepts either a string containing the translation memory ID or a TranslationMemory object.

Listing translation memories

translation_memories.list returns a list of TranslationMemory objects for your stored translation memories. The method accepts optional parameters: page (page number for pagination, 0-indexed) and page_size (number of items per page, max 25).

# List translation memoriestranslation_memories=DeepL.translation_memories.listtranslation_memories.eachdo |tm|
puts"#{tm.name} (#{tm.translation_memory_id})"puts" Source: #{tm.source_language}, Targets: #{tm.target_languages.join(', ')}"puts" Segments: #{tm.segment_count}"end# List with paginationtranslation_memories=DeepL.translation_memories.list(page: 0,page_size: 10)

Retrieving a single translation memory

translation_memories.find retrieves one translation memory by ID. In addition to the fields returned by list, the resource carries the creation_time and updated_time timestamps.

tm=DeepL.translation_memories.find'YOUR_TM_ID'putstm.class# => DeepL::Resources::TranslationMemoryputstm.name# => 'Legal'putstm.segment_count# => 12putstm.creation_time.class# => Time

Listing the segments of a translation memory

translation_memories.segments returns one page of the segments of a translation memory as a TranslationMemorySegments object. Each segment holds the source text and one target per target language of the translation memory.

Pagination is cursor-based: omit page_cursor on the first call, then pass the next_page_cursor of the previous response until next_page? is false. The method also accepts page_size (1-100, defaults to 50), filter_text (a substring matched against the source and target texts, at least 2 characters) and filter_case_sensitive (defaults to false).

Note that segment_count is the number of segments stored in the translation memory; a text filter does not reduce it.

page=DeepL.translation_memories.segments'YOUR_TM_ID',page_size: 50putspage.class# => DeepL::Resources::TranslationMemorySegmentsputspage.segment_count# => 12putspage.segments.first.source_text# => 'Quelltext Nummer 0'putspage.segments.first.targets.first.target_text# => 'Source text number 0'# Walk through every page of segmentswhilepage.next_page?page=DeepL.translation_memories.segments'YOUR_TM_ID',page_size: 50,page_cursor: page.next_page_cursorend# Only the segments matching a textpage=DeepL.translation_memories.segments'YOUR_TM_ID',filter_text: 'Nummer 1',filter_case_sensitive: true

Importing a translation memory

translation_memories.import_from_filepath creates a new translation memory from a TMX file. It creates the import job, uploads the file and waits for the processing to finish, and returns the finished TranslationMemoryJob. Its result carries the ID of the newly created translation memory.

job=DeepL.translation_memories.import_from_filepath'legal.tmx',display_name: 'Legal',timeout_s: 300putsjob.class# => DeepL::Resources::TranslationMemoryJobputsjob.status# => 'completed'putsjob.result.translation_memory_id# => 'a74d88fb-ed2a-4943-a664-a4512398b994'putsjob.result.skipped_segment_count# => 0

The three steps can also be performed separately, for example to upload a file that is not available on the local file system. The upload URL is a pre-signed storage URL outside of the DeepL API, so no authorization header is sent with the upload.

content=File.binread'legal.tmx'created=DeepL.translation_memories.create_import'legal.tmx',content.bytesize,content_type: 'application/xml',display_name: 'Legal'putscreated.upload_url# => 'https://...'DeepL.translation_memories.upload_filecreated,contentjob=DeepL.translation_memories.wait_until_job_donecreated.job_id

Until the file is uploaded the job stays in the awaiting_input status and result.required_action describes what is missing. The API detects the upload asynchronously, so the job keeps reporting awaiting_input for a while afterwards, typically around half a minute, before it completes. wait_until_job_done therefore polls through that status like any other non-terminal one. A job whose file is never uploaded does not finish on its own, so pass timeout_s when that is a possibility.

Exporting a translation memory

translation_memories.export_to_filepath writes a translation memory to a TMX file. It creates the export job, waits for it to finish and downloads the result, overwriting the output file if it already exists.

job=DeepL.translation_memories.export_to_filepath'YOUR_TM_ID','export.tmx'putsjob.status# => 'completed'

The steps can be performed separately as well. Repeating the export of an unchanged translation memory reuses the previously completed job instead of starting a new one, which reused_existing? reports. Just like the upload URL, the download URL is a pre-signed storage URL and is requested without an authorization header.

created=DeepL.translation_memories.create_export'YOUR_TM_ID'putscreated.reused_existing?# => falsejob=DeepL.translation_memories.wait_until_job_donecreated.job_idputsjob.result.download_url# => 'https://...'DeepL.translation_memories.download_exportjob,'export.tmx'

Tracking import and export jobs

translation_memories.find_job returns the current status of an import or export job, and translation_memories.wait_until_job_done polls it every five seconds until it finished, raising if the job failed or expired. Pass timeout_s to give up after a number of seconds instead of waiting forever.

job=DeepL.translation_memories.find_job'YOUR_JOB_ID'putsjob.operation# => 'import'putsjob.status# => 'processing'putsjob.finished?# => false

The status is one of awaiting_input, processing, completed, downloaded, failed or expired.

Deleting a translation memory

translation_memories.destroy deletes a translation memory and returns its ID.

DeepL.translation_memories.destroy'YOUR_TM_ID'# => 'YOUR_TM_ID'

Using a translation memory in translations

Pass the translation_memory parameter to translate to use a translation memory. You can pass either a string containing the translation memory ID, or a TranslationMemory object. Use translation_memory_threshold to control the minimum matching percentage for fuzzy matches (0-100, recommended minimum of 75%).

# Using a translation memory IDtranslation=DeepL.translate'Hello, world!','EN','DE',translation_memory: 'YOUR_TM_ID',translation_memory_threshold: 80# Or using a TranslationMemory objecttranslation_memories=DeepL.translation_memories.listtranslation=DeepL.translate'Hello, world!','EN','DE',translation_memory: translation_memories.first

The same translation_memory and translation_memory_threshold options can be passed to document translation via DeepL.document.upload (or DeepL.document.translate_document). The translation_memory option accepts either a translation memory ID string or a TranslationMemory object:

handle=DeepL.document.upload'my_document.docx','EN','DE','my_document.docx',translation_memory: 'YOUR_TM_ID',translation_memory_threshold: 80

Monitor usage

To check current API usage, use:

usage=DeepL.usageputsusage.character_count# => 180118putsusage.character_limit# => 1250000

Translate documents

To translate a document, use the document.translate_document method. Example:

DeepL.document.translate_document('/path/to/spanish_document.pdf','/path/to/translated_document.pdf','ES','EN')

The lower level upload, get_status and download methods are also exposed, as well as the convenience method wait_until_document_translation_finished on the DocumentHandle object, which would replace get_status:

doc_handle=DeepL.document.upload('/path/to/spanish_document.pdf','ES','EN')doc_status=doc_handle.wait_until_document_translation_finished# alternatively poll `DeepL.document.get_status`# until the `doc_status.successful?`DeepL.document.download(doc_handle,'/path/to/translated_document.pdf')unlessdoc_status.error?

You can also pass additional options to document translation methods, including extra_body_parameters:

options={formality: 'more',extra_body_parameters: {example_param: 'true'}}doc_handle=DeepL.document.upload('/path/to/spanish_document.pdf','ES','EN',nil,options)

The extra_body_parameters option allows you to pass arbitrary parameters in the request body. This can be used to access beta features by adding new parameters, or to override built-in parameters (such as target_lang, source_lang, etc.) for testing purposes.

Sending additional HTTP headers

You can pass additional HTTP headers to translate, rephrase, and the document methods. For example, to send the X-DeepL-Reporting-Tag header for usage reporting (see the cookbook entry):

additional_headers={'X-DeepL-Reporting-Tag'=>'my-tag'}translation=DeepL.translate'Hello, world!','EN','DE',{},additional_headersrephrased=DeepL.rephrase'Hello, world!','EN',nil,nil,{},additional_headers

Handle exceptions

You can capture and process exceptions that may be raised during API calls. These are all the possible exceptions:

Exception classDescription
DeepL::Exceptions::AuthorizationFailedThe authorization process has failed. Check your auth_key value.
DeepL::Exceptions::BadRequestSomething is wrong in your request. Check exception.message for more information.
DeepL::Exceptions::DocumentTranslationErrorAn error occured during document translation. Check exception.message for more information.
DeepL::Exceptions::LimitExceededYou've reached the API's call limit.
DeepL::Exceptions::QuotaExceededYou've reached the API's character limit.
DeepL::Exceptions::RequestErrorAn unkown request error. Check exception.response and exception.request for more information.
DeepL::Exceptions::NotSupportedThe requested method or API endpoint is not supported.
DeepL::Exceptions::RequestEntityTooLargeYour request is too large, reduce the amount of data you are sending. The API has a request size limit of 128 KiB.
DeepL::Exceptions::ServerErrorAn error occured in the DeepL API, wait a short amount of time and retry.

An exampling of handling a generic exception:

defmy_methoditem=DeepL.translate'This is my text',nil,'ES'rescueDeepL::Exceptions::RequestError=>eputs'Oops!'puts"Code: #{e.response.code}"puts"Response body: #{e.response.body}"puts"Request body: #{e.request.body}"end

Logging

To enable logging, pass a suitable logging object (e.g. the default Logger from the Ruby standard library) when configuring the library. The library logs HTTP requests to INFO and debug information to DEBUG. Example:

require'logger'logger=Logger.new(STDOUT)logger.level=Logger::INFOdeepl.configuredo |config|
config.auth_key=configuration.auth_keyconfig.logger=loggerend

Proxy configuration

To use HTTP proxies, a session needs to be used. The proxy can then be configured as part of the HTTP client options:

client_options=HTTPClientOptions.new({'proxy_addr'=>'http://localhost','proxy_port'=>80})deepl.with_session(client_options)do |session|
# ...end

Anonymous platform information

By default, we send some basic information about the platform the client library is running on with each request, see here for an explanation. This data is completely anonymous and only used to improve our product, not track any individual users. If you do not wish to send this data, you can opt-out by setting the send_platform_info flag in the configuration to false like so:

deepl.configure({},nil,nil,false)do |config|
# ...end

You can also complete customize the User-Agent header like so:

deepl.configuredo |config|
config.user_agent='myCustomUserAgent'end

Sending multiple requests

When writing an application that send multiple requests, using a HTTP session will give better performance through HTTP Keep-Alive. You can use it by simply wrapping your requests in a with_session block:

deepl.with_sessiondo |session|
deepl.translate(sentence1,'DE','EN-GB')deepl.translate(sentence2,'DE','EN-GB')deepl.translate(sentence3,'DE','EN-GB')end

Writing a plugin

If you use this library in an application, please identify the application by setting the name and version of the plugin:

deepl.configure({},'MyTranslationPlugin','1.0.1')do |config|
# ...end

This information is passed along when the library makes calls to the DeepL API. Both name and version are required. Please note that setting the User-Agent header via deepl.configure will override this setting, if you need to use this, please manually identify your Application in the User-Agent header.

Options Constants

The available values for various possible options are provided under the DeepL::Constants namespace. The currently available options are

TagHandlingSplitSentencesModelTypeFormalityWritingStyleTone

To view all the possible options for a given constant, call options:

all_available_tones=DeepL::Constants::Tones.options

To check if a given string is a possible option for a given constant, call valid?:

DeepL::Constants::Tones.valid?('friendly')# trueDeepL::Constants::Tones.valid?('rude')# false

Integrations

Ruby on Rails

You may use this gem as a standalone service by creating an initializer on your config/initializers folder with your DeepL configuration. For example:

# config/initializers/deepl.rbDeepL.configuredo |config|
# Your configuration goes hereend

Since the DeepL service is defined globally, you can use service anywhere in your code (controllers, models, views, jobs, plain ruby objects… you name it).

i18n-tasks

You may also take a look at i18n-tasks, which is a gem that helps you find and manage missing and unused translations. deepl-rb is used as one of the backend services to translate content.

Development

Clone the repository, and install its dependencies:

git clone https://github.com/DeepLcom/deepl-rb
cd deepl-rb
bundle install

To run tests (rspec and rubocop), use

bundle exec rake test

Acknowledgements

This library was originally developed by Daniel Herzog, we are grateful for his contributions. Beginning with v3.0.0, DeepL took over development and officially supports and maintains the library together with Daniel.

About

Official Ruby library for the DeepL language translation API.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

19 stars

Watchers

1 watching

Forks

Releases

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Gem Version

DeepL Ruby Library

The DeepL API is a language translation API that allows other computer programs to send texts and documents to DeepL's servers and receive high-quality translations. This opens a whole universe of opportunities for developers: any translation product you can imagine can now be built on top of DeepL's best-in-class translation technology.

The DeepL Ruby library offers a convenient way for applications written in Ruby to interact with the DeepL API. We intend to support all API functions with the library, though support for new features may be added to the library after they’re added to the API.

Getting an authentication key

To use the DeepL Ruby Library, you'll need an API authentication key. To get a key, please create an account here. With a DeepL API Free account you can translate up to 500,000 characters/month for free.

Installation

Install this gem with

gem install deepl-rb
# Load it in your ruby file using `require 'deepl'`

Or add it to your Gemfile:

gem'deepl-rb',require: 'deepl'

Usage

Setup an environment variable named DEEPL_AUTH_KEY with your authentication key:

export DEEPL_AUTH_KEY="your-api-token"

Alternatively, you can configure the API client within a ruby block:

DeepL.configuredo |config|
config.auth_key='your-api-token'end

You can also configure the API host and the API version:

DeepL.configuredo |config|
config.auth_key='your-api-token'config.host='https://api-free.deepl.com'# Default value is 'https://api.deepl.com'config.version='v1'# Default value is 'v2'end

Available languages

Available languages can be retrieved via API:

languages=DeepL.languagesputslanguages.class# => Arrayputslanguages.first.class# => DeepL::Resources::Languageputs"#{languages.first.code} -> #{languages.first.name}"# => "ES -> Spanish"

Note that source and target languages may be different, which can be retrieved by using the type option:

putsDeepL.languages(type: :source).count# => 24putsDeepL.languages(type: :target).count# => 26

All languages are also defined on the official API documentation.

Note that target languages may include the supports_formality flag, which may be checked using the DeepL::Resources::Language#supports_formality?.

Translate

To translate a simple text, use the translate method:

translation=DeepL.translate'This is my text','EN','ES'putstranslation.class# => DeepL::Resources::Textputstranslation.text# => 'Este es mi texto'

Enable auto-detect source language by skipping the source language with nil:

translation=DeepL.translate'This is my text',nil,'ES'putstranslation.detected_source_language# => 'EN'

Translate a list of texts by passing an array as an argument:

texts=['Sample text','Another text']translations=DeepL.translatetexts,'EN','ES'putstranslations.class# => Arrayputstranslations.first.class# => DeepL::Resources::Text

You can also use custom query parameters, like tag_handling, split_sentences, non_splitting_tags or ignore_tags:

translation=DeepL.translate'<p>A sample</p>','EN','ES',tag_handling: 'xml',split_sentences: false,non_splitting_tags: 'h1',ignore_tags: %w[codepre]putstranslation.text# => "<p>Una muestra</p>"

To specify which version of the tag handling algorithm to use, you can use the tag_handling_version parameter:

translation=DeepL.translate'<p>A sample</p>','EN','ES',tag_handling: 'xml',tag_handling_version: 'v2'putstranslation.text# => "<p>Una muestra</p>"

The available values are 'v1' and 'v2'.

To translate with context, simply supply the context parameter:

translation=DeepL.translate'That is hot!','EN','ES',context: 'He did not like the jalapenos in his meal.'putstranslation.text# => "¡Eso es picante!"

To specify a type of translation model to use, you can use the model_type option:

translation=DeepL.translate'That is hot!','EN','DE',model_type: 'quality_optimized'

This would use next-gen translation models for the translation. The available values are

  • 'quality_optimized': use a translation model that maximizes translation quality, at the cost of response time. This option may be unavailable for some language pairs.
  • 'prefer_quality_optimized': use the highest-quality translation model for the given language pair.
  • 'latency_optimized': use a translation model that minimizes response time, at the cost of translation quality.

To translate with custom instructions, supply the custom_instructions parameter:

translation=DeepL.translate'Hello, world!','EN','DE',custom_instructions: ['Use informal language','Be concise']putstranslation.text

Up to 10 custom instructions can be specified, each with a maximum of 300 characters. The target language must be de, en, es, fr, it, ja, ko, zh or any variants. Note that using custom_instructions will automatically use quality_optimized models, and cannot be combined with model_type: 'latency_optimized'.

The following parameters will be automatically converted:

ParameterConversion
preserve_formattingConverts false to '0' and true to '1'
split_sentencesConverts false to '0' and true to '1'
outline_detectionConverts false to '0' and true to '1'
splitting_tagsConverts arrays to strings joining by commas
non_splitting_tagsConverts arrays to strings joining by commas
ignore_tagsConverts arrays to strings joining by commas
formalityNo conversion applied
glossary_idNo conversion applied
style_ruleNo conversion applied (can be a string ID or a StyleRule object)
translation_memoryNo conversion applied (can be a string ID or a TranslationMemory object)
translation_memory_thresholdNo conversion applied (integer 0-100, recommended minimum 75)
contextNo conversion applied
custom_instructionsNo conversion applied
tag_handling_versionNo conversion applied
extra_body_parametersHash of extra parameters to pass in the body of the HTTP request. Can be used to access beta features, or to override built-in parameters for testing purposes. Extra parameters can override keys explicitly set by the client.

Rephrase Text

To rephrase or improve text, including changing the writing style or tone of the text, use the rephrase method:

rephrased_text=DeepL.rephrase'you will acquire new rephrased text','EN'putsrephrased_text.class# => DeepL::Resources::Textputsrephrased_text.text# => 'You get new rephrased text.'

As with translate, the text input can be a single string or an array of strings.

You can use the additional arguments to specify the writing style or tone you want for the rephrased text:

rephrased_text=DeepL.rephrase'you will acquire new rephrased text','EN','casual'putsrephrased_text.text# => 'You'll get new, rephrased text.'
rephrased_text=DeepL.rephrase'you will acquire new rephrased text','EN',nil,'friendly'putsrephrased_text.text# => 'You'll get to enjoy new, rephrased text!'

Glossaries

To create a glossary, use the glossaries.create method. The glossary entries argument should be an array of text pairs. Each pair includes the source and the target translations.

entries=[['Hello World','Hola Tierra'],['car','auto']]glossary=DeepL.glossaries.create'Mi Glosario','EN','ES',entriesputsglossary.class# => DeepL::Resources::Glossaryputsglossary.id# => 'aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e'putsglossary.entry_count# => 2

Created glossaries can be used in the translate method by specifying the glossary_id option:

translation=DeepL.translate'Hello World','EN','ES',glossary_id: 'aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e'putstranslation.class# => DeepL::Resources::Textputstranslation.text# => 'Hola Tierra'translation=DeepL.translate"I wish we had a car.",'EN','ES',glossary_id: 'aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e'putstranslation.class# => DeepL::Resources::Textputstranslation.text# => Ojalá tuviéramos un auto.

To use more than one glossary at once, specify the glossary_ids option with an array of up to 5 glossary IDs (as strings or DeepL::Resources::Glossary objects) instead of glossary_id. This works for both text and document translation. glossary_ids requires source_lang to be set, cannot be combined with glossary_id, and raises ArgumentError if these rules are violated or more than 5 IDs are provided:

# Text translation with multiple glossariestranslation=DeepL.translate'Hello World','EN','ES',glossary_ids: ['aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e','bb59d8g1-1e13-524f-9b17-e6ccg1db8b7f']# Document translation with multiple glossarieshandle=DeepL.document.upload'my_document.docx','EN','ES','my_document.docx',glossary_ids: ['aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e','bb59d8g1-1e13-524f-9b17-e6ccg1db8b7f']

To list all the glossaries available, use the glossaries.list method:

glossaries=DeepL.glossaries.listputsglossaries.class# => Arrayputsglossaries.first.class# => DeepL::Resources::Glossary

To find an existing glossary, use the glossaries.find method:

glossary=DeepL.glossaries.find'aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e'putsglossary.class# => DeepL::Resources::Glossary

The glossary resource does not include the glossary entries. To list the glossary entries, use the glossaries.entries method:

entries=DeepL.glossaries.entries'aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e'putsentries.class# => Arrayputsentries.size# => 2ppentries.first# => ["Hello World", "Hola Tierra"]

To delete an existing glossary, use the glossaries.destroy method:

glossary_id=DeepL.glossaries.destroy'aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e'putsglossary_id# => aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e

You can list all the language pairs supported by glossaries using the glossaries.language_pairs method:

language_pairs=DeepL.glossaries.language_pairsputslanguage_pairs.class# => Arrayputslanguage_pairs.first.class# => DeepL::Resources::LanguagePairputslanguage_pairs.first.source_lang# => enputslanguage_pairs.first.target_lang# => de

Style Rules

Style rules allow you to customize your translations using a managed, shared list of rules for style, formatting, and more. Multiple style rules can be stored with your account, each with a user-specified name and a uniquely-assigned ID.

Creating a style rule

Use create to create a new style rule with a name and language code. You can optionally provide configured_rules and custom_instructions.

# Simple creation with just a name and languagestyle_rule=DeepL.style_rules.create('My Style Rule','en')puts"Created: #{style_rule.name} (#{style_rule.style_id})"# Creation with configured rules and custom instructionsstyle_rule=DeepL.style_rules.create('Formal English','en',configured_rules: {style_and_tone: {formality: 'formal'}},custom_instructions: [{label: 'Tone',prompt: 'Always use formal language'}])

Retrieving and listing style rules

Use find to retrieve a single style rule by ID, or list to list all style rules.

list returns a list of StyleRule objects corresponding to all of your stored style rules. The method accepts optional parameters: page (page number for pagination, 0-indexed), page_size (number of items per page), and detailed. When true, the response includes configured_rules and custom_instructions for each style rule. When false (default), these fields are omitted for faster responses.

# Get a single style rule by IDstyle_rule=DeepL.style_rules.find('YOUR_STYLE_ID')puts"#{style_rule.name} (#{style_rule.language})"# List all style rulesstyle_rules=DeepL.style_rules.liststyle_rules.eachdo |rule|
puts"#{rule.name} (#{rule.style_id})"end# List with paginationstyle_rules=DeepL.style_rules.list(page: 0,page_size: 10)# List with detailed configurationstyle_rules=DeepL.style_rules.list(detailed: true)style_rules.eachdo |rule|
ifrule.configured_rulesputs" Number formatting: #{rule.configured_rules.numbers.keys.join(', ')}"endend

Updating a style rule

Use update_name to rename a style rule, and update_configured_rules to update its configured rules.

# Update the nameupdated=DeepL.style_rules.update_name('YOUR_STYLE_ID','New Name')# Update configured rulesupdated=DeepL.style_rules.update_configured_rules('YOUR_STYLE_ID',{style_and_tone: {formality: 'formal'}})

The configured_rules hash supports the following categories: dates_and_times, formatting, numbers, punctuation, spelling_and_grammar, style_and_tone, and vocabulary.

Managing custom instructions

Custom instructions allow you to add free-text prompts to a style rule. Each instruction has an id, label, prompt, and source_language. Use create_custom_instruction, find_custom_instruction, update_custom_instruction, and destroy_custom_instruction to manage them.

# Create a custom instructioninstruction=DeepL.style_rules.create_custom_instruction('YOUR_STYLE_ID','Formal tone','Always use formal language')puts"Created instruction: #{instruction.id}"# Create with an optional source languageinstruction=DeepL.style_rules.create_custom_instruction('YOUR_STYLE_ID','Formal tone','Always use formal language','en')# Get a custom instructioninstruction=DeepL.style_rules.find_custom_instruction('YOUR_STYLE_ID',instruction.id)# Update a custom instructionupdated=DeepL.style_rules.update_custom_instruction('YOUR_STYLE_ID',instruction.id,'Updated label','Use very formal language')# Delete a custom instructionDeepL.style_rules.destroy_custom_instruction('YOUR_STYLE_ID',instruction.id)

Deleting a style rule

Use destroy to delete a style rule by ID.

DeepL.style_rules.destroy('YOUR_STYLE_ID')

Using style rules in translations

Style rules can be used in the translate method by specifying the style_rule option with either a style rule ID string or a StyleRule object:

# Using a style rule IDtranslation=DeepL.translate'Hello World','EN','ES',style_rule: 'dca2e053-8ae5-45e6-a0d2-881156e7f4e4'# Or using a StyleRule objectstyle_rules=DeepL.style_rules.listtranslation=DeepL.translate'Hello World','EN','ES',style_rule: style_rules.first

The same style_rule option can be passed to document translation via DeepL.document.upload (or DeepL.document.translate_document), accepting either a style rule ID string or a StyleRule object:

handle=DeepL.document.upload'my_document.docx','EN','ES','my_document.docx',style_rule: 'dca2e053-8ae5-45e6-a0d2-881156e7f4e4'

Translation Memories

Translation memories allow you to store and reuse previously created translations. They can be used in text translation requests to improve consistency by matching against stored segments. Multiple translation memories can be stored with your account, each with a source language and one or more target languages.

Translation memories can also be managed in the DeepL UI via https://www.deepl.com/translation-memory.

Every method that takes a translation memory accepts either a string containing the translation memory ID or a TranslationMemory object.

Listing translation memories

translation_memories.list returns a list of TranslationMemory objects for your stored translation memories. The method accepts optional parameters: page (page number for pagination, 0-indexed) and page_size (number of items per page, max 25).

# List translation memoriestranslation_memories=DeepL.translation_memories.listtranslation_memories.eachdo |tm|
puts"#{tm.name} (#{tm.translation_memory_id})"puts" Source: #{tm.source_language}, Targets: #{tm.target_languages.join(', ')}"puts" Segments: #{tm.segment_count}"end# List with paginationtranslation_memories=DeepL.translation_memories.list(page: 0,page_size: 10)

Retrieving a single translation memory

translation_memories.find retrieves one translation memory by ID. In addition to the fields returned by list, the resource carries the creation_time and updated_time timestamps.

tm=DeepL.translation_memories.find'YOUR_TM_ID'putstm.class# => DeepL::Resources::TranslationMemoryputstm.name# => 'Legal'putstm.segment_count# => 12putstm.creation_time.class# => Time

Listing the segments of a translation memory

translation_memories.segments returns one page of the segments of a translation memory as a TranslationMemorySegments object. Each segment holds the source text and one target per target language of the translation memory.

Pagination is cursor-based: omit page_cursor on the first call, then pass the next_page_cursor of the previous response until next_page? is false. The method also accepts page_size (1-100, defaults to 50), filter_text (a substring matched against the source and target texts, at least 2 characters) and filter_case_sensitive (defaults to false).

Note that segment_count is the number of segments stored in the translation memory; a text filter does not reduce it.

page=DeepL.translation_memories.segments'YOUR_TM_ID',page_size: 50putspage.class# => DeepL::Resources::TranslationMemorySegmentsputspage.segment_count# => 12putspage.segments.first.source_text# => 'Quelltext Nummer 0'putspage.segments.first.targets.first.target_text# => 'Source text number 0'# Walk through every page of segmentswhilepage.next_page?page=DeepL.translation_memories.segments'YOUR_TM_ID',page_size: 50,page_cursor: page.next_page_cursorend# Only the segments matching a textpage=DeepL.translation_memories.segments'YOUR_TM_ID',filter_text: 'Nummer 1',filter_case_sensitive: true

Importing a translation memory

translation_memories.import_from_filepath creates a new translation memory from a TMX file. It creates the import job, uploads the file and waits for the processing to finish, and returns the finished TranslationMemoryJob. Its result carries the ID of the newly created translation memory.

job=DeepL.translation_memories.import_from_filepath'legal.tmx',display_name: 'Legal',timeout_s: 300putsjob.class# => DeepL::Resources::TranslationMemoryJobputsjob.status# => 'completed'putsjob.result.translation_memory_id# => 'a74d88fb-ed2a-4943-a664-a4512398b994'putsjob.result.skipped_segment_count# => 0

The three steps can also be performed separately, for example to upload a file that is not available on the local file system. The upload URL is a pre-signed storage URL outside of the DeepL API, so no authorization header is sent with the upload.

content=File.binread'legal.tmx'created=DeepL.translation_memories.create_import'legal.tmx',content.bytesize,content_type: 'application/xml',display_name: 'Legal'putscreated.upload_url# => 'https://...'DeepL.translation_memories.upload_filecreated,contentjob=DeepL.translation_memories.wait_until_job_donecreated.job_id

Until the file is uploaded the job stays in the awaiting_input status and result.required_action describes what is missing. The API detects the upload asynchronously, so the job keeps reporting awaiting_input for a while afterwards, typically around half a minute, before it completes. wait_until_job_done therefore polls through that status like any other non-terminal one. A job whose file is never uploaded does not finish on its own, so pass timeout_s when that is a possibility.

Exporting a translation memory

translation_memories.export_to_filepath writes a translation memory to a TMX file. It creates the export job, waits for it to finish and downloads the result, overwriting the output file if it already exists.

job=DeepL.translation_memories.export_to_filepath'YOUR_TM_ID','export.tmx'putsjob.status# => 'completed'

The steps can be performed separately as well. Repeating the export of an unchanged translation memory reuses the previously completed job instead of starting a new one, which reused_existing? reports. Just like the upload URL, the download URL is a pre-signed storage URL and is requested without an authorization header.

created=DeepL.translation_memories.create_export'YOUR_TM_ID'putscreated.reused_existing?# => falsejob=DeepL.translation_memories.wait_until_job_donecreated.job_idputsjob.result.download_url# => 'https://...'DeepL.translation_memories.download_exportjob,'export.tmx'

Tracking import and export jobs

translation_memories.find_job returns the current status of an import or export job, and translation_memories.wait_until_job_done polls it every five seconds until it finished, raising if the job failed or expired. Pass timeout_s to give up after a number of seconds instead of waiting forever.

job=DeepL.translation_memories.find_job'YOUR_JOB_ID'putsjob.operation# => 'import'putsjob.status# => 'processing'putsjob.finished?# => false

The status is one of awaiting_input, processing, completed, downloaded, failed or expired.

Deleting a translation memory

translation_memories.destroy deletes a translation memory and returns its ID.

DeepL.translation_memories.destroy'YOUR_TM_ID'# => 'YOUR_TM_ID'

Using a translation memory in translations

Pass the translation_memory parameter to translate to use a translation memory. You can pass either a string containing the translation memory ID, or a TranslationMemory object. Use translation_memory_threshold to control the minimum matching percentage for fuzzy matches (0-100, recommended minimum of 75%).

# Using a translation memory IDtranslation=DeepL.translate'Hello, world!','EN','DE',translation_memory: 'YOUR_TM_ID',translation_memory_threshold: 80# Or using a TranslationMemory objecttranslation_memories=DeepL.translation_memories.listtranslation=DeepL.translate'Hello, world!','EN','DE',translation_memory: translation_memories.first

The same translation_memory and translation_memory_threshold options can be passed to document translation via DeepL.document.upload (or DeepL.document.translate_document). The translation_memory option accepts either a translation memory ID string or a TranslationMemory object:

handle=DeepL.document.upload'my_document.docx','EN','DE','my_document.docx',translation_memory: 'YOUR_TM_ID',translation_memory_threshold: 80

Monitor usage

To check current API usage, use:

usage=DeepL.usageputsusage.character_count# => 180118putsusage.character_limit# => 1250000

Translate documents

To translate a document, use the document.translate_document method. Example:

DeepL.document.translate_document('/path/to/spanish_document.pdf','/path/to/translated_document.pdf','ES','EN')

The lower level upload, get_status and download methods are also exposed, as well as the convenience method wait_until_document_translation_finished on the DocumentHandle object, which would replace get_status:

doc_handle=DeepL.document.upload('/path/to/spanish_document.pdf','ES','EN')doc_status=doc_handle.wait_until_document_translation_finished# alternatively poll `DeepL.document.get_status`# until the `doc_status.successful?`DeepL.document.download(doc_handle,'/path/to/translated_document.pdf')unlessdoc_status.error?

You can also pass additional options to document translation methods, including extra_body_parameters:

options={formality: 'more',extra_body_parameters: {example_param: 'true'}}doc_handle=DeepL.document.upload('/path/to/spanish_document.pdf','ES','EN',nil,options)

The extra_body_parameters option allows you to pass arbitrary parameters in the request body. This can be used to access beta features by adding new parameters, or to override built-in parameters (such as target_lang, source_lang, etc.) for testing purposes.

Sending additional HTTP headers

You can pass additional HTTP headers to translate, rephrase, and the document methods. For example, to send the X-DeepL-Reporting-Tag header for usage reporting (see the cookbook entry):

additional_headers={'X-DeepL-Reporting-Tag'=>'my-tag'}translation=DeepL.translate'Hello, world!','EN','DE',{},additional_headersrephrased=DeepL.rephrase'Hello, world!','EN',nil,nil,{},additional_headers

Handle exceptions

You can capture and process exceptions that may be raised during API calls. These are all the possible exceptions:

Exception classDescription
DeepL::Exceptions::AuthorizationFailedThe authorization process has failed. Check your auth_key value.
DeepL::Exceptions::BadRequestSomething is wrong in your request. Check exception.message for more information.
DeepL::Exceptions::DocumentTranslationErrorAn error occured during document translation. Check exception.message for more information.
DeepL::Exceptions::LimitExceededYou've reached the API's call limit.
DeepL::Exceptions::QuotaExceededYou've reached the API's character limit.
DeepL::Exceptions::RequestErrorAn unkown request error. Check exception.response and exception.request for more information.
DeepL::Exceptions::NotSupportedThe requested method or API endpoint is not supported.
DeepL::Exceptions::RequestEntityTooLargeYour request is too large, reduce the amount of data you are sending. The API has a request size limit of 128 KiB.
DeepL::Exceptions::ServerErrorAn error occured in the DeepL API, wait a short amount of time and retry.

An exampling of handling a generic exception:

defmy_methoditem=DeepL.translate'This is my text',nil,'ES'rescueDeepL::Exceptions::RequestError=>eputs'Oops!'puts"Code: #{e.response.code}"puts"Response body: #{e.response.body}"puts"Request body: #{e.request.body}"end

Logging

To enable logging, pass a suitable logging object (e.g. the default Logger from the Ruby standard library) when configuring the library. The library logs HTTP requests to INFO and debug information to DEBUG. Example:

require'logger'logger=Logger.new(STDOUT)logger.level=Logger::INFOdeepl.configuredo |config|
config.auth_key=configuration.auth_keyconfig.logger=loggerend

Proxy configuration

To use HTTP proxies, a session needs to be used. The proxy can then be configured as part of the HTTP client options:

client_options=HTTPClientOptions.new({'proxy_addr'=>'http://localhost','proxy_port'=>80})deepl.with_session(client_options)do |session|
# ...end

Anonymous platform information

By default, we send some basic information about the platform the client library is running on with each request, see here for an explanation. This data is completely anonymous and only used to improve our product, not track any individual users. If you do not wish to send this data, you can opt-out by setting the send_platform_info flag in the configuration to false like so:

deepl.configure({},nil,nil,false)do |config|
# ...end

You can also complete customize the User-Agent header like so:

deepl.configuredo |config|
config.user_agent='myCustomUserAgent'end

Sending multiple requests

When writing an application that send multiple requests, using a HTTP session will give better performance through HTTP Keep-Alive. You can use it by simply wrapping your requests in a with_session block:

deepl.with_sessiondo |session|
deepl.translate(sentence1,'DE','EN-GB')deepl.translate(sentence2,'DE','EN-GB')deepl.translate(sentence3,'DE','EN-GB')end

Writing a plugin

If you use this library in an application, please identify the application by setting the name and version of the plugin:

deepl.configure({},'MyTranslationPlugin','1.0.1')do |config|
# ...end

This information is passed along when the library makes calls to the DeepL API. Both name and version are required. Please note that setting the User-Agent header via deepl.configure will override this setting, if you need to use this, please manually identify your Application in the User-Agent header.

Options Constants

The available values for various possible options are provided under the DeepL::Constants namespace. The currently available options are

TagHandlingSplitSentencesModelTypeFormalityWritingStyleTone

To view all the possible options for a given constant, call options:

all_available_tones=DeepL::Constants::Tones.options

To check if a given string is a possible option for a given constant, call valid?:

DeepL::Constants::Tones.valid?('friendly')# trueDeepL::Constants::Tones.valid?('rude')# false

Integrations

Ruby on Rails

You may use this gem as a standalone service by creating an initializer on your config/initializers folder with your DeepL configuration. For example:

# config/initializers/deepl.rbDeepL.configuredo |config|
# Your configuration goes hereend

Since the DeepL service is defined globally, you can use service anywhere in your code (controllers, models, views, jobs, plain ruby objects… you name it).

i18n-tasks

You may also take a look at i18n-tasks, which is a gem that helps you find and manage missing and unused translations. deepl-rb is used as one of the backend services to translate content.

Development

Clone the repository, and install its dependencies:

git clone https://github.com/DeepLcom/deepl-rb
cd deepl-rb
bundle install

To run tests (rspec and rubocop), use

bundle exec rake test

Acknowledgements

This library was originally developed by Daniel Herzog, we are grateful for his contributions. Beginning with v3.0.0, DeepL took over development and officially supports and maintains the library together with Daniel.

About

Official Ruby library for the DeepL language translation API.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

19 stars

Watchers

1 watching

Forks

Releases

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

Gem Version

DeepL Ruby Library

The DeepL API is a language translation API that allows other computer programs to send texts and documents to DeepL's servers and receive high-quality translations. This opens a whole universe of opportunities for developers: any translation product you can imagine can now be built on top of DeepL's best-in-class translation technology.

The DeepL Ruby library offers a convenient way for applications written in Ruby to interact with the DeepL API. We intend to support all API functions with the library, though support for new features may be added to the library after they’re added to the API.

Getting an authentication key

To use the DeepL Ruby Library, you'll need an API authentication key. To get a key, please create an account here. With a DeepL API Free account you can translate up to 500,000 characters/month for free.

Installation

Install this gem with

gem install deepl-rb
# Load it in your ruby file using `require 'deepl'`

Or add it to your Gemfile:

gem'deepl-rb',require: 'deepl'

Usage

Setup an environment variable named DEEPL_AUTH_KEY with your authentication key:

export DEEPL_AUTH_KEY="your-api-token"

Alternatively, you can configure the API client within a ruby block:

DeepL.configuredo |config|
config.auth_key='your-api-token'end

You can also configure the API host and the API version:

DeepL.configuredo |config|
config.auth_key='your-api-token'config.host='https://api-free.deepl.com'# Default value is 'https://api.deepl.com'config.version='v1'# Default value is 'v2'end

Available languages

Available languages can be retrieved via API:

languages=DeepL.languagesputslanguages.class# => Arrayputslanguages.first.class# => DeepL::Resources::Languageputs"#{languages.first.code} -> #{languages.first.name}"# => "ES -> Spanish"

Note that source and target languages may be different, which can be retrieved by using the type option:

putsDeepL.languages(type: :source).count# => 24putsDeepL.languages(type: :target).count# => 26

All languages are also defined on the official API documentation.

Note that target languages may include the supports_formality flag, which may be checked using the DeepL::Resources::Language#supports_formality?.

Translate

To translate a simple text, use the translate method:

translation=DeepL.translate'This is my text','EN','ES'putstranslation.class# => DeepL::Resources::Textputstranslation.text# => 'Este es mi texto'

Enable auto-detect source language by skipping the source language with nil:

translation=DeepL.translate'This is my text',nil,'ES'putstranslation.detected_source_language# => 'EN'

Translate a list of texts by passing an array as an argument:

texts=['Sample text','Another text']translations=DeepL.translatetexts,'EN','ES'putstranslations.class# => Arrayputstranslations.first.class# => DeepL::Resources::Text

You can also use custom query parameters, like tag_handling, split_sentences, non_splitting_tags or ignore_tags:

translation=DeepL.translate'<p>A sample</p>','EN','ES',tag_handling: 'xml',split_sentences: false,non_splitting_tags: 'h1',ignore_tags: %w[codepre]putstranslation.text# => "<p>Una muestra</p>"

To specify which version of the tag handling algorithm to use, you can use the tag_handling_version parameter:

translation=DeepL.translate'<p>A sample</p>','EN','ES',tag_handling: 'xml',tag_handling_version: 'v2'putstranslation.text# => "<p>Una muestra</p>"

The available values are 'v1' and 'v2'.

To translate with context, simply supply the context parameter:

translation=DeepL.translate'That is hot!','EN','ES',context: 'He did not like the jalapenos in his meal.'putstranslation.text# => "¡Eso es picante!"

To specify a type of translation model to use, you can use the model_type option:

translation=DeepL.translate'That is hot!','EN','DE',model_type: 'quality_optimized'

This would use next-gen translation models for the translation. The available values are

  • 'quality_optimized': use a translation model that maximizes translation quality, at the cost of response time. This option may be unavailable for some language pairs.
  • 'prefer_quality_optimized': use the highest-quality translation model for the given language pair.
  • 'latency_optimized': use a translation model that minimizes response time, at the cost of translation quality.

To translate with custom instructions, supply the custom_instructions parameter:

translation=DeepL.translate'Hello, world!','EN','DE',custom_instructions: ['Use informal language','Be concise']putstranslation.text

Up to 10 custom instructions can be specified, each with a maximum of 300 characters. The target language must be de, en, es, fr, it, ja, ko, zh or any variants. Note that using custom_instructions will automatically use quality_optimized models, and cannot be combined with model_type: 'latency_optimized'.

The following parameters will be automatically converted:

ParameterConversion
preserve_formattingConverts false to '0' and true to '1'
split_sentencesConverts false to '0' and true to '1'
outline_detectionConverts false to '0' and true to '1'
splitting_tagsConverts arrays to strings joining by commas
non_splitting_tagsConverts arrays to strings joining by commas
ignore_tagsConverts arrays to strings joining by commas
formalityNo conversion applied
glossary_idNo conversion applied
style_ruleNo conversion applied (can be a string ID or a StyleRule object)
translation_memoryNo conversion applied (can be a string ID or a TranslationMemory object)
translation_memory_thresholdNo conversion applied (integer 0-100, recommended minimum 75)
contextNo conversion applied
custom_instructionsNo conversion applied
tag_handling_versionNo conversion applied
extra_body_parametersHash of extra parameters to pass in the body of the HTTP request. Can be used to access beta features, or to override built-in parameters for testing purposes. Extra parameters can override keys explicitly set by the client.

Rephrase Text

To rephrase or improve text, including changing the writing style or tone of the text, use the rephrase method:

rephrased_text=DeepL.rephrase'you will acquire new rephrased text','EN'putsrephrased_text.class# => DeepL::Resources::Textputsrephrased_text.text# => 'You get new rephrased text.'

As with translate, the text input can be a single string or an array of strings.

You can use the additional arguments to specify the writing style or tone you want for the rephrased text:

rephrased_text=DeepL.rephrase'you will acquire new rephrased text','EN','casual'putsrephrased_text.text# => 'You'll get new, rephrased text.'
rephrased_text=DeepL.rephrase'you will acquire new rephrased text','EN',nil,'friendly'putsrephrased_text.text# => 'You'll get to enjoy new, rephrased text!'

Glossaries

To create a glossary, use the glossaries.create method. The glossary entries argument should be an array of text pairs. Each pair includes the source and the target translations.

entries=[['Hello World','Hola Tierra'],['car','auto']]glossary=DeepL.glossaries.create'Mi Glosario','EN','ES',entriesputsglossary.class# => DeepL::Resources::Glossaryputsglossary.id# => 'aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e'putsglossary.entry_count# => 2

Created glossaries can be used in the translate method by specifying the glossary_id option:

translation=DeepL.translate'Hello World','EN','ES',glossary_id: 'aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e'putstranslation.class# => DeepL::Resources::Textputstranslation.text# => 'Hola Tierra'translation=DeepL.translate"I wish we had a car.",'EN','ES',glossary_id: 'aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e'putstranslation.class# => DeepL::Resources::Textputstranslation.text# => Ojalá tuviéramos un auto.

To use more than one glossary at once, specify the glossary_ids option with an array of up to 5 glossary IDs (as strings or DeepL::Resources::Glossary objects) instead of glossary_id. This works for both text and document translation. glossary_ids requires source_lang to be set, cannot be combined with glossary_id, and raises ArgumentError if these rules are violated or more than 5 IDs are provided:

# Text translation with multiple glossariestranslation=DeepL.translate'Hello World','EN','ES',glossary_ids: ['aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e','bb59d8g1-1e13-524f-9b17-e6ccg1db8b7f']# Document translation with multiple glossarieshandle=DeepL.document.upload'my_document.docx','EN','ES','my_document.docx',glossary_ids: ['aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e','bb59d8g1-1e13-524f-9b17-e6ccg1db8b7f']

To list all the glossaries available, use the glossaries.list method:

glossaries=DeepL.glossaries.listputsglossaries.class# => Arrayputsglossaries.first.class# => DeepL::Resources::Glossary

To find an existing glossary, use the glossaries.find method:

glossary=DeepL.glossaries.find'aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e'putsglossary.class# => DeepL::Resources::Glossary

The glossary resource does not include the glossary entries. To list the glossary entries, use the glossaries.entries method:

entries=DeepL.glossaries.entries'aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e'putsentries.class# => Arrayputsentries.size# => 2ppentries.first# => ["Hello World", "Hola Tierra"]

To delete an existing glossary, use the glossaries.destroy method:

glossary_id=DeepL.glossaries.destroy'aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e'putsglossary_id# => aa48c7f0-0d02-413e-8a06-d5bbf0ca7a6e

You can list all the language pairs supported by glossaries using the glossaries.language_pairs method:

language_pairs=DeepL.glossaries.language_pairsputslanguage_pairs.class# => Arrayputslanguage_pairs.first.class# => DeepL::Resources::LanguagePairputslanguage_pairs.first.source_lang# => enputslanguage_pairs.first.target_lang# => de

Style Rules

Style rules allow you to customize your translations using a managed, shared list of rules for style, formatting, and more. Multiple style rules can be stored with your account, each with a user-specified name and a uniquely-assigned ID.

Creating a style rule

Use create to create a new style rule with a name and language code. You can optionally provide configured_rules and custom_instructions.

# Simple creation with just a name and languagestyle_rule=DeepL.style_rules.create('My Style Rule','en')puts"Created: #{style_rule.name} (#{style_rule.style_id})"# Creation with configured rules and custom instructionsstyle_rule=DeepL.style_rules.create('Formal English','en',configured_rules: {style_and_tone: {formality: 'formal'}},custom_instructions: [{label: 'Tone',prompt: 'Always use formal language'}])

Retrieving and listing style rules

Use find to retrieve a single style rule by ID, or list to list all style rules.

list returns a list of StyleRule objects corresponding to all of your stored style rules. The method accepts optional parameters: page (page number for pagination, 0-indexed), page_size (number of items per page), and detailed. When true, the response includes configured_rules and custom_instructions for each style rule. When false (default), these fields are omitted for faster responses.

# Get a single style rule by IDstyle_rule=DeepL.style_rules.find('YOUR_STYLE_ID')puts"#{style_rule.name} (#{style_rule.language})"# List all style rulesstyle_rules=DeepL.style_rules.liststyle_rules.eachdo |rule|
puts"#{rule.name} (#{rule.style_id})"end# List with paginationstyle_rules=DeepL.style_rules.list(page: 0,page_size: 10)# List with detailed configurationstyle_rules=DeepL.style_rules.list(detailed: true)style_rules.eachdo |rule|
ifrule.configured_rulesputs" Number formatting: #{rule.configured_rules.numbers.keys.join(', ')}"endend

Updating a style rule

Use update_name to rename a style rule, and update_configured_rules to update its configured rules.

# Update the nameupdated=DeepL.style_rules.update_name('YOUR_STYLE_ID','New Name')# Update configured rulesupdated=DeepL.style_rules.update_configured_rules('YOUR_STYLE_ID',{style_and_tone: {formality: 'formal'}})

The configured_rules hash supports the following categories: dates_and_times, formatting, numbers, punctuation, spelling_and_grammar, style_and_tone, and vocabulary.

Managing custom instructions

Custom instructions allow you to add free-text prompts to a style rule. Each instruction has an id, label, prompt, and source_language. Use create_custom_instruction, find_custom_instruction, update_custom_instruction, and destroy_custom_instruction to manage them.

# Create a custom instructioninstruction=DeepL.style_rules.create_custom_instruction('YOUR_STYLE_ID','Formal tone','Always use formal language')puts"Created instruction: #{instruction.id}"# Create with an optional source languageinstruction=DeepL.style_rules.create_custom_instruction('YOUR_STYLE_ID','Formal tone','Always use formal language','en')# Get a custom instructioninstruction=DeepL.style_rules.find_custom_instruction('YOUR_STYLE_ID',instruction.id)# Update a custom instructionupdated=DeepL.style_rules.update_custom_instruction('YOUR_STYLE_ID',instruction.id,'Updated label','Use very formal language')# Delete a custom instructionDeepL.style_rules.destroy_custom_instruction('YOUR_STYLE_ID',instruction.id)

Deleting a style rule

Use destroy to delete a style rule by ID.

DeepL.style_rules.destroy('YOUR_STYLE_ID')

Using style rules in translations

Style rules can be used in the translate method by specifying the style_rule option with either a style rule ID string or a StyleRule object:

# Using a style rule IDtranslation=DeepL.translate'Hello World','EN','ES',style_rule: 'dca2e053-8ae5-45e6-a0d2-881156e7f4e4'# Or using a StyleRule objectstyle_rules=DeepL.style_rules.listtranslation=DeepL.translate'Hello World','EN','ES',style_rule: style_rules.first

The same style_rule option can be passed to document translation via DeepL.document.upload (or DeepL.document.translate_document), accepting either a style rule ID string or a StyleRule object:

handle=DeepL.document.upload'my_document.docx','EN','ES','my_document.docx',style_rule: 'dca2e053-8ae5-45e6-a0d2-881156e7f4e4'

Translation Memories

Translation memories allow you to store and reuse previously created translations. They can be used in text translation requests to improve consistency by matching against stored segments. Multiple translation memories can be stored with your account, each with a source language and one or more target languages.

Translation memories can also be managed in the DeepL UI via https://www.deepl.com/translation-memory.

Every method that takes a translation memory accepts either a string containing the translation memory ID or a TranslationMemory object.

Listing translation memories

translation_memories.list returns a list of TranslationMemory objects for your stored translation memories. The method accepts optional parameters: page (page number for pagination, 0-indexed) and page_size (number of items per page, max 25).

# List translation memoriestranslation_memories=DeepL.translation_memories.listtranslation_memories.eachdo |tm|
puts"#{tm.name} (#{tm.translation_memory_id})"puts" Source: #{tm.source_language}, Targets: #{tm.target_languages.join(', ')}"puts" Segments: #{tm.segment_count}"end# List with paginationtranslation_memories=DeepL.translation_memories.list(page: 0,page_size: 10)

Retrieving a single translation memory

translation_memories.find retrieves one translation memory by ID. In addition to the fields returned by list, the resource carries the creation_time and updated_time timestamps.

tm=DeepL.translation_memories.find'YOUR_TM_ID'putstm.class# => DeepL::Resources::TranslationMemoryputstm.name# => 'Legal'putstm.segment_count# => 12putstm.creation_time.class# => Time

Listing the segments of a translation memory

translation_memories.segments returns one page of the segments of a translation memory as a TranslationMemorySegments object. Each segment holds the source text and one target per target language of the translation memory.

Pagination is cursor-based: omit page_cursor on the first call, then pass the next_page_cursor of the previous response until next_page? is false. The method also accepts page_size (1-100, defaults to 50), filter_text (a substring matched against the source and target texts, at least 2 characters) and filter_case_sensitive (defaults to false).

Note that segment_count is the number of segments stored in the translation memory; a text filter does not reduce it.

page=DeepL.translation_memories.segments'YOUR_TM_ID',page_size: 50putspage.class# => DeepL::Resources::TranslationMemorySegmentsputspage.segment_count# => 12putspage.segments.first.source_text# => 'Quelltext Nummer 0'putspage.segments.first.targets.first.target_text# => 'Source text number 0'# Walk through every page of segmentswhilepage.next_page?page=DeepL.translation_memories.segments'YOUR_TM_ID',page_size: 50,page_cursor: page.next_page_cursorend# Only the segments matching a textpage=DeepL.translation_memories.segments'YOUR_TM_ID',filter_text: 'Nummer 1',filter_case_sensitive: true

Importing a translation memory

translation_memories.import_from_filepath creates a new translation memory from a TMX file. It creates the import job, uploads the file and waits for the processing to finish, and returns the finished TranslationMemoryJob. Its result carries the ID of the newly created translation memory.

job=DeepL.translation_memories.import_from_filepath'legal.tmx',display_name: 'Legal',timeout_s: 300putsjob.class# => DeepL::Resources::TranslationMemoryJobputsjob.status# => 'completed'putsjob.result.translation_memory_id# => 'a74d88fb-ed2a-4943-a664-a4512398b994'putsjob.result.skipped_segment_count# => 0

The three steps can also be performed separately, for example to upload a file that is not available on the local file system. The upload URL is a pre-signed storage URL outside of the DeepL API, so no authorization header is sent with the upload.

content=File.binread'legal.tmx'created=DeepL.translation_memories.create_import'legal.tmx',content.bytesize,content_type: 'application/xml',display_name: 'Legal'putscreated.upload_url# => 'https://...'DeepL.translation_memories.upload_filecreated,contentjob=DeepL.translation_memories.wait_until_job_donecreated.job_id

Until the file is uploaded the job stays in the awaiting_input status and result.required_action describes what is missing. The API detects the upload asynchronously, so the job keeps reporting awaiting_input for a while afterwards, typically around half a minute, before it completes. wait_until_job_done therefore polls through that status like any other non-terminal one. A job whose file is never uploaded does not finish on its own, so pass timeout_s when that is a possibility.

Exporting a translation memory

translation_memories.export_to_filepath writes a translation memory to a TMX file. It creates the export job, waits for it to finish and downloads the result, overwriting the output file if it already exists.

job=DeepL.translation_memories.export_to_filepath'YOUR_TM_ID','export.tmx'putsjob.status# => 'completed'

The steps can be performed separately as well. Repeating the export of an unchanged translation memory reuses the previously completed job instead of starting a new one, which reused_existing? reports. Just like the upload URL, the download URL is a pre-signed storage URL and is requested without an authorization header.

created=DeepL.translation_memories.create_export'YOUR_TM_ID'putscreated.reused_existing?# => falsejob=DeepL.translation_memories.wait_until_job_donecreated.job_idputsjob.result.download_url# => 'https://...'DeepL.translation_memories.download_exportjob,'export.tmx'

Tracking import and export jobs

translation_memories.find_job returns the current status of an import or export job, and translation_memories.wait_until_job_done polls it every five seconds until it finished, raising if the job failed or expired. Pass timeout_s to give up after a number of seconds instead of waiting forever.

job=DeepL.translation_memories.find_job'YOUR_JOB_ID'putsjob.operation# => 'import'putsjob.status# => 'processing'putsjob.finished?# => false

The status is one of awaiting_input, processing, completed, downloaded, failed or expired.

Deleting a translation memory

translation_memories.destroy deletes a translation memory and returns its ID.

DeepL.translation_memories.destroy'YOUR_TM_ID'# => 'YOUR_TM_ID'

Using a translation memory in translations

Pass the translation_memory parameter to translate to use a translation memory. You can pass either a string containing the translation memory ID, or a TranslationMemory object. Use translation_memory_threshold to control the minimum matching percentage for fuzzy matches (0-100, recommended minimum of 75%).

# Using a translation memory IDtranslation=DeepL.translate'Hello, world!','EN','DE',translation_memory: 'YOUR_TM_ID',translation_memory_threshold: 80# Or using a TranslationMemory objecttranslation_memories=DeepL.translation_memories.listtranslation=DeepL.translate'Hello, world!','EN','DE',translation_memory: translation_memories.first

The same translation_memory and translation_memory_threshold options can be passed to document translation via DeepL.document.upload (or DeepL.document.translate_document). The translation_memory option accepts either a translation memory ID string or a TranslationMemory object:

handle=DeepL.document.upload'my_document.docx','EN','DE','my_document.docx',translation_memory: 'YOUR_TM_ID',translation_memory_threshold: 80

Monitor usage

To check current API usage, use:

usage=DeepL.usageputsusage.character_count# => 180118putsusage.character_limit# => 1250000

Translate documents

To translate a document, use the document.translate_document method. Example:

DeepL.document.translate_document('/path/to/spanish_document.pdf','/path/to/translated_document.pdf','ES','EN')

The lower level upload, get_status and download methods are also exposed, as well as the convenience method wait_until_document_translation_finished on the DocumentHandle object, which would replace get_status:

doc_handle=DeepL.document.upload('/path/to/spanish_document.pdf','ES','EN')doc_status=doc_handle.wait_until_document_translation_finished# alternatively poll `DeepL.document.get_status`# until the `doc_status.successful?`DeepL.document.download(doc_handle,'/path/to/translated_document.pdf')unlessdoc_status.error?

You can also pass additional options to document translation methods, including extra_body_parameters:

options={formality: 'more',extra_body_parameters: {example_param: 'true'}}doc_handle=DeepL.document.upload('/path/to/spanish_document.pdf','ES','EN',nil,options)

The extra_body_parameters option allows you to pass arbitrary parameters in the request body. This can be used to access beta features by adding new parameters, or to override built-in parameters (such as target_lang, source_lang, etc.) for testing purposes.

Sending additional HTTP headers

You can pass additional HTTP headers to translate, rephrase, and the document methods. For example, to send the X-DeepL-Reporting-Tag header for usage reporting (see the cookbook entry):

additional_headers={'X-DeepL-Reporting-Tag'=>'my-tag'}translation=DeepL.translate'Hello, world!','EN','DE',{},additional_headersrephrased=DeepL.rephrase'Hello, world!','EN',nil,nil,{},additional_headers

Handle exceptions

You can capture and process exceptions that may be raised during API calls. These are all the possible exceptions:

Exception classDescription
DeepL::Exceptions::AuthorizationFailedThe authorization process has failed. Check your auth_key value.
DeepL::Exceptions::BadRequestSomething is wrong in your request. Check exception.message for more information.
DeepL::Exceptions::DocumentTranslationErrorAn error occured during document translation. Check exception.message for more information.
DeepL::Exceptions::LimitExceededYou've reached the API's call limit.
DeepL::Exceptions::QuotaExceededYou've reached the API's character limit.
DeepL::Exceptions::RequestErrorAn unkown request error. Check exception.response and exception.request for more information.
DeepL::Exceptions::NotSupportedThe requested method or API endpoint is not supported.
DeepL::Exceptions::RequestEntityTooLargeYour request is too large, reduce the amount of data you are sending. The API has a request size limit of 128 KiB.
DeepL::Exceptions::ServerErrorAn error occured in the DeepL API, wait a short amount of time and retry.

An exampling of handling a generic exception:

defmy_methoditem=DeepL.translate'This is my text',nil,'ES'rescueDeepL::Exceptions::RequestError=>eputs'Oops!'puts"Code: #{e.response.code}"puts"Response body: #{e.response.body}"puts"Request body: #{e.request.body}"end

Logging

To enable logging, pass a suitable logging object (e.g. the default Logger from the Ruby standard library) when configuring the library. The library logs HTTP requests to INFO and debug information to DEBUG. Example:

require'logger'logger=Logger.new(STDOUT)logger.level=Logger::INFOdeepl.configuredo |config|
config.auth_key=configuration.auth_keyconfig.logger=loggerend

Proxy configuration

To use HTTP proxies, a session needs to be used. The proxy can then be configured as part of the HTTP client options:

client_options=HTTPClientOptions.new({'proxy_addr'=>'http://localhost','proxy_port'=>80})deepl.with_session(client_options)do |session|
# ...end

Anonymous platform information

By default, we send some basic information about the platform the client library is running on with each request, see here for an explanation. This data is completely anonymous and only used to improve our product, not track any individual users. If you do not wish to send this data, you can opt-out by setting the send_platform_info flag in the configuration to false like so:

deepl.configure({},nil,nil,false)do |config|
# ...end

You can also complete customize the User-Agent header like so:

deepl.configuredo |config|
config.user_agent='myCustomUserAgent'end

Sending multiple requests

When writing an application that send multiple requests, using a HTTP session will give better performance through HTTP Keep-Alive. You can use it by simply wrapping your requests in a with_session block:

deepl.with_sessiondo |session|
deepl.translate(sentence1,'DE','EN-GB')deepl.translate(sentence2,'DE','EN-GB')deepl.translate(sentence3,'DE','EN-GB')end

Writing a plugin

If you use this library in an application, please identify the application by setting the name and version of the plugin:

deepl.configure({},'MyTranslationPlugin','1.0.1')do |config|
# ...end

This information is passed along when the library makes calls to the DeepL API. Both name and version are required. Please note that setting the User-Agent header via deepl.configure will override this setting, if you need to use this, please manually identify your Application in the User-Agent header.

Options Constants

The available values for various possible options are provided under the DeepL::Constants namespace. The currently available options are

TagHandlingSplitSentencesModelTypeFormalityWritingStyleTone

To view all the possible options for a given constant, call options:

all_available_tones=DeepL::Constants::Tones.options

To check if a given string is a possible option for a given constant, call valid?:

DeepL::Constants::Tones.valid?('friendly')# trueDeepL::Constants::Tones.valid?('rude')# false

Integrations

Ruby on Rails

You may use this gem as a standalone service by creating an initializer on your config/initializers folder with your DeepL configuration. For example:

# config/initializers/deepl.rbDeepL.configuredo |config|
# Your configuration goes hereend

Since the DeepL service is defined globally, you can use service anywhere in your code (controllers, models, views, jobs, plain ruby objects… you name it).

i18n-tasks

You may also take a look at i18n-tasks, which is a gem that helps you find and manage missing and unused translations. deepl-rb is used as one of the backend services to translate content.

Development

Clone the repository, and install its dependencies:

git clone https://github.com/DeepLcom/deepl-rb
cd deepl-rb
bundle install

To run tests (rspec and rubocop), use

bundle exec rake test

Acknowledgements

This library was originally developed by Daniel Herzog, we are grateful for his contributions. Beginning with v3.0.0, DeepL took over development and officially supports and maintains the library together with Daniel.

About

Official Ruby library for the DeepL language translation API.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

19 stars

Watchers

1 watching

Forks

Releases

Used by

Contributors

Languages