deepl-rb 3.1.0 → 3.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/.gitlab-ci.yml +38 -1
  3. data/CHANGELOG.md +38 -24
  4. data/README.md +68 -0
  5. data/Rakefile +1 -0
  6. data/VERSION +1 -1
  7. data/deepl-rb.gemspec +15 -3
  8. data/lib/deepl/constants/base_constant.rb +18 -0
  9. data/lib/deepl/constants/formality.rb +16 -0
  10. data/lib/deepl/constants/model_type.rb +14 -0
  11. data/lib/deepl/constants/split_sentences.rb +14 -0
  12. data/lib/deepl/constants/tag_handling.rb +13 -0
  13. data/lib/deepl/constants/tone.rb +20 -0
  14. data/lib/deepl/constants/writing_style.rb +20 -0
  15. data/lib/deepl/exceptions/authorization_failed.rb +1 -1
  16. data/lib/deepl/exceptions/bad_request.rb +1 -1
  17. data/lib/deepl/exceptions/limit_exceeded.rb +1 -1
  18. data/lib/deepl/exceptions/not_found.rb +1 -1
  19. data/lib/deepl/exceptions/quota_exceeded.rb +1 -1
  20. data/lib/deepl/exceptions/request_entity_too_large.rb +1 -1
  21. data/lib/deepl/exceptions/request_error.rb +1 -1
  22. data/lib/deepl/exceptions/server_error.rb +1 -1
  23. data/lib/deepl/requests/base.rb +38 -5
  24. data/lib/deepl/requests/document/upload.rb +21 -11
  25. data/lib/deepl/requests/rephrase.rb +55 -0
  26. data/lib/deepl.rb +15 -0
  27. data/spec/api/deepl_spec.rb +29 -0
  28. data/spec/constants/constants_spec.rb +158 -0
  29. data/spec/fixtures/vcr_cassettes/deepl_rephrase.yml +87 -0
  30. data/spec/fixtures/vcr_cassettes/rephrase_texts.yml +401 -0
  31. data/spec/fixtures/vcr_cassettes/translate_texts.yml +44 -1
  32. data/spec/integration_tests/document_api_spec.rb +22 -0
  33. data/spec/requests/rephrase_spec.rb +172 -0
  34. data/spec/requests/translate_spec.rb +35 -0
  35. data/spec/spec_helper.rb +6 -2
  36. metadata +14 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1de43b1593c5b5d4236c0b064c08436ab57fe13bf3fdc29069220fd899ca8e1d
4
- data.tar.gz: a486d446fa3bebddbf3fd6aa468300bead03eafe8bc075c33a28d80be6e555b8
3
+ metadata.gz: ce04c17b4585b9813713f61db8fe35e3a61b777c48ec22011f81b7febe106527
4
+ data.tar.gz: 3c4432516a14b2fb0e8886f2ff3e6d31c5ba5c88590d4e28a9631fc0a233f724
5
5
  SHA512:
6
- metadata.gz: ca167089f7a190915436fb316a8a82aa69bf8093316b4074c6536bb21e002811d9bdd57fc8711eeb634025b094a9fe17e2b057eee5ea5d2499539060e09b8ebd
7
- data.tar.gz: 1c63cd745170652f01a2335cc064ceb0266c1584a19bd1fcd6683c6d461241b646d33df0b3e36f516e1dff6a1d6158e706994b862b6bd8d671b1db399cabfa03
6
+ metadata.gz: 8a736f2b2cc257c26cd47e67bdbdcbc89afbb6de444176f0dab5b0a470fe2c713e3c32396391a05c007ddfbfbbc80953b0f6c6afb1fdf9b138c0eca97ae02a52
7
+ data.tar.gz: 1828bdede7c38bec246302645e39ec7f01950096f3c52fb1b119766bbdf11b6c2b6d3ab881ebdf2875f736ab8f47778e87abcb5f107ca2ef6f4848c66d11d680
data/.gitlab-ci.yml CHANGED
@@ -1,5 +1,6 @@
1
1
  # Note: This GitLab CI configuration is used for internal testing, users can ignore it.
2
2
  include:
3
+ - template: Security/SAST.gitlab-ci.yml
3
4
  - project: '${CI_PROJECT_NAMESPACE}/ci-libs-for-client-libraries'
4
5
  file:
5
6
  - '/${CI_PROJECT_NAME}/.gitlab-ci.yml'
@@ -7,6 +8,7 @@ include:
7
8
  file:
8
9
  - '/templates/.buildkit.yml'
9
10
  - '/templates/.secret-detection.yml'
11
+ - '/templates/.gitlab-release.yml'
10
12
 
11
13
  # Global --------------------------
12
14
 
@@ -16,11 +18,14 @@ workflow:
16
18
  - if: $CI_COMMIT_TAG
17
19
  - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
18
20
 
21
+ variables:
22
+ GITLAB_ADVANCED_SAST_ENABLED: 'true'
23
+
19
24
  stages:
20
25
  - install
21
26
  - check
22
27
  - test
23
- # - publish
28
+ - publish # Only for internal tracking
24
29
 
25
30
 
26
31
  before_script:
@@ -82,6 +87,29 @@ license_check:
82
87
  - ./license_checker.sh '*.rb' | tee license_check_output.txt
83
88
  - '[ ! -s license_check_output.txt ]'
84
89
 
90
+ gitlab-advanced-sast:
91
+ stage: check
92
+ before_script:
93
+ - ''
94
+ rules:
95
+ - when: always
96
+ variables:
97
+ SAST_EXCLUDED_PATHS: '$DEFAULT_SAST_EXCLUDED_PATHS,/spec'
98
+ GIT_STRATEGY: clone
99
+ KUBERNETES_HELPER_MEMORY_LIMIT: 8Gi
100
+ SAST_SCANNER_ALLOWED_CLI_OPTS: --multi-core 8
101
+
102
+ semgrep-sast:
103
+ stage: check
104
+ before_script:
105
+ - ''
106
+ rules:
107
+ - when: always
108
+ variables:
109
+ SAST_EXCLUDED_PATHS: '$DEFAULT_SAST_EXCLUDED_PATHS,/spec'
110
+ GIT_STRATEGY: clone
111
+ KUBERNETES_MEMORY_LIMIT: 8Gi
112
+
85
113
 
86
114
  # stage: test ----------------------
87
115
 
@@ -133,3 +161,12 @@ test_manual:
133
161
  extends: .test_base
134
162
  rules:
135
163
  - if: $CI_PIPELINE_SOURCE != "schedule"
164
+
165
+
166
+ # stage: publish ----------------------
167
+
168
+ gitlab release:
169
+ stage: publish
170
+ extends: .create_gitlab_release
171
+ rules:
172
+ - if: '$CI_COMMIT_TAG =~ /^v[0-9]+\.[0-9]+\.[0-9]+$/'
data/CHANGELOG.md CHANGED
@@ -4,55 +4,69 @@ All notable changes to this project will be documented in this file.
4
4
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5
5
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [Unreleased]
7
8
 
8
- ## [3.1.0]
9
+ ## [3.3.0] - 2025-11-04
9
10
  ### Added
10
- * Added `model_type` option to `translate()` to use models with higher
11
+ - Added `extra_body_parameters` option to text and document translation methods to pass arbitrary parameters in the request body. This can be used to access beta features or override built-in parameters (such as `target_lang`, `source_lang`, etc.).
12
+ - Added `rephrase` functionality to the top-level `DeepL` module for convenience.
13
+ * Thanks to [341bms](https://github.com/341bms) in [#14](https://github.com/DeepLcom/deepl-rb/issues/14) for the report!
14
+
15
+ ## [3.2.0] - 2025-01-15
16
+ ### Added
17
+ - Added `rephrase` functionality to get a new version of submitted text with various possible styles or tones applied
18
+ - Added `DeepL::Constants` namespace and associated constant values for options possibilities
19
+
20
+ ## [3.1.0] - 2024-11-15
21
+ ### Added
22
+ - Added `model_type` option to `translate()` to use models with higher
11
23
  translation quality (available for some language pairs), or better latency.
12
24
  Options are `'quality_optimized'`, `'latency_optimized'`, and `'prefer_quality_optimized'`
13
- * Added the `model_type_used` field to the `translate()` response, that
25
+ - Added the `model_type_used` field to the `translate()` response, that
14
26
  indicates the translation model used when the `model_type` option is
15
27
  specified.
16
28
 
17
-
18
29
  ## [3.0.2] - 2024-10-02
19
30
  ### Added
20
- * Added doc example and tests for context parameter
31
+ - Added doc example and tests for context parameter
32
+
21
33
  ### Fixed
22
- * Fix metadata displayed on RubyGems.org for this library.
23
- * Fixed library version sent in the `User-Agent` string.
34
+ - Fix metadata displayed on RubyGems.org for this library.
35
+ - Fixed library version sent in the `User-Agent` string.
24
36
 
25
37
  ## [3.0.1] - 2024-09-23
26
38
  ### Fixed
27
- * `document.translate_document` required a filename, this is now optional. The example in the README now works.
39
+ - `document.translate_document` required a filename, this is now optional. The example in the README now works.
28
40
 
29
41
  ## [3.0.0] - 2024-09-20
30
42
  Beginning with version 3, deepl-rb is officially supported by DeepL, and maintained together with [Daniel Herzog](mailto:info@danielherzog.es) the developer of earlier versions of this library.
31
43
  The change in major version is only due to the change in maintainership, there is no migration necessary from v2 to v3.
44
+
32
45
  ### Added
33
- * Added rubocop-rspec linting for rspec test files
34
- * Added document translation to the ruby CL
35
- * Added possibility to use one HTTP session for multiple calls
36
- * Added platform and ruby version information to the user-agent string that is sent with API calls, along with an opt-out
37
- * Added support for logging of HTTP requests
38
- * Added support for using a proxy and a custom certificate file
39
- * Added a gitlab CI pipeline
46
+ - Added rubocop-rspec linting for rspec test files
47
+ - Added document translation to the ruby CL
48
+ - Added possibility to use one HTTP session for multiple calls
49
+ - Added platform and ruby version information to the user-agent string that is sent with API calls, along with an opt-out
50
+ - Added support for logging of HTTP requests
51
+ - Added support for using a proxy and a custom certificate file
52
+ - Added a gitlab CI pipeline
53
+
40
54
  ### Changed
41
- * HTTP requests to the DeepL API now use `application/json`, rather than `application/www-form-unencoded`
42
- * HTTP requests now automatically retry on transient failures, using exponential backoff
43
- ### Deprecated
55
+ - HTTP requests to the DeepL API now use `application/json`, rather than `application/www-form-unencoded`
56
+ - HTTP requests now automatically retry on transient failures, using exponential backoff
57
+
44
58
  ### Removed
45
- * Removed CircleCI and CodeCov upload
46
- ### Fixed
47
- ### Security
59
+ - Removed CircleCI and CodeCov upload
48
60
 
49
61
  ## [2.5.3] - 2022-09-26
50
62
  ### Fixed
51
- * Make RequestEntityTooLarge error message more clear
52
-
63
+ - Make RequestEntityTooLarge error message more clear
53
64
 
65
+ [Unreleased]: https://github.com/DeepLcom/deepl-rb/compare/v3.3.0...HEAD
66
+ [3.3.0]: https://github.com/DeepLcom/deepl-rb/compare/v3.2.0...v3.3.0
67
+ [3.2.0]: https://github.com/DeepLcom/deepl-rb/compare/v3.1.0...v3.2.0
54
68
  [3.1.0]: https://github.com/DeepLcom/deepl-rb/compare/v3.0.2...v3.1.0
55
69
  [3.0.2]: https://github.com/DeepLcom/deepl-rb/compare/v3.0.1...v3.0.2
56
70
  [3.0.1]: https://github.com/DeepLcom/deepl-rb/compare/v3.0.0...v3.0.1
57
71
  [3.0.0]: https://github.com/DeepLcom/deepl-rb/compare/v2.5.3...v3.0.0
58
- [2.5.3]: https://github.com/DeepLcom/deepl-rb/compare/v2.5.2...v2.5.3
72
+ [2.5.3]: https://github.com/DeepLcom/deepl-rb/releases/tag/v2.5.3
data/README.md CHANGED
@@ -167,6 +167,38 @@ The following parameters will be automatically converted:
167
167
  | `formality` | No conversion applied
168
168
  | `glossary_id` | No conversion applied
169
169
  | `context` | No conversion applied
170
+ | `extra_body_parameters` | Hash 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.
171
+
172
+ ### Rephrase Text
173
+
174
+ To rephrase or improve text, including changing the writing style or tone of the text, use the `rephrase` method:
175
+
176
+ ```rb
177
+ rephrased_text = DeepL.rephrase 'you will acquire new rephrased text', 'EN'
178
+
179
+ puts rephrased_text.class
180
+ # => DeepL::Resources::Text
181
+ puts rephrased_text.text
182
+ # => 'You get new rephrased text.'
183
+ ```
184
+
185
+ As with translate, the text input can be a single string or an array of strings.
186
+
187
+ You can use the additional arguments to specify the writing style or tone you want for the rephrased text:
188
+
189
+ ```rb
190
+ rephrased_text = DeepL.rephrase 'you will acquire new rephrased text', 'EN', 'casual'
191
+
192
+ puts rephrased_text.text
193
+ # => 'You'll get new, rephrased text.'
194
+ ```
195
+
196
+ ```rb
197
+ rephrased_text = DeepL.rephrase 'you will acquire new rephrased text', 'EN', nil, 'friendly'
198
+
199
+ puts rephrased_text.text
200
+ # => 'You'll get to enjoy new, rephrased text!'
201
+ ```
170
202
 
171
203
  ### Glossaries
172
204
 
@@ -291,6 +323,18 @@ doc_status = doc_handle.wait_until_document_translation_finished # alternatively
291
323
  DeepL.document.download(doc_handle, '/path/to/translated_document.pdf') unless doc_status.error?
292
324
  ```
293
325
 
326
+ You can also pass additional options to document translation methods, including `extra_body_parameters`:
327
+
328
+ ```rb
329
+ options = {
330
+ formality: 'more',
331
+ extra_body_parameters: { example_param: 'true' }
332
+ }
333
+ doc_handle = DeepL.document.upload('/path/to/spanish_document.pdf', 'ES', 'EN', nil, options)
334
+ ```
335
+
336
+ 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.
337
+
294
338
  ### Handle exceptions
295
339
 
296
340
  You can capture and process exceptions that may be raised during API calls. These are all the possible exceptions:
@@ -389,6 +433,30 @@ end
389
433
 
390
434
  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.
391
435
 
436
+ ## Options Constants
437
+
438
+ The available values for various possible options are provided under the `DeepL::Constants` namespace. The currently available options are
439
+
440
+ `TagHandling`
441
+ `SplitSentences`
442
+ `ModelType`
443
+ `Formality`
444
+ `WritingStyle`
445
+ `Tone`
446
+
447
+ To view all the possible options for a given constant, call `options`:
448
+
449
+ ```rb
450
+ all_available_tones = DeepL::Constants::Tones.options
451
+ ```
452
+
453
+ To check if a given string is a possible option for a given constant, call `valid?`:
454
+
455
+ ```rb
456
+ DeepL::Constants::Tones.valid?('friendly') # true
457
+ DeepL::Constants::Tones.valid?('rude') # false
458
+ ```
459
+
392
460
  ## Integrations
393
461
 
394
462
  ### Ruby on Rails
data/Rakefile CHANGED
@@ -33,6 +33,7 @@ Juwelier::Tasks.new do |gem|
33
33
  }
34
34
  gem.files.exclude '.github'
35
35
  gem.files.exclude '.circleci'
36
+ gem.files.exclude 'catalog-info.yaml'
36
37
  end
37
38
 
38
39
  Juwelier::RubygemsDotOrgTasks.new
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.1.0
1
+ 3.3.0
data/deepl-rb.gemspec CHANGED
@@ -2,17 +2,17 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Juwelier::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: deepl-rb 3.1.0 ruby lib
5
+ # stub: deepl-rb 3.3.0 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "deepl-rb".freeze
9
- s.version = "3.1.0"
9
+ s.version = "3.3.0"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
12
12
  s.metadata = { "bug_tracker_uri" => "https://github.com/DeepLcom/deepl-rb/issues", "changelog_uri" => "https://github.com/DeepLcom/deepl-rb/blob/main/CHANGELOG.md", "documentation_uri" => "https://github.com/DeepLcom/deepl-rb/blob/main/README.md", "homepage_uri" => "https://github.com/DeepLcom/deepl-rb" } if s.respond_to? :metadata=
13
13
  s.require_paths = ["lib".freeze]
14
14
  s.authors = ["DeepL SE".freeze]
15
- s.date = "2024-11-15"
15
+ s.date = "2025-11-04"
16
16
  s.description = "Official Ruby library for the DeepL language translation API (v2). For more information, check this: https://www.deepl.com/docs/api-reference.html".freeze
17
17
  s.email = "open-source@deepl.com".freeze
18
18
  s.extra_rdoc_files = [
@@ -39,6 +39,13 @@ Gem::Specification.new do |s|
39
39
  "lib/deepl.rb",
40
40
  "lib/deepl/api.rb",
41
41
  "lib/deepl/configuration.rb",
42
+ "lib/deepl/constants/base_constant.rb",
43
+ "lib/deepl/constants/formality.rb",
44
+ "lib/deepl/constants/model_type.rb",
45
+ "lib/deepl/constants/split_sentences.rb",
46
+ "lib/deepl/constants/tag_handling.rb",
47
+ "lib/deepl/constants/tone.rb",
48
+ "lib/deepl/constants/writing_style.rb",
42
49
  "lib/deepl/document_api.rb",
43
50
  "lib/deepl/exceptions/authorization_failed.rb",
44
51
  "lib/deepl/exceptions/bad_request.rb",
@@ -63,6 +70,7 @@ Gem::Specification.new do |s|
63
70
  "lib/deepl/requests/glossary/language_pairs.rb",
64
71
  "lib/deepl/requests/glossary/list.rb",
65
72
  "lib/deepl/requests/languages.rb",
73
+ "lib/deepl/requests/rephrase.rb",
66
74
  "lib/deepl/requests/translate.rb",
67
75
  "lib/deepl/requests/usage.rb",
68
76
  "lib/deepl/resources/base.rb",
@@ -80,14 +88,17 @@ Gem::Specification.new do |s|
80
88
  "spec/api/api_spec.rb",
81
89
  "spec/api/configuration_spec.rb",
82
90
  "spec/api/deepl_spec.rb",
91
+ "spec/constants/constants_spec.rb",
83
92
  "spec/fixtures/vcr_cassettes/deepl_document.yml",
84
93
  "spec/fixtures/vcr_cassettes/deepl_document_download.yml",
85
94
  "spec/fixtures/vcr_cassettes/deepl_glossaries.yml",
86
95
  "spec/fixtures/vcr_cassettes/deepl_languages.yml",
96
+ "spec/fixtures/vcr_cassettes/deepl_rephrase.yml",
87
97
  "spec/fixtures/vcr_cassettes/deepl_translate.yml",
88
98
  "spec/fixtures/vcr_cassettes/deepl_usage.yml",
89
99
  "spec/fixtures/vcr_cassettes/glossaries.yml",
90
100
  "spec/fixtures/vcr_cassettes/languages.yml",
101
+ "spec/fixtures/vcr_cassettes/rephrase_texts.yml",
91
102
  "spec/fixtures/vcr_cassettes/translate_texts.yml",
92
103
  "spec/fixtures/vcr_cassettes/usage.yml",
93
104
  "spec/integration_tests/document_api_spec.rb",
@@ -99,6 +110,7 @@ Gem::Specification.new do |s|
99
110
  "spec/requests/glossary/language_pairs_spec.rb",
100
111
  "spec/requests/glossary/list_spec.rb",
101
112
  "spec/requests/languages_spec.rb",
113
+ "spec/requests/rephrase_spec.rb",
102
114
  "spec/requests/translate_spec.rb",
103
115
  "spec/requests/usage_spec.rb",
104
116
  "spec/resources/glossary_spec.rb",
@@ -0,0 +1,18 @@
1
+ # Copyright 2025 DeepL SE (https://www.deepl.com)
2
+ # Use of this source code is governed by an MIT
3
+ # license that can be found in the LICENSE.md file.
4
+ # frozen_string_literal: true
5
+
6
+ module DeepL
7
+ module Constants
8
+ class BaseConstant
9
+ def self.options
10
+ constants.map { |const| const_get(const) }
11
+ end
12
+
13
+ def self.valid?(value)
14
+ options.include?(value)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,16 @@
1
+ # Copyright 2025 DeepL SE (https://www.deepl.com)
2
+ # Use of this source code is governed by an MIT
3
+ # license that can be found in the LICENSE.md file.
4
+ # frozen_string_literal: true
5
+
6
+ module DeepL
7
+ module Constants
8
+ class Formality < BaseConstant
9
+ DEFAULT = 'default'
10
+ MORE = 'more'
11
+ LESS = 'less'
12
+ PREFER_MORE = 'prefer_more'
13
+ PREFER_LESS = 'prefer_less'
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,14 @@
1
+ # Copyright 2025 DeepL SE (https://www.deepl.com)
2
+ # Use of this source code is governed by an MIT
3
+ # license that can be found in the LICENSE.md file.
4
+ # frozen_string_literal: true
5
+
6
+ module DeepL
7
+ module Constants
8
+ class ModelType < BaseConstant
9
+ QUALITY_OPTIMIZED = 'quality_optimized'
10
+ PREFER_QUALITY_OPTIMIZED = 'prefer_quality_optimized'
11
+ LATENCY_OPTIMIZED = 'latency_optimized'
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ # Copyright 2025 DeepL SE (https://www.deepl.com)
2
+ # Use of this source code is governed by an MIT
3
+ # license that can be found in the LICENSE.md file.
4
+ # frozen_string_literal: true
5
+
6
+ module DeepL
7
+ module Constants
8
+ class SplitSentences < BaseConstant
9
+ NO_SPLITTING = '0'
10
+ SPLIT_ON_PUNCTUATION_AND_NEWLINES = '1'
11
+ SPLIT_ON_PUNCTUATION_ONLY = 'nonewlines'
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,13 @@
1
+ # Copyright 2025 DeepL SE (https://www.deepl.com)
2
+ # Use of this source code is governed by an MIT
3
+ # license that can be found in the LICENSE.md file.
4
+ # frozen_string_literal: true
5
+
6
+ module DeepL
7
+ module Constants
8
+ class TagHandling < BaseConstant
9
+ XML = 'xml'
10
+ HTML = 'html'
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,20 @@
1
+ # Copyright 2025 DeepL SE (https://www.deepl.com)
2
+ # Use of this source code is governed by an MIT
3
+ # license that can be found in the LICENSE.md file.
4
+ # frozen_string_literal: true
5
+
6
+ module DeepL
7
+ module Constants
8
+ class Tone < BaseConstant
9
+ DEFAULT = 'default'
10
+ ENTHUSIASTIC = 'enthusiastic'
11
+ FRIENDLY = 'friendly'
12
+ CONFIDENT = 'confident'
13
+ DIPLOMATIC = 'diplomatic'
14
+ PREFER_ENTHUSIASTIC = 'prefer_enthusiastic'
15
+ PREFER_FRIENDLY = 'prefer_friendly'
16
+ PREFER_CONFIDENT = 'prefer_confident'
17
+ PREFER_DIPLOMATIC = 'prefer_diplomatic'
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ # Copyright 2025 DeepL SE (https://www.deepl.com)
2
+ # Use of this source code is governed by an MIT
3
+ # license that can be found in the LICENSE.md file.
4
+ # frozen_string_literal: true
5
+
6
+ module DeepL
7
+ module Constants
8
+ class WritingStyle < BaseConstant
9
+ DEFAULT = 'default'
10
+ SIMPLE = 'simple'
11
+ BUSINESS = 'business'
12
+ ACADEMIC = 'academic'
13
+ CASUAL = 'casual'
14
+ PREFER_SIMPLE = 'prefer_simple'
15
+ PREFER_BUSINESS = 'prefer_business'
16
+ PREFER_ACADEMIC = 'prefer_academic'
17
+ PREFER_CASUAL = 'prefer_casual'
18
+ end
19
+ end
20
+ end
@@ -6,7 +6,7 @@
6
6
  module DeepL
7
7
  module Exceptions
8
8
  class AuthorizationFailed < RequestError
9
- def message
9
+ def to_s
10
10
  'Authorization failed. Please supply a valid auth_key parameter.'
11
11
  end
12
12
  end
@@ -6,7 +6,7 @@
6
6
  module DeepL
7
7
  module Exceptions
8
8
  class BadRequest < RequestError
9
- def message
9
+ def to_s
10
10
  JSON.parse(response.body)['message']
11
11
  rescue JSON::ParserError
12
12
  response.body
@@ -6,7 +6,7 @@
6
6
  module DeepL
7
7
  module Exceptions
8
8
  class LimitExceeded < RequestError
9
- def message
9
+ def to_s
10
10
  'Limit exceeded. Please wait and send your request once again.'
11
11
  end
12
12
 
@@ -6,7 +6,7 @@
6
6
  module DeepL
7
7
  module Exceptions
8
8
  class NotFound < RequestError
9
- def message
9
+ def to_s
10
10
  JSON.parse(response.body)['message']
11
11
  rescue JSON::ParserError
12
12
  response.body
@@ -6,7 +6,7 @@
6
6
  module DeepL
7
7
  module Exceptions
8
8
  class QuotaExceeded < RequestError
9
- def message
9
+ def to_s
10
10
  'Quota exceeded. The character limit has been reached.'
11
11
  end
12
12
  end
@@ -6,7 +6,7 @@
6
6
  module DeepL
7
7
  module Exceptions
8
8
  class RequestEntityTooLarge < RequestError
9
- def message
9
+ def to_s
10
10
  'The request size has reached the supported limit. ' \
11
11
  "Make sure that you're not sending more than 50 text parts."
12
12
  end
@@ -13,7 +13,7 @@ module DeepL
13
13
  @response = response
14
14
  end
15
15
 
16
- def message
16
+ def to_s
17
17
  'Unknown error.'
18
18
  end
19
19
  end
@@ -6,7 +6,7 @@
6
6
  module DeepL
7
7
  module Exceptions
8
8
  class ServerError < RequestError
9
- def message
9
+ def to_s
10
10
  'An internal server error occured. Try again after waiting a short period.'
11
11
  end
12
12
 
@@ -46,6 +46,40 @@ module DeepL
46
46
  end
47
47
  end
48
48
 
49
+ # Returns options excluding extra_body_parameters
50
+ # extra_body_parameters are applied separately via apply_extra_body_parameters_* methods
51
+ def options_without_extra_params
52
+ options.reject do |k, _|
53
+ k.to_s == 'extra_body_parameters' || k.to_sym == :extra_body_parameters
54
+ end
55
+ end
56
+
57
+ # Apply extra body parameters to a hash payload (for JSON/form-encoded requests)
58
+ # Extra parameters will override existing keys
59
+ def apply_extra_body_parameters_to_json(payload)
60
+ return unless option?(:extra_body_parameters)
61
+
62
+ extra_params = option(:extra_body_parameters)
63
+ extra_params.each do |key, value|
64
+ payload[key] = value.to_s
65
+ end
66
+ end
67
+
68
+ # Apply extra body parameters to multipart form data array
69
+ # Extra parameters will override existing keys
70
+ def apply_extra_body_parameters_to_form(form_data)
71
+ return unless option?(:extra_body_parameters)
72
+
73
+ extra_params = option(:extra_body_parameters)
74
+ extra_params.each do |key, value|
75
+ key_str = key.to_s
76
+ # Remove existing key if present to allow override.
77
+ # Required for form data as it would be duplicated otherwise
78
+ form_data.reject! { |field| field[0].to_s == key_str }
79
+ form_data.push([key_str, value.to_s])
80
+ end
81
+ end
82
+
49
83
  # Files to reset: list of file objects to rewind when retrying the request
50
84
  def execute_request_with_retries(req, files_to_reset = []) # rubocop:disable all
51
85
  api.configuration.logger&.info("Request to the DeepL API: #{self}")
@@ -88,17 +122,16 @@ module DeepL
88
122
  end
89
123
 
90
124
  def post_request(payload)
125
+ apply_extra_body_parameters_to_json(payload)
91
126
  http_headers = add_json_content_type(headers)
92
127
  post_req = Net::HTTP::Post.new(uri.path, http_headers)
93
- post_req.body = payload.merge(options).to_json
128
+ post_req.body = payload.merge(options_without_extra_params).to_json
94
129
  post_req
95
130
  end
96
131
 
97
132
  def post_request_with_file(form_data)
98
133
  http_headers = add_multipart_form_content_type(headers)
99
134
  post_req = Net::HTTP::Post.new(uri.request_uri, http_headers)
100
- # options are passed in `form_data`
101
- form_data += options.map { |key, value| [key.to_s, value.to_s] }
102
135
  post_req.set_form(form_data, 'multipart/form-data')
103
136
  post_req
104
137
  end
@@ -106,14 +139,14 @@ module DeepL
106
139
  def get_request # rubocop:disable Naming/AccessorMethodName
107
140
  http_headers = add_json_content_type(headers)
108
141
  get_req = Net::HTTP::Get.new(uri.path, http_headers)
109
- get_req.body = options.to_json
142
+ get_req.body = options_without_extra_params.to_json
110
143
  get_req
111
144
  end
112
145
 
113
146
  def delete_request
114
147
  http_headers = add_json_content_type(headers)
115
148
  del_req = Net::HTTP::Delete.new(uri.path, http_headers)
116
- del_req.body = options.to_json
149
+ del_req.body = options_without_extra_params.to_json
117
150
  del_req
118
151
  end
119
152