Skip to content

Commit bca4f82

Browse files
feat: Add support for style_id and get all style rules endpoint
1 parent 3c2f9a9 commit bca4f82

File tree

10 files changed

+516
-1
lines changed

10 files changed

+516
-1
lines changed

README.md

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,9 @@ a `TextTranslationOptions`, with the following setters:
164164
`listGlossaries()` or `listMultilingualGlossaries()`).
165165
- `setGlossaryId()` is also available for backward-compatibility, accepting
166166
a string containing the glossary ID.
167+
- `setStyleRule()`: specifies a style rule to use with translation, as a string
168+
containing the ID of the style rule, or a `StyleRuleInfo` object.
169+
- `setStyleId()` is also available, accepting a string containing the style rule ID.
167170
- `setContext()`: specifies additional context to influence translations, that is not
168171
translated itself. Characters in the `context` parameter are not counted toward billing.
169172
See the [API documentation][api-docs-context-param] for more information and
@@ -640,6 +643,66 @@ class Example { // Continuing class Example from above
640643
The `translateDocument()` and `translateDocumentUpload()` functions both
641644
support the `glossary` argument.
642645

646+
### Style Rules
647+
648+
Style rules allow you to customize your translations using a managed, shared list
649+
of rules for style, formatting, and more. Multiple style rules can be stored with
650+
your account, each with a user-specified name and a uniquely-assigned ID.
651+
652+
#### Creating and managing style rules
653+
654+
Currently style rules must be created and managed in the DeepL UI via
655+
https://www.deepl.com/en/custom-rules. Full CRUD functionality via the APIs will
656+
come shortly.
657+
658+
#### Listing all style rules
659+
660+
`getAllStyleRules()` returns a list of `StyleRuleInfo` objects
661+
corresponding to all of your stored style rules. The method accepts optional
662+
parameters: `page` (page number for pagination, 0-indexed), `pageSize` (number
663+
of items per page), and `detailed` (whether to include detailed configuration
664+
rules in the `configuredRules` property).
665+
666+
```java
667+
class Example { // Continuing class Example from above
668+
public void styleRulesExample() throws Exception {
669+
// Get all style rules
670+
List<StyleRuleInfo> styleRules = client.getAllStyleRules();
671+
for (StyleRuleInfo rule : styleRules) {
672+
System.out.println(String.format("%s (%s)", rule.getName(), rule.getStyleId()));
673+
}
674+
675+
// Get style rules with detailed configuration
676+
List<StyleRuleInfo> styleRulesDetailed = client.getAllStyleRules(null, null, true);
677+
for (StyleRuleInfo rule : styleRulesDetailed) {
678+
if (rule.getConfiguredRules() != null && rule.getConfiguredRules().getNumbers() != null) {
679+
System.out.println(String.format("Number formatting rules: %s",
680+
String.join(", ", rule.getConfiguredRules().getNumbers().keySet())));
681+
}
682+
}
683+
}
684+
}
685+
```
686+
687+
#### Using a stored style rule
688+
689+
You can use a stored style rule for text translation by setting the `styleRule`
690+
argument to either the style rule ID or `StyleRuleInfo` object:
691+
692+
```java
693+
class Example { // Continuing class Example from above
694+
public void usingStyleRuleExample() throws Exception {
695+
String styleId = "dca2e053-8ae5-45e6-a0d2-881156e7f4e4";
696+
TextResult result = client.translateText(
697+
"Hallo, Welt!",
698+
"de",
699+
"en-US",
700+
new TextTranslationOptions().setStyleId(styleId));
701+
System.out.println(result.getText());
702+
}
703+
}
704+
```
705+
643706
### Checking account usage
644707

645708
To check account usage, use the `getUsage()` function.
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
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 file.
4+
package com.deepl.api;
5+
6+
import com.google.gson.annotations.*;
7+
import java.util.*;
8+
import org.jetbrains.annotations.*;
9+
10+
/** Configuration rules for a style rule list. */
11+
public class ConfiguredRules {
12+
@SerializedName(value = "dates_and_times")
13+
@Nullable
14+
private final Map<String, String> datesAndTimes;
15+
16+
@SerializedName(value = "formatting")
17+
@Nullable
18+
private final Map<String, String> formatting;
19+
20+
@SerializedName(value = "numbers")
21+
@Nullable
22+
private final Map<String, String> numbers;
23+
24+
@SerializedName(value = "punctuation")
25+
@Nullable
26+
private final Map<String, String> punctuation;
27+
28+
@SerializedName(value = "spelling_and_grammar")
29+
@Nullable
30+
private final Map<String, String> spellingAndGrammar;
31+
32+
@SerializedName(value = "style_and_tone")
33+
@Nullable
34+
private final Map<String, String> styleAndTone;
35+
36+
@SerializedName(value = "vocabulary")
37+
@Nullable
38+
private final Map<String, String> vocabulary;
39+
40+
/**
41+
* Initializes a new {@link ConfiguredRules} containing configuration rules for a style rule list.
42+
*
43+
* @param datesAndTimes Date and time formatting rules.
44+
* @param formatting Text formatting rules.
45+
* @param numbers Number formatting rules.
46+
* @param punctuation Punctuation rules.
47+
* @param spellingAndGrammar Spelling and grammar rules.
48+
* @param styleAndTone Style and tone rules.
49+
* @param vocabulary Vocabulary rules.
50+
*/
51+
public ConfiguredRules(
52+
@Nullable Map<String, String> datesAndTimes,
53+
@Nullable Map<String, String> formatting,
54+
@Nullable Map<String, String> numbers,
55+
@Nullable Map<String, String> punctuation,
56+
@Nullable Map<String, String> spellingAndGrammar,
57+
@Nullable Map<String, String> styleAndTone,
58+
@Nullable Map<String, String> vocabulary) {
59+
this.datesAndTimes = datesAndTimes;
60+
this.formatting = formatting;
61+
this.numbers = numbers;
62+
this.punctuation = punctuation;
63+
this.spellingAndGrammar = spellingAndGrammar;
64+
this.styleAndTone = styleAndTone;
65+
this.vocabulary = vocabulary;
66+
}
67+
68+
/** @return Date and time formatting rules. */
69+
@Nullable
70+
public Map<String, String> getDatesAndTimes() {
71+
return datesAndTimes;
72+
}
73+
74+
/** @return Text formatting rules. */
75+
@Nullable
76+
public Map<String, String> getFormatting() {
77+
return formatting;
78+
}
79+
80+
/** @return Number formatting rules. */
81+
@Nullable
82+
public Map<String, String> getNumbers() {
83+
return numbers;
84+
}
85+
86+
/** @return Punctuation rules. */
87+
@Nullable
88+
public Map<String, String> getPunctuation() {
89+
return punctuation;
90+
}
91+
92+
/** @return Spelling and grammar rules. */
93+
@Nullable
94+
public Map<String, String> getSpellingAndGrammar() {
95+
return spellingAndGrammar;
96+
}
97+
98+
/** @return Style and tone rules. */
99+
@Nullable
100+
public Map<String, String> getStyleAndTone() {
101+
return styleAndTone;
102+
}
103+
104+
/** @return Vocabulary rules. */
105+
@Nullable
106+
public Map<String, String> getVocabulary() {
107+
return vocabulary;
108+
}
109+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
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 file.
4+
package com.deepl.api;
5+
6+
import com.google.gson.annotations.*;
7+
import org.jetbrains.annotations.*;
8+
9+
/** Custom instruction for a style rule. */
10+
public class CustomInstruction {
11+
@SerializedName(value = "label")
12+
private final String label;
13+
14+
@SerializedName(value = "prompt")
15+
private final String prompt;
16+
17+
@SerializedName(value = "source_language")
18+
@Nullable
19+
private final String sourceLanguage;
20+
21+
/**
22+
* Initializes a new {@link CustomInstruction} containing a custom instruction for a style rule.
23+
*
24+
* @param label Label for the custom instruction.
25+
* @param prompt Prompt text for the custom instruction.
26+
* @param sourceLanguage Optional source language code for the custom instruction.
27+
*/
28+
public CustomInstruction(String label, String prompt, @Nullable String sourceLanguage) {
29+
this.label = label;
30+
this.prompt = prompt;
31+
this.sourceLanguage = sourceLanguage;
32+
}
33+
34+
/** @return Label for the custom instruction. */
35+
public String getLabel() {
36+
return label;
37+
}
38+
39+
/** @return Prompt text for the custom instruction. */
40+
public String getPrompt() {
41+
return prompt;
42+
}
43+
44+
/** @return Optional source language code for the custom instruction. */
45+
@Nullable
46+
public String getSourceLanguage() {
47+
return sourceLanguage;
48+
}
49+
}

deepl-java/src/main/java/com/deepl/api/DeepLClient.java

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -732,6 +732,68 @@ public void deleteMultilingualGlossaryDictionary(
732732
glossaryDict.getTargetLanguageCode());
733733
}
734734

735+
/**
736+
* Retrieves the list of all available style rules and returns a list of {@link StyleRuleInfo}
737+
* objects corresponding to all of your stored style rules.
738+
*
739+
* @param page Optional page number for pagination, 0-indexed.
740+
* @param pageSize Optional number of items per page.
741+
* @param detailed Optional flag indicating whether to include detailed configuration rules
742+
* including the configuredRules and customInstructions properties.
743+
* @return List of {@link StyleRuleInfo} objects for all available style rules.
744+
* @throws InterruptedException If the thread is interrupted during execution of this function.
745+
* @throws DeepLException If any error occurs while communicating with the DeepL API, a {@link
746+
* DeepLException} or a derived class will be thrown.
747+
*/
748+
public List<StyleRuleInfo> getAllStyleRules(
749+
@Nullable Integer page, @Nullable Integer pageSize, @Nullable Boolean detailed)
750+
throws DeepLException, InterruptedException {
751+
ArrayList<KeyValuePair<String, String>> queryParams = new ArrayList<>();
752+
if (page != null) {
753+
queryParams.add(new KeyValuePair<>("page", page.toString()));
754+
}
755+
if (pageSize != null) {
756+
queryParams.add(new KeyValuePair<>("page_size", pageSize.toString()));
757+
}
758+
if (detailed != null) {
759+
queryParams.add(new KeyValuePair<>("detailed", detailed.toString().toLowerCase()));
760+
}
761+
762+
String queryString = "";
763+
if (!queryParams.isEmpty()) {
764+
StringBuilder sb = new StringBuilder("?");
765+
for (int i = 0; i < queryParams.size(); i++) {
766+
if (i > 0) {
767+
sb.append("&");
768+
}
769+
KeyValuePair<String, String> param = queryParams.get(i);
770+
try {
771+
sb.append(URLEncoder.encode(param.getKey(), StandardCharsets.UTF_8.name()))
772+
.append("=")
773+
.append(URLEncoder.encode(param.getValue(), StandardCharsets.UTF_8.name()));
774+
} catch (java.io.UnsupportedEncodingException e) {
775+
throw new RuntimeException("UTF-8 encoding not supported", e);
776+
}
777+
}
778+
queryString = sb.toString();
779+
}
780+
781+
String relativeUrl = "/v3/style_rules" + queryString;
782+
HttpResponse response = httpClientWrapper.sendGetRequestWithBackoff(relativeUrl);
783+
checkResponse(response, false, false);
784+
return jsonParser.parseStyleRuleInfoList(response.getBody());
785+
}
786+
787+
/**
788+
* Functions the same as {@link DeepLClient#getAllStyleRules(Integer, Integer, Boolean)} but with
789+
* default parameters (all null).
790+
*
791+
* @see DeepLClient#getAllStyleRules(Integer, Integer, Boolean)
792+
*/
793+
public List<StyleRuleInfo> getAllStyleRules() throws DeepLException, InterruptedException {
794+
return getAllStyleRules(null, null, null);
795+
}
796+
735797
/** Creates a glossary with given details. */
736798
private MultilingualGlossaryInfo createGlossaryFromCsvInternal(
737799
String name, String sourceLanguageCode, String targetLanguageCode, String entries)

0 commit comments

Comments
 (0)