Skip to content

Commit ff97e10

Browse files
hive-botclaude
andcommitted
fix: read absent custom tag speech-to-speech minutes as null
CustomTagUsageBreakdown.getSpeechToSpeechMinutes() is now a nullable Double that is null when speech_to_speech_minutes is absent, instead of 0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 24f5796 commit ff97e10

5 files changed

Lines changed: 34 additions & 8 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
150150
end day are included. Report dates are `Date` values at midnight UTC.
151151
`DeveloperKey.getLabel()`, `DeveloperKey.getUsageLimits()`,
152152
`KeyUsage.getApiKeyLabel()`, `AdminUsageReport.getTotalUsage()` and
153-
`AdminUsageBreakdown.getSpeechToSpeechMinutes()` (a `Double`) return `null`
154-
when the API sends no value.
153+
`AdminUsageBreakdown.getSpeechToSpeechMinutes()` and
154+
`CustomTagUsageBreakdown.getSpeechToSpeechMinutes()` (both a `Double`) return
155+
`null` when the API sends no value.
155156
`setDeveloperKeyUsageLimits()` takes a `DeveloperKeyUsageLimitsUpdate` and
156157
changes only the limits set in it, including the speech-to-speech limit.
157158
- Added the API Pro fields of `GET /v2/usage` to `Usage`:

‎README.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1798,6 +1798,8 @@ chooses between the whole period (`CustomTagUsageAggregateBy.Period`, the
17981798
default) and per-day usage (`CustomTagUsageAggregateBy.Day`); a string is sent
17991799
as given. The results are paginated: pass the `getNextPage()` value of a report
18001800
as the `page` argument to get the next page.
1801+
`CustomTagUsageBreakdown.getSpeechToSpeechMinutes()` (a `Double`) is `null` if
1802+
the report does not include it.
18011803

18021804
```java
18031805
import com.deepl.api.*;

‎deepl-java/src/main/java/com/deepl/api/CustomTagUsageBreakdown.java‎

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
package com.deepl.api;
55

66
import com.google.gson.annotations.*;
7+
import org.jetbrains.annotations.*;
78

89
/** Usage totals for a custom tag, see {@link CustomTagUsage}. */
910
public class CustomTagUsageBreakdown {
@@ -20,7 +21,7 @@ public class CustomTagUsageBreakdown {
2021
private final double speechToTextMinutes;
2122

2223
@SerializedName(value = "speech_to_speech_minutes")
23-
private final double speechToSpeechMinutes;
24+
private final @Nullable Double speechToSpeechMinutes;
2425

2526
/**
2627
* Initializes a new {@link CustomTagUsageBreakdown}.
@@ -29,14 +30,15 @@ public class CustomTagUsageBreakdown {
2930
* @param textTranslationCharacters Number of characters used for text translation.
3031
* @param textImprovementCharacters Number of characters used for text improvement.
3132
* @param speechToTextMinutes Number of speech-to-text minutes used.
32-
* @param speechToSpeechMinutes Number of speech-to-speech minutes used.
33+
* @param speechToSpeechMinutes Number of speech-to-speech minutes used, or <code>null</code> if
34+
* the report does not include it.
3335
*/
3436
public CustomTagUsageBreakdown(
3537
long totalCharacters,
3638
long textTranslationCharacters,
3739
long textImprovementCharacters,
3840
double speechToTextMinutes,
39-
double speechToSpeechMinutes) {
41+
@Nullable Double speechToSpeechMinutes) {
4042
this.totalCharacters = totalCharacters;
4143
this.textTranslationCharacters = textTranslationCharacters;
4244
this.textImprovementCharacters = textImprovementCharacters;
@@ -64,8 +66,11 @@ public double getSpeechToTextMinutes() {
6466
return speechToTextMinutes;
6567
}
6668

67-
/** @return Number of speech-to-speech minutes used. */
68-
public double getSpeechToSpeechMinutes() {
69+
/**
70+
* @return Number of speech-to-speech minutes used, or <code>null</code> if the report does not
71+
* include it.
72+
*/
73+
public @Nullable Double getSpeechToSpeechMinutes() {
6974
return speechToSpeechMinutes;
7075
}
7176
}

‎deepl-java/src/main/java/com/deepl/api/parsing/AdminResponseParser.java‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ private CustomTagUsageBreakdown parseCustomTagBreakdown(@Nullable JsonElement js
149149
count(object, "text_translation_characters"),
150150
count(object, "text_improvement_characters"),
151151
number(object, "speech_to_text_minutes"),
152-
number(object, "speech_to_speech_minutes"));
152+
numberOrNull(object, "speech_to_speech_minutes"));
153153
}
154154

155155
private static JsonObject asObject(@Nullable JsonElement json) {

‎deepl-java/src/offlineTest/java/com/deepl/api/AdminClientTest.java‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,24 @@ void readsAbsentSpeechToSpeechMinutesAsNull() throws Exception {
150150
assertNull(report.getKeyUsages().get(0).getUsage().getSpeechToSpeechMinutes());
151151
}
152152

153+
@Test
154+
void readsAbsentCustomTagSpeechToSpeechMinutesAsNull() throws Exception {
155+
wm.stubFor(
156+
get("/v2/admin/analytics/custom-tags?start_date=2025-09-29&end_date=2025-10-01")
157+
.willReturn(
158+
okJson(
159+
"{\"custom_tag_usage_report\":{\"usage\":["
160+
+ "{\"custom_tag\":\"a\",\"breakdown\":{\"speech_to_speech_minutes\":0}},"
161+
+ "{\"custom_tag\":\"b\",\"breakdown\":{\"total_characters\":4}}]}}")));
162+
163+
List<CustomTagUsage> usage =
164+
client
165+
.getCustomTagUsageAnalytics(LocalDate.of(2025, 9, 29), LocalDate.of(2025, 10, 1))
166+
.getUsage();
167+
assertEquals(0.0, usage.get(0).getBreakdown().getSpeechToSpeechMinutes());
168+
assertNull(usage.get(1).getBreakdown().getSpeechToSpeechMinutes());
169+
}
170+
153171
@Test
154172
void readsAbsentTotalUsageAsNull() throws Exception {
155173
wm.stubFor(

0 commit comments

Comments
 (0)