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
21 changes: 21 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,25 @@ jobs:

- name: Run tests
run: ./scripts/test
examples:
name: examples
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Set up Java
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: |
8
17
cache: gradle
- name: Set up Gradle
uses: gradle/gradle-build-action@v2

- env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
run: |
./gradlew :openai-java-example:run
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "0.30.0"
".": "0.31.0"
}
2 changes: 1 addition & 1 deletion .stats.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
configured_endpoints: 65
configured_endpoints: 72
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai-5d30684c3118d049682ea30cdb4dbef39b97d51667da484689193dc40162af32.yml
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,26 @@
# Changelog

## 0.31.0 (2025-03-04)

Full Changelog: [v0.30.0...v0.31.0](https://github.com/openai/openai-java/compare/v0.30.0...v0.31.0)

### Features

* **client:** add file upload endpoints ([#268](https://github.com/openai/openai-java/issues/268)) ([456274d](https://github.com/openai/openai-java/commit/456274d2dc572ad4711d2fc3640c7e01aa08f4b8))
* **client:** allow configuring timeouts granularly ([#266](https://github.com/openai/openai-java/issues/266)) ([c3bc6e4](https://github.com/openai/openai-java/commit/c3bc6e4fb9717c7f6146f864ce3cc2451619c9f0))


### Chores

* **internal:** refactor `ErrorHandlingTest` ([#264](https://github.com/openai/openai-java/issues/264)) ([2472f85](https://github.com/openai/openai-java/commit/2472f859b49f49cf14539e787cf15e8f863f5dac))
* **internal:** run example files in CI ([#271](https://github.com/openai/openai-java/issues/271)) ([8da7851](https://github.com/openai/openai-java/commit/8da785184c3e039ea4b9d2b26c6d14b607291750))


### Documentation

* add raw response readme documentation ([#269](https://github.com/openai/openai-java/issues/269)) ([2839903](https://github.com/openai/openai-java/commit/28399031c60eed8899475c5d1d38677c2eaa2284))
* update URLs from stainlessapi.com to stainless.com ([#259](https://github.com/openai/openai-java/issues/259)) ([b824bf3](https://github.com/openai/openai-java/commit/b824bf39a44251e15c7c8b5b14bc6cbf9133dff5))

## 0.30.0 (2025-02-27)

Full Changelog: [v0.29.0...v0.30.0](https://github.com/openai/openai-java/compare/v0.29.0...v0.30.0)
Expand Down
39 changes: 35 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@

<!-- 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/0.30.0)
[![javadoc](https://javadoc.io/badge2/com.openai/openai-java/0.30.0/javadoc.svg)](https://javadoc.io/doc/com.openai/openai-java/0.30.0)
[![Maven Central](https://img.shields.io/maven-central/v/com.openai/openai-java)](https://central.sonatype.com/artifact/com.openai/openai-java/0.31.0)
[![javadoc](https://javadoc.io/badge2/com.openai/openai-java/0.31.0/javadoc.svg)](https://javadoc.io/doc/com.openai/openai-java/0.31.0)

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

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

```kotlin
implementation("com.openai:openai-java:0.30.0")
implementation("com.openai:openai-java:0.31.0")
```

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

Expand Down Expand Up @@ -314,6 +314,37 @@ try (HttpResponse response = client.files().content(params)) {
}
```

## Raw responses

The SDK defines methods that deserialize responses into instances of Java classes. However, these methods don't provide access to the response headers, status code, or the raw response body.

To access this data, prefix any HTTP method call on a client or service with `withRawResponse()`:

```java
import com.openai.core.http.Headers;
import com.openai.core.http.HttpResponseFor;
import com.openai.models.ChatCompletion;
import com.openai.models.ChatCompletionCreateParams;
import com.openai.models.ChatModel;

ChatCompletionCreateParams params = ChatCompletionCreateParams.builder()
.addUserMessage("Say this is a test")
.model(ChatModel.O3_MINI)
.build();
HttpResponseFor<ChatCompletion> chatCompletion = client.chat().completions().withRawResponse().create(params);

int statusCode = chatCompletion.statusCode();
Headers headers = chatCompletion.headers();
```

You can still deserialize the response into an instance of a Java class if needed:

```java
import com.openai.models.ChatCompletion;

ChatCompletion parsedChatCompletion = chatCompletion.parse();
```

## Error handling

The SDK throws custom unchecked exception types:
Expand Down
4 changes: 2 additions & 2 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

## Reporting Security Issues

This SDK is generated by [Stainless Software Inc](http://stainlessapi.com). Stainless takes security seriously, and encourages you to report any security vulnerability promptly so that appropriate action can be taken.
This SDK is generated by [Stainless Software Inc](http://stainless.com). Stainless takes security seriously, and encourages you to report any security vulnerability promptly so that appropriate action can be taken.

To report a security issue, please contact the Stainless team at security@stainlessapi.com.
To report a security issue, please contact the Stainless team at security@stainless.com.

## Responsible Disclosure

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 = "0.30.0" // x-release-please-version
version = "0.31.0" // x-release-please-version
}

subprojects {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
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
Expand Down Expand Up @@ -88,13 +89,12 @@ private constructor(private val okHttpClient: okhttp3.OkHttpClient, private val
)
}

val timeout = requestOptions.timeout
if (timeout != null) {
requestOptions.timeout?.let {
clientBuilder
.connectTimeout(timeout)
.readTimeout(timeout)
.writeTimeout(timeout)
.callTimeout(if (timeout.seconds == 0L) timeout else timeout.plusSeconds(30))
.connectTimeout(it.connect())
.readTimeout(it.read())
.writeTimeout(it.write())
.callTimeout(it.request())
}

val client = clientBuilder.build()
Expand Down Expand Up @@ -195,23 +195,24 @@ private constructor(private val okHttpClient: okhttp3.OkHttpClient, private val
class Builder internal constructor() {

private var baseUrl: HttpUrl? = null
// The default timeout is 10 minutes.
private var timeout: Duration = Duration.ofSeconds(600)
private var timeout: Timeout = Timeout.default()
private var proxy: Proxy? = null

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

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

fun timeout(timeout: Duration) = timeout(Timeout.builder().request(timeout).build())

fun proxy(proxy: Proxy?) = apply { this.proxy = proxy }

fun build(): OkHttpClient =
OkHttpClient(
okhttp3.OkHttpClient.Builder()
.connectTimeout(timeout)
.readTimeout(timeout)
.writeTimeout(timeout)
.callTimeout(if (timeout.seconds == 0L) timeout else timeout.plusSeconds(30))
.connectTimeout(timeout.connect())
.readTimeout(timeout.read())
.writeTimeout(timeout.write())
.callTimeout(timeout.request())
.proxy(proxy)
.build(),
checkRequired("baseUrl", baseUrl),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import com.openai.azure.AzureOpenAIServiceVersion
import com.openai.client.OpenAIClient
import com.openai.client.OpenAIClientImpl
import com.openai.core.ClientOptions
import com.openai.core.Timeout
import com.openai.core.http.Headers
import com.openai.core.http.QueryParams
import com.openai.credential.Credential
Expand All @@ -30,8 +31,7 @@ class OpenAIOkHttpClient private constructor() {

private var clientOptions: ClientOptions.Builder = ClientOptions.builder()
private var baseUrl: String = ClientOptions.PRODUCTION_URL
// The default timeout for the client is 10 minutes.
private var timeout: Duration = Duration.ofSeconds(600)
private var timeout: Timeout = Timeout.default()
private var proxy: Proxy? = null

fun baseUrl(baseUrl: String) = apply {
Expand Down Expand Up @@ -127,7 +127,19 @@ class OpenAIOkHttpClient private constructor() {
clientOptions.removeAllQueryParams(keys)
}

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

/**
* Sets the maximum time allowed for a complete HTTP call, not including retries.
*
* See [Timeout.request] for more details.
*
* For fine-grained control, pass a [Timeout] object.
*/
fun timeout(timeout: Duration) = timeout(Timeout.builder().request(timeout).build())

fun maxRetries(maxRetries: Int) = apply { clientOptions.maxRetries(maxRetries) }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import com.openai.azure.AzureOpenAIServiceVersion
import com.openai.client.OpenAIClientAsync
import com.openai.client.OpenAIClientAsyncImpl
import com.openai.core.ClientOptions
import com.openai.core.Timeout
import com.openai.core.http.Headers
import com.openai.core.http.QueryParams
import com.openai.credential.Credential
Expand All @@ -30,8 +31,7 @@ class OpenAIOkHttpClientAsync private constructor() {

private var clientOptions: ClientOptions.Builder = ClientOptions.builder()
private var baseUrl: String = ClientOptions.PRODUCTION_URL
// The default timeout for the client is 10 minutes.
private var timeout: Duration = Duration.ofSeconds(600)
private var timeout: Timeout = Timeout.default()
private var proxy: Proxy? = null

fun baseUrl(baseUrl: String) = apply {
Expand Down Expand Up @@ -127,7 +127,19 @@ class OpenAIOkHttpClientAsync private constructor() {
clientOptions.removeAllQueryParams(keys)
}

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

/**
* Sets the maximum time allowed for a complete HTTP call, not including retries.
*
* See [Timeout.request] for more details.
*
* For fine-grained control, pass a [Timeout] object.
*/
fun timeout(timeout: Duration) = timeout(Timeout.builder().request(timeout).build())

fun maxRetries(maxRetries: Int) = apply { clientOptions.maxRetries(maxRetries) }

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.services.blocking.AudioService
import com.openai.services.blocking.BatchService
import com.openai.services.blocking.BetaService
import com.openai.services.blocking.ChatService
Expand Down Expand Up @@ -38,6 +39,11 @@ interface OpenAIClient {
*/
fun async(): OpenAIClientAsync

/**
* Returns a view of this service that provides access to raw HTTP responses for each method.
*/
fun withRawResponse(): WithRawResponse

fun completions(): CompletionService

fun chat(): ChatService
Expand All @@ -48,6 +54,8 @@ interface OpenAIClient {

fun images(): ImageService

fun audio(): AudioService

fun moderations(): ModerationService

fun models(): ModelService
Expand All @@ -72,4 +80,32 @@ interface OpenAIClient {
* method.
*/
fun close()

/** A view of [OpenAIClient] that provides access to raw HTTP responses for each method. */
interface WithRawResponse {

fun completions(): CompletionService.WithRawResponse

fun chat(): ChatService.WithRawResponse

fun embeddings(): EmbeddingService.WithRawResponse

fun files(): FileService.WithRawResponse

fun images(): ImageService.WithRawResponse

fun audio(): AudioService.WithRawResponse

fun moderations(): ModerationService.WithRawResponse

fun models(): ModelService.WithRawResponse

fun fineTuning(): FineTuningService.WithRawResponse

fun beta(): BetaService.WithRawResponse

fun batches(): BatchService.WithRawResponse

fun uploads(): UploadService.WithRawResponse
}
}
Loading