openai/openai-java

Public

mirrored from https://github.com/openai/openai-javaAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v0.7.5

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

README.md

409lines · modecode

1# OpenAI Java API Library
2
3> [!NOTE]
4> The OpenAI Java API Library is currently in _alpha_.
5>
6> There may be frequent breaking changes.
7
8<!-- x-release-please-start-version -->
9
10[![Maven Central](https://img.shields.io/maven-central/v/com.openai/openai-java)](https://central.sonatype.com/artifact/com.openai/openai-java/0.7.5)
11
12<!-- x-release-please-end -->
13
14The OpenAI Java SDK provides convenient access to the OpenAI REST API from applications written in Java. It includes helper classes with helpful types and documentation for every request and response property.
15
16The OpenAI Java SDK is similar to the OpenAI Kotlin SDK but with minor differences that make it more ergonomic for use in Java, such as `Optional` instead of nullable values, `Stream` instead of `Sequence`, and `CompletableFuture` instead of suspend functions.
17
18## Documentation
19
20The REST API documentation can be found on [platform.openai.com](https://platform.openai.com/docs).
21
22---
23
24## Getting started
25
26### Install dependencies
27
28#### Gradle
29
30<!-- x-release-please-start-version -->
31
32```kotlin
33implementation("com.openai:openai-java:0.7.5")
34```
35
36#### Maven
37
38```xml
39<dependency>
40 <groupId>com.openai</groupId>
41 <artifactId>openai-java</artifactId>
42 <version>0.7.5</version>
43</dependency>
44```
45
46<!-- x-release-please-end -->
47
48### Configure the client
49
50Use `OpenAIOkHttpClient.builder()` to configure the client. At a minimum you need to set `.apiKey()`:
51
52```java
53import com.openai.client.OpenAIClient;
54import com.openai.client.okhttp.OpenAIOkHttpClient;
55
56OpenAIClient client = OpenAIOkHttpClient.builder()
57 .apiKey("My API Key")
58 .build();
59```
60
61Alternately, set the environment with `OPENAI_API_KEY`, `OPENAI_ORG_ID` or `OPENAI_PROJECT_ID`, and use `OpenAIOkHttpClient.fromEnv()` to read from the environment.
62
63```java
64OpenAIClient client = OpenAIOkHttpClient.fromEnv();
65
66// Note: you can also call fromEnv() from the client builder, for example if you need to set additional properties
67OpenAIClient client = OpenAIOkHttpClient.builder()
68 .fromEnv()
69 // ... set properties on the builder
70 .build();
71```
72
73| Property | Environment variable | Required | Default value |
74| ------------ | -------------------- | -------- | ------------- |
75| apiKey | `OPENAI_API_KEY` | true | — |
76| organization | `OPENAI_ORG_ID` | false | — |
77| project | `OPENAI_PROJECT_ID` | false | — |
78
79Read the documentation for more configuration options.
80
81---
82
83### Example: creating a resource
84
85To create a new chat completion, first use the `ChatCompletionCreateParams` builder to specify attributes,
86then pass that to the `create` method of the `completions` service.
87
88```java
89import com.openai.models.ChatCompletion;
90import com.openai.models.ChatCompletionCreateParams;
91import java.util.List;
92
93ChatCompletionCreateParams params = ChatCompletionCreateParams.builder()
94 .message(List.of(ChatCompletionMessageParam.ofChatCompletionUserMessageParam(ChatCompletionUserMessageParam.builder()
95 .role(ChatCompletionUserMessageParam.Role.USER)
96 .content(ChatCompletionUserMessageParam.Content.ofTextContent("Say this is a test"))
97 .build())))
98 .model(ChatModel.O1_PREVIEW)
99 .build();
100ChatCompletion chatCompletion = client.chat().completions().create(params);
101```
102
103### Example: listing resources
104
105The OpenAI API provides a `list` method to get a paginated list of jobs.
106You can retrieve the first page by:
107
108```java
109import com.openai.models.FineTuningJob;
110import com.openai.models.Page;
111
112FineTuningJobListPage page = client.fineTuning().jobs().list();
113for (FineTuningJob job : page.data()) {
114 System.out.println(job);
115}
116```
117
118Use the `FineTuningJobListParams` builder to set parameters:
119
120```java
121FineTuningJobListParams params = FineTuningJobListParams.builder()
122 .limit(20)
123 .build();
124FineTuningJobListPage page1 = client.fineTuning().jobs().list(params);
125
126// Using the `from` method of the builder you can reuse previous params values:
127FineTuningJobListPage page2 = client.fineTuning().jobs().list(FineTuningJobListParams.builder()
128 .from(params)
129 .build());
130
131// Or easily get params for the next page by using the helper `getNextPageParams`:
132FineTuningJobListPage page3 = client.fineTuning().jobs().list(params.getNextPageParams(page2));
133```
134
135See [Pagination](#pagination) below for more information on transparently working with lists of objects without worrying about fetching each page.
136
137---
138
139## Requests
140
141### Parameters and bodies
142
143To make a request to the OpenAI API, you generally build an instance of the appropriate `Params` class.
144
145In [Example: creating a resource](#example-creating-a-resource) above, we used the `ChatCompletionCreateParams.builder()` to pass to
146the `create` method of the `completions` service.
147
148Sometimes, the API may support other properties that are not yet supported in the Java SDK types. In that case,
149you can attach them using the `putAdditionalProperty` method.
150
151```java
152import com.openai.models.core.JsonValue;
153ChatCompletionCreateParams params = ChatCompletionCreateParams.builder()
154 // ... normal properties
155 .putAdditionalProperty("secret_param", JsonValue.from("4242"))
156 .build();
157```
158
159## Responses
160
161### Response validation
162
163When receiving a response, the OpenAI Java SDK will deserialize it into instances of the typed model classes. In rare cases, the API may return a response property that doesn't match the expected Java type. If you directly access the mistaken property, the SDK will throw an unchecked `OpenAIInvalidDataException` at runtime. If you would prefer to check in advance that that response is completely well-typed, call `.validate()` on the returned model.
164
165```java
166ChatCompletion chatCompletion = client.chat().completions().create().validate();
167```
168
169### Response properties as JSON
170
171In rare cases, you may want to access the underlying JSON value for a response property rather than using the typed version provided by
172this SDK. Each model property has a corresponding JSON version, with an underscore before the method name, which returns a `JsonField` value.
173
174```java
175JsonField field = responseObj._field();
176
177if (field.isMissing()) {
178 // Value was not specified in the JSON response
179} else if (field.isNull()) {
180 // Value was provided as a literal null
181} else {
182 // See if value was provided as a string
183 Optional<String> jsonString = field.asString();
184
185 // If the value given by the API did not match the shape that the SDK expects
186 // you can deserialise into a custom type
187 MyClass myObj = responseObj._field().asUnknown().orElseThrow().convert(MyClass.class);
188}
189```
190
191### Additional model properties
192
193Sometimes, the server response may include additional properties that are not yet available in this library's types. You can access them using the model's `_additionalProperties` method:
194
195```java
196JsonValue secret = errorObject._additionalProperties().get("secret_field");
197```
198
199---
200
201## Pagination
202
203For methods that return a paginated list of results, this library provides convenient ways access
204the results either one page at a time, or item-by-item across all pages.
205
206### Auto-pagination
207
208To iterate through all results across all pages, you can use `autoPager`,
209which automatically handles fetching more pages for you:
210
211### Synchronous
212
213```java
214// As an Iterable:
215FineTuningJobListPage page = client.fineTuning().jobs().list(params);
216for (FineTuningJob job : page.autoPager()) {
217 System.out.println(job);
218};
219
220// As a Stream:
221client.fineTuning().jobs().list(params).autoPager().stream()
222 .limit(50)
223 .forEach(job -> System.out.println(job));
224```
225
226### Asynchronous
227
228```java
229// Using forEach, which returns CompletableFuture<Void>:
230asyncClient.fineTuning().jobs().list(params).autoPager()
231 .forEach(job -> System.out.println(job), executor);
232```
233
234### Manual pagination
235
236If none of the above helpers meet your needs, you can also manually request pages one-by-one.
237A page of results has a `data()` method to fetch the list of objects, as well as top-level
238`response` and other methods to fetch top-level data about the page. It also has methods
239`hasNextPage`, `getNextPage`, and `getNextPageParams` methods to help with pagination.
240
241```java
242FineTuningJobListPage page = client.fineTuning().jobs().list(params);
243while (page != null) {
244 for (FineTuningJob job : page.data()) {
245 System.out.println(job);
246 }
247
248 page = page.getNextPage().orElse(null);
249}
250```
251
252---
253
254## Error handling
255
256This library throws exceptions in a single hierarchy for easy handling:
257
258- **`OpenAIException`** - Base exception for all exceptions
259
260 - **`OpenAIServiceException`** - HTTP errors with a well-formed response body we were able to parse. The exception message and the `.debuggingRequestId()` will be set by the server.
261
262 | 400 | BadRequestException |
263 | ------ | ----------------------------- |
264 | 401 | AuthenticationException |
265 | 403 | PermissionDeniedException |
266 | 404 | NotFoundException |
267 | 422 | UnprocessableEntityException |
268 | 429 | RateLimitException |
269 | 5xx | InternalServerException |
270 | others | UnexpectedStatusCodeException |
271
272 - **`OpenAIIoException`** - I/O networking errors
273 - **`OpenAIInvalidDataException`** - any other exceptions on the client side, e.g.:
274 - We failed to serialize the request body
275 - We failed to parse the response body (has access to response code and body)
276
277## Microsoft Azure OpenAI
278
279To use this library with [Azure OpenAI](https://learn.microsoft.com/azure/ai-services/openai/overview), use the same
280OpenAI client builder but with the Azure-specific configuration.
281
282```java
283OpenAIOkHttpClient.Builder clientBuilder = OpenAIOkHttpClient.builder();
284
285/* Azure-specific code starts here */
286// You can either set 'endpoint' directly in the builder.
287// or set the env var "AZURE_OPENAI_ENDPOINT" and use fromEnv() method instead
288clientBuilder
289 .baseUrl(System.getenv("AZURE_OPENAI_ENDPOINT"))
290 .credential(BearerTokenCredential.create(
291 AuthenticationUtil.getBearerTokenSupplier(
292 new DefaultAzureCredentialBuilder().build(), "https://cognitiveservices.azure.com/.default")
293 ));
294/* Azure-specific code ends here */
295
296OpenAIClient client = clientBuilder.build();
297
298ChatCompletionCreateParams params = ChatCompletionCreateParams.builder()
299 .addMessage(ChatCompletionMessageParam.ofChatCompletionUserMessageParam(
300 ChatCompletionUserMessageParam.builder()
301 .role(ChatCompletionUserMessageParam.Role.USER)
302 .content(ChatCompletionUserMessageParam.Content.ofTextContent("Who won the world series in 2020?"))
303 .build()))
304 .model("gpt-4o")
305 .build();
306
307ChatCompletion chatCompletion = client.chat().completions().create(params);
308
309List<ChatCompletion.Choice> choices = chatCompletion.choices();
310for (ChatCompletion.Choice choice : choices) {
311 System.out.println("Choice content: " + choice.message().content().get());
312}
313```
314
315See the complete Azure OpenAI examples in the [Azure OpenAI example](https://github.com/openai/openai-java/tree/next/openai-azure-java-example/src/main/java/com.openai.azure.examples).
316
317## Network options
318
319### Retries
320
321Requests that experience certain errors are automatically retried 2 times by default, with a short exponential backoff. Connection errors (for example, due to a network connectivity problem), 408 Request Timeout, 409 Conflict, 429 Rate Limit, and >=500 Internal errors will all be retried by default.
322You can provide a `maxRetries` on the client builder to configure this:
323
324```java
325OpenAIClient client = OpenAIOkHttpClient.builder()
326 .fromEnv()
327 .maxRetries(4)
328 .build();
329```
330
331### Timeouts
332
333Requests time out after 10 minutes by default. You can configure this on the client builder:
334
335```java
336OpenAIClient client = OpenAIOkHttpClient.builder()
337 .fromEnv()
338 .timeout(Duration.ofSeconds(30))
339 .build();
340```
341
342### Proxies
343
344Requests can be routed through a proxy. You can configure this on the client builder:
345
346```java
347OpenAIClient client = OpenAIOkHttpClient.builder()
348 .fromEnv()
349 .proxy(new Proxy(
350 Type.HTTP,
351 new InetSocketAddress("proxy.com", 8080)
352 ))
353 .build();
354```
355
356## Making custom/undocumented requests
357
358This library is typed for convenient access to the documented API. If you need to access undocumented
359params or response properties, the library can still be used.
360
361### Undocumented request params
362
363To make requests using undocumented parameters, you can provide or override parameters on the params object
364while building it.
365
366```kotlin
367FooCreateParams address = FooCreateParams.builder()
368 .id("my_id")
369 .putAdditionalProperty("secret_prop", JsonValue.from("hello"))
370 .build();
371```
372
373### Undocumented response properties
374
375To access undocumented response properties, you can use `res._additionalProperties()` on a response object to
376get a map of untyped fields of type `Map<String, JsonValue>`. You can then access fields like
377`._additionalProperties().get("secret_prop").asString()` or use other helpers defined on the `JsonValue` class
378to extract it to a desired type.
379
380## Logging
381
382We use the standard [OkHttp logging interceptor](https://github.com/square/okhttp/tree/master/okhttp-logging-interceptor).
383
384You can enable logging by setting the environment variable `OPENAI_LOG` to `info`.
385
386```sh
387$ export OPENAI_LOG=info
388```
389
390Or to `debug` for more verbose logging.
391
392```sh
393$ export OPENAI_LOG=debug
394```
395
396## Semantic versioning
397
398This package generally follows [SemVer](https://semver.org/spec/v2.0.0.html) conventions, though certain backwards-incompatible changes may be released as minor versions:
399
4001. Changes to library internals which are technically public but not intended or documented for external use. _(Please open a GitHub issue to let us know if you are relying on such internals)_.
4012. Changes that we do not expect to impact the vast majority of users in practice.
402
403We take backwards-compatibility seriously and work hard to ensure you can rely on a smooth upgrade experience.
404
405We are keen for your feedback; please open an [issue](https://www.github.com/openai/openai-java/issues) with questions, bugs, or suggestions.
406
407## Requirements
408
409This library requires Java 8 or later.