Skip to content

release: 2.8.0 #507

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
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
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "2.7.0"
".": "2.8.0"
}
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
# Changelog

## 2.8.0 (2025-06-14)

Full Changelog: [v2.7.0...v2.8.0](https://github.com/openai/openai-java/compare/v2.7.0...v2.8.0)

### Features

* **client:** implement per-endpoint base URL support ([c87f1af](https://github.com/openai/openai-java/commit/c87f1af80b1f3d898a5a1553be48ee87ea4e7b4f))


### Chores

* **internal:** codegen related update ([3597aee](https://github.com/openai/openai-java/commit/3597aee95ae1956afbe8bd62b5a6946dd62256b3))

## 2.7.0 (2025-06-10)

Full Changelog: [v2.6.0...v2.7.0](https://github.com/openai/openai-java/compare/v2.6.0...v2.7.0)
Expand Down
25 changes: 20 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@

<!-- x-release-please-start-version -->

[![Maven Central](https://img.shields.io/maven-central/v/com.openai/openai-java)](https://central.sonatype.com/artifact/com.openai/openai-java/2.7.0)
[![javadoc](https://javadoc.io/badge2/com.openai/openai-java/2.7.0/javadoc.svg)](https://javadoc.io/doc/com.openai/openai-java/2.7.0)
[![Maven Central](https://img.shields.io/maven-central/v/com.openai/openai-java)](https://central.sonatype.com/artifact/com.openai/openai-java/2.8.0)
[![javadoc](https://javadoc.io/badge2/com.openai/openai-java/2.8.0/javadoc.svg)](https://javadoc.io/doc/com.openai/openai-java/2.8.0)

<!-- x-release-please-end -->

The OpenAI Java SDK provides convenient access to the [OpenAI REST API](https://platform.openai.com/docs) from applications written in Java.

<!-- x-release-please-start-version -->

The REST API documentation can be found on [platform.openai.com](https://platform.openai.com/docs). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.openai/openai-java/2.7.0).
The REST API documentation can be found on [platform.openai.com](https://platform.openai.com/docs). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.openai/openai-java/2.8.0).

<!-- x-release-please-end -->

Expand All @@ -22,7 +22,7 @@ The REST API documentation can be found on [platform.openai.com](https://platfor
### Gradle

```kotlin
implementation("com.openai:openai-java:2.7.0")
implementation("com.openai:openai-java:2.8.0")
```

### Maven
Expand All @@ -31,7 +31,7 @@ implementation("com.openai:openai-java:2.7.0")
<dependency>
<groupId>com.openai</groupId>
<artifactId>openai-java</artifactId>
<version>2.7.0</version>
<version>2.8.0</version>
</dependency>
```

Expand Down Expand Up @@ -132,6 +132,21 @@ See this table for the available options:
> Don't create more than one client in the same application. Each client has a connection pool and
> thread pools, which are more efficient to share between requests.

### Modifying configuration

To temporarily use a modified client configuration, while reusing the same connection and thread pools, call `withOptions()` on any client or service:

```java
import com.openai.client.OpenAIClient;

OpenAIClient clientWithOptions = client.withOptions(optionsBuilder -> {
optionsBuilder.baseUrl("https://example.com");
optionsBuilder.maxRetries(42);
});
```

The `withOptions()` method does not affect the original client or service.

## Requests and responses

To send a request to the OpenAI API, build an instance of some `Params` class and pass it to the corresponding client method. When the response is received, it will be deserialized into an instance of a Java class.
Expand Down
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ repositories {

allprojects {
group = "com.openai"
version = "2.7.0" // x-release-please-version
version = "2.8.0" // x-release-please-version
}

subprojects {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package com.openai.client.okhttp

import com.openai.core.RequestOptions
import com.openai.core.Timeout
import com.openai.core.checkRequired
import com.openai.core.http.Headers
import com.openai.core.http.HttpClient
import com.openai.core.http.HttpMethod
Expand All @@ -17,7 +16,6 @@ import java.time.Duration
import java.util.concurrent.CompletableFuture
import okhttp3.Call
import okhttp3.Callback
import okhttp3.HttpUrl
import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.MediaType
import okhttp3.MediaType.Companion.toMediaType
Expand All @@ -28,8 +26,7 @@ import okhttp3.Response
import okhttp3.logging.HttpLoggingInterceptor
import okio.BufferedSink

class OkHttpClient
private constructor(private val okHttpClient: okhttp3.OkHttpClient, private val baseUrl: HttpUrl) :
class OkHttpClient private constructor(private val okHttpClient: okhttp3.OkHttpClient) :
HttpClient {

override fun execute(request: HttpRequest, requestOptions: RequestOptions): HttpResponse {
Expand Down Expand Up @@ -140,11 +137,7 @@ private constructor(private val okHttpClient: okhttp3.OkHttpClient, private val
}

private fun HttpRequest.toUrl(): String {
url?.let {
return it
}

val builder = baseUrl.newBuilder()
val builder = baseUrl.toHttpUrl().newBuilder()
pathSegments.forEach(builder::addPathSegment)
queryParams.keys().forEach { key ->
queryParams.values(key).forEach { builder.addQueryParameter(key, it) }
Expand Down Expand Up @@ -194,12 +187,9 @@ private constructor(private val okHttpClient: okhttp3.OkHttpClient, private val

class Builder internal constructor() {

private var baseUrl: HttpUrl? = null
private var timeout: Timeout = Timeout.default()
private var proxy: Proxy? = null

fun baseUrl(baseUrl: String) = apply { this.baseUrl = baseUrl.toHttpUrl() }

fun timeout(timeout: Timeout) = apply { this.timeout = timeout }

fun timeout(timeout: Duration) = timeout(Timeout.builder().request(timeout).build())
Expand All @@ -214,8 +204,7 @@ private constructor(private val okHttpClient: okhttp3.OkHttpClient, private val
.writeTimeout(timeout.write())
.callTimeout(timeout.request())
.proxy(proxy)
.build(),
checkRequired("baseUrl", baseUrl),
.build()
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -186,13 +186,7 @@ class OpenAIOkHttpClient private constructor() {
fun build(): OpenAIClient =
OpenAIClientImpl(
clientOptions
.httpClient(
OkHttpClient.builder()
.baseUrl(clientOptions.baseUrl())
.timeout(timeout)
.proxy(proxy)
.build()
)
.httpClient(OkHttpClient.builder().timeout(timeout).proxy(proxy).build())
.build()
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,13 +186,7 @@ class OpenAIOkHttpClientAsync private constructor() {
fun build(): OpenAIClientAsync =
OpenAIClientAsyncImpl(
clientOptions
.httpClient(
OkHttpClient.builder()
.baseUrl(clientOptions.baseUrl())
.timeout(timeout)
.proxy(proxy)
.build()
)
.httpClient(OkHttpClient.builder().timeout(timeout).proxy(proxy).build())
.build()
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ internal fun HttpRequest.Builder.addPathSegmentsForAzure(
clientOptions: ClientOptions,
deploymentModel: String?,
): HttpRequest.Builder = apply {
if (isAzureEndpoint(clientOptions.baseUrl)) {
if (isAzureEndpoint(clientOptions.baseUrl())) {
addPathSegment("openai")
deploymentModel?.let { addPathSegments("deployments", it) }
}
Expand All @@ -21,7 +21,8 @@ internal fun HttpRequest.Builder.replaceBearerTokenForAzure(
clientOptions: ClientOptions
): HttpRequest.Builder = apply {
if (
isAzureEndpoint(clientOptions.baseUrl) && clientOptions.credential is BearerTokenCredential
isAzureEndpoint(clientOptions.baseUrl()) &&
clientOptions.credential is BearerTokenCredential
) {
replaceHeaders("Authorization", "Bearer ${clientOptions.credential.token()}")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

package com.openai.client

import com.openai.core.ClientOptions
import com.openai.services.blocking.AudioService
import com.openai.services.blocking.BatchService
import com.openai.services.blocking.BetaService
Expand All @@ -19,6 +20,7 @@ import com.openai.services.blocking.ModerationService
import com.openai.services.blocking.ResponseService
import com.openai.services.blocking.UploadService
import com.openai.services.blocking.VectorStoreService
import java.util.function.Consumer

/**
* A client for interacting with the OpenAI REST API synchronously. You can also switch to
Expand Down Expand Up @@ -49,6 +51,13 @@ interface OpenAIClient {
*/
fun withRawResponse(): WithRawResponse

/**
* Returns a view of this service with the given option modifications applied.
*
* The original service is not modified.
*/
fun withOptions(modifier: Consumer<ClientOptions.Builder>): OpenAIClient

fun completions(): CompletionService

fun chat(): ChatService
Expand Down Expand Up @@ -99,6 +108,13 @@ interface OpenAIClient {
/** A view of [OpenAIClient] that provides access to raw HTTP responses for each method. */
interface WithRawResponse {

/**
* Returns a view of this service with the given option modifications applied.
*
* The original service is not modified.
*/
fun withOptions(modifier: Consumer<ClientOptions.Builder>): OpenAIClient.WithRawResponse

fun completions(): CompletionService.WithRawResponse

fun chat(): ChatService.WithRawResponse
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

package com.openai.client

import com.openai.core.ClientOptions
import com.openai.services.async.AudioServiceAsync
import com.openai.services.async.BatchServiceAsync
import com.openai.services.async.BetaServiceAsync
Expand All @@ -19,6 +20,7 @@ import com.openai.services.async.ModerationServiceAsync
import com.openai.services.async.ResponseServiceAsync
import com.openai.services.async.UploadServiceAsync
import com.openai.services.async.VectorStoreServiceAsync
import java.util.function.Consumer

/**
* A client for interacting with the OpenAI REST API asynchronously. You can also switch to
Expand Down Expand Up @@ -49,6 +51,13 @@ interface OpenAIClientAsync {
*/
fun withRawResponse(): WithRawResponse

/**
* Returns a view of this service with the given option modifications applied.
*
* The original service is not modified.
*/
fun withOptions(modifier: Consumer<ClientOptions.Builder>): OpenAIClientAsync

fun completions(): CompletionServiceAsync

fun chat(): ChatServiceAsync
Expand Down Expand Up @@ -99,6 +108,15 @@ interface OpenAIClientAsync {
/** A view of [OpenAIClientAsync] that provides access to raw HTTP responses for each method. */
interface WithRawResponse {

/**
* Returns a view of this service with the given option modifications applied.
*
* The original service is not modified.
*/
fun withOptions(
modifier: Consumer<ClientOptions.Builder>
): OpenAIClientAsync.WithRawResponse

fun completions(): CompletionServiceAsync.WithRawResponse

fun chat(): ChatServiceAsync.WithRawResponse
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import com.openai.services.async.UploadServiceAsync
import com.openai.services.async.UploadServiceAsyncImpl
import com.openai.services.async.VectorStoreServiceAsync
import com.openai.services.async.VectorStoreServiceAsyncImpl
import java.util.function.Consumer

class OpenAIClientAsyncImpl(private val clientOptions: ClientOptions) : OpenAIClientAsync {

Expand Down Expand Up @@ -120,6 +121,9 @@ class OpenAIClientAsyncImpl(private val clientOptions: ClientOptions) : OpenAICl

override fun withRawResponse(): OpenAIClientAsync.WithRawResponse = withRawResponse

override fun withOptions(modifier: Consumer<ClientOptions.Builder>): OpenAIClientAsync =
OpenAIClientAsyncImpl(clientOptions.toBuilder().apply(modifier::accept).build())

override fun completions(): CompletionServiceAsync = completions

override fun chat(): ChatServiceAsync = chat
Expand Down Expand Up @@ -227,6 +231,13 @@ class OpenAIClientAsyncImpl(private val clientOptions: ClientOptions) : OpenAICl
ContainerServiceAsyncImpl.WithRawResponseImpl(clientOptions)
}

override fun withOptions(
modifier: Consumer<ClientOptions.Builder>
): OpenAIClientAsync.WithRawResponse =
OpenAIClientAsyncImpl.WithRawResponseImpl(
clientOptions.toBuilder().apply(modifier::accept).build()
)

override fun completions(): CompletionServiceAsync.WithRawResponse = completions

override fun chat(): ChatServiceAsync.WithRawResponse = chat
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import com.openai.services.blocking.UploadService
import com.openai.services.blocking.UploadServiceImpl
import com.openai.services.blocking.VectorStoreService
import com.openai.services.blocking.VectorStoreServiceImpl
import java.util.function.Consumer

class OpenAIClientImpl(private val clientOptions: ClientOptions) : OpenAIClient {

Expand Down Expand Up @@ -108,6 +109,9 @@ class OpenAIClientImpl(private val clientOptions: ClientOptions) : OpenAIClient

override fun withRawResponse(): OpenAIClient.WithRawResponse = withRawResponse

override fun withOptions(modifier: Consumer<ClientOptions.Builder>): OpenAIClient =
OpenAIClientImpl(clientOptions.toBuilder().apply(modifier::accept).build())

override fun completions(): CompletionService = completions

override fun chat(): ChatService = chat
Expand Down Expand Up @@ -215,6 +219,13 @@ class OpenAIClientImpl(private val clientOptions: ClientOptions) : OpenAIClient
ContainerServiceImpl.WithRawResponseImpl(clientOptions)
}

override fun withOptions(
modifier: Consumer<ClientOptions.Builder>
): OpenAIClient.WithRawResponse =
OpenAIClientImpl.WithRawResponseImpl(
clientOptions.toBuilder().apply(modifier::accept).build()
)

override fun completions(): CompletionService.WithRawResponse = completions

override fun chat(): ChatService.WithRawResponse = chat
Expand Down
Loading
Loading