Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/main/java/com/google/genai/ApiClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,7 @@ protected Request buildRequest(

requestHttpOptions.ifPresent(
httpOptions -> {
requestBuilder.tag(HttpOptions.class, httpOptions);
if (httpOptions.retryOptions().isPresent()) {
requestBuilder.tag(HttpRetryOptions.class, mergedHttpOptions.retryOptions().get());
}
Expand Down
25 changes: 23 additions & 2 deletions src/main/java/com/google/genai/HttpApiClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,12 @@
import com.google.genai.types.ClientOptions;
import com.google.genai.types.HttpOptions;
import java.io.IOException;
import java.time.Duration;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

Expand Down Expand Up @@ -78,7 +80,16 @@ public HttpApiResponse request(
/** Executes the given HTTP request. */
private HttpApiResponse executeRequest(Request request) {
try {
return new HttpApiResponse(httpClient.newCall(request).execute());
OkHttpClient client = httpClient;
HttpOptions requestOptions = request.tag(HttpOptions.class);
if (requestOptions != null && requestOptions.timeout().isPresent()) {
client =
httpClient
.newBuilder()
.callTimeout(Duration.ofMillis(requestOptions.timeout().get()))
.build();
}
return new HttpApiResponse(client.newCall(request).execute());
} catch (IOException e) {
throw new GenAiIOException("Failed to execute HTTP request.", e);
}
Expand Down Expand Up @@ -114,7 +125,17 @@ public CompletableFuture<ApiResponse> asyncRequest(
private CompletableFuture<ApiResponse> asyncExecuteRequest(Request request) {
CompletableFuture<ApiResponse> future = new CompletableFuture<>();

httpClient
OkHttpClient client = httpClient;
HttpOptions requestOptions = request.tag(HttpOptions.class);
if (requestOptions != null && requestOptions.timeout().isPresent()) {
client =
httpClient
.newBuilder()
.callTimeout(Duration.ofMillis(requestOptions.timeout().get()))
.build();
}

client
.newCall(request)
.enqueue(
new Callback() {
Expand Down
25 changes: 25 additions & 0 deletions src/test/java/com/google/genai/HttpApiClientTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,31 @@ public void testRequestWithHttpOptions() throws Exception {
assertEquals("header", capturedRequest.header("test"));
}

@Test
public void testRequestWithHttpOptions_overrideTimeout() throws Exception {
// Arrange
HttpApiClient client =
new HttpApiClient(Optional.of(API_KEY), Optional.empty(), Optional.empty());
setMockClient(client);

okhttp3.OkHttpClient.Builder mockBuilder = Mockito.mock(okhttp3.OkHttpClient.Builder.class);
when(mockHttpClient.newBuilder()).thenReturn(mockBuilder);
when(mockBuilder.callTimeout(any(java.time.Duration.class))).thenReturn(mockBuilder);
when(mockBuilder.build()).thenReturn(mockHttpClient);

Optional<HttpOptions> requestOptions =
Optional.of(HttpOptions.builder().timeout(30000).build());

// Act
client.request("POST", TEST_PATH, TEST_REQUEST_JSON, requestOptions);

// Assert
verify(mockHttpClient).newBuilder();
verify(mockBuilder).callTimeout(java.time.Duration.ofMillis(30000));
verify(mockBuilder).build();
verify(mockHttpClient).newCall(any(okhttp3.Request.class));
}

@Test
public void testRequestWithHttpOptions_extraBody_addNewKey() throws Exception {
// Arrange
Expand Down
Loading