Skip to content
This repository was archived by the owner on Feb 11, 2025. It is now read-only.

Commit cc1f179

Browse files
author
deep-learning-dynamo
committed
Added an option to specify openAiApiKey and azureApiKey independently
1 parent bb3eac4 commit cc1f179

15 files changed

+108
-36
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package dev.ai4j.openai4j;
2+
3+
import okhttp3.Interceptor;
4+
import okhttp3.Request;
5+
import okhttp3.Response;
6+
7+
import java.io.IOException;
8+
9+
class ApiKeyHeaderInjector implements Interceptor {
10+
11+
private final String apiKey;
12+
13+
ApiKeyHeaderInjector(String apiKey) {
14+
this.apiKey = apiKey;
15+
}
16+
17+
@Override
18+
public Response intercept(Chain chain) throws IOException {
19+
20+
Request request = chain.request()
21+
.newBuilder()
22+
.addHeader("api-key", apiKey)
23+
.build();
24+
25+
return chain.proceed(request);
26+
}
27+
}

src/main/java/dev/ai4j/openai4j/ApiKeyInsertingInterceptor.java renamed to src/main/java/dev/ai4j/openai4j/AuthorizationHeaderInjector.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@
66

77
import java.io.IOException;
88

9-
class ApiKeyInsertingInterceptor implements Interceptor {
9+
class AuthorizationHeaderInjector implements Interceptor {
1010

1111
private final String apiKey;
1212

13-
ApiKeyInsertingInterceptor(String apiKey) {
13+
AuthorizationHeaderInjector(String apiKey) {
1414
this.apiKey = apiKey;
1515
}
1616

src/main/java/dev/ai4j/openai4j/OpenAiClient.java

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public class OpenAiClient {
3535
private final boolean logStreamingResponses;
3636

3737
public OpenAiClient(String apiKey) {
38-
this(builder().apiKey(apiKey));
38+
this(builder().openAiApiKey(apiKey));
3939
}
4040

4141
private OpenAiClient(Builder serviceBuilder) {
@@ -44,21 +44,32 @@ private OpenAiClient(Builder serviceBuilder) {
4444
this.apiVersion = serviceBuilder.apiVersion;
4545

4646
OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient.Builder()
47-
.addInterceptor(new ApiKeyInsertingInterceptor(serviceBuilder.apiKey))
4847
.callTimeout(serviceBuilder.callTimeout)
4948
.connectTimeout(serviceBuilder.connectTimeout)
5049
.readTimeout(serviceBuilder.readTimeout)
5150
.writeTimeout(serviceBuilder.writeTimeout);
5251

52+
if (serviceBuilder.openAiApiKey == null && serviceBuilder.azureApiKey == null) {
53+
throw new IllegalArgumentException("openAiApiKey OR azureApiKey must be defined");
54+
}
55+
if (serviceBuilder.openAiApiKey != null && serviceBuilder.azureApiKey != null) {
56+
throw new IllegalArgumentException("openAiApiKey AND azureApiKey cannot both be defined at the same time");
57+
}
58+
if (serviceBuilder.openAiApiKey != null) {
59+
okHttpClientBuilder.addInterceptor(new AuthorizationHeaderInjector(serviceBuilder.openAiApiKey));
60+
} else {
61+
okHttpClientBuilder.addInterceptor(new ApiKeyHeaderInjector(serviceBuilder.azureApiKey));
62+
}
63+
5364
if (serviceBuilder.proxy != null) {
54-
okHttpClientBuilder = okHttpClientBuilder.proxy(serviceBuilder.proxy);
65+
okHttpClientBuilder.proxy(serviceBuilder.proxy);
5566
}
5667

5768
if (serviceBuilder.logRequests) {
58-
okHttpClientBuilder = okHttpClientBuilder.addInterceptor(new RequestLoggingInterceptor());
69+
okHttpClientBuilder.addInterceptor(new RequestLoggingInterceptor());
5970
}
6071
if (serviceBuilder.logResponses) {
61-
okHttpClientBuilder = okHttpClientBuilder.addInterceptor(new ResponseLoggingInterceptor());
72+
okHttpClientBuilder.addInterceptor(new ResponseLoggingInterceptor());
6273
}
6374
this.logStreamingResponses = serviceBuilder.logStreamingResponses;
6475

@@ -97,7 +108,8 @@ public static class Builder {
97108

98109
private String baseUrl = "https://api.openai.com/v1/";
99110
private String apiVersion;
100-
private String apiKey;
111+
private String openAiApiKey;
112+
private String azureApiKey;
101113
private Duration callTimeout = Duration.ofSeconds(60);
102114
private Duration connectTimeout = Duration.ofSeconds(60);
103115
private Duration readTimeout = Duration.ofSeconds(60);
@@ -133,11 +145,29 @@ public Builder apiVersion(String apiVersion) {
133145
return this;
134146
}
135147

136-
public Builder apiKey(String apiKey) {
137-
if (apiKey == null || apiKey.trim().isEmpty()) {
138-
throw new IllegalArgumentException("API key cannot be null or empty. API keys can be generated here: https://platform.openai.com/account/api-keys");
148+
/**
149+
* @param openAiApiKey OpenAI API key.
150+
* Will be injected in HTTP headers like this: "Authorization: Bearer ${openAiApiKey}"
151+
* @return builder
152+
*/
153+
public Builder openAiApiKey(String openAiApiKey) {
154+
if (openAiApiKey == null || openAiApiKey.trim().isEmpty()) {
155+
throw new IllegalArgumentException("openAiApiKey cannot be null or empty. API keys can be generated here: https://platform.openai.com/account/api-keys");
156+
}
157+
this.openAiApiKey = openAiApiKey;
158+
return this;
159+
}
160+
161+
/**
162+
* @param azureApiKey Azure API key.
163+
* Will be injected in HTTP headers like this: "api-key: ${azureApiKey}"
164+
* @return builder
165+
*/
166+
public Builder azureApiKey(String azureApiKey) {
167+
if (azureApiKey == null || azureApiKey.trim().isEmpty()) {
168+
throw new IllegalArgumentException("azureApiKey cannot be null or empty");
139169
}
140-
this.apiKey = apiKey;
170+
this.azureApiKey = azureApiKey;
141171
return this;
142172
}
143173

src/main/java/dev/ai4j/openai4j/RequestLoggingInterceptor.java

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,18 +50,20 @@ static String inOneLine(Headers headers) {
5050
.map(header -> {
5151
String headerKey = header.component1();
5252
String headerValue = header.component2();
53-
if (headerKey.contains("Authorization")) {
54-
headerValue = maskApiToken(headerValue);
53+
if (headerKey.equals("Authorization")) {
54+
headerValue = maskAuthorizationHeaderValue(headerValue);
55+
} else if (headerKey.equals("api-key")) {
56+
headerValue = maskApiKeyHeaderValue(headerValue);
5557
}
5658
return String.format("[%s: %s]", headerKey, headerValue);
5759
})
5860
.collect(joining(", "));
5961
}
6062

61-
private static String maskApiToken(String request) {
63+
private static String maskAuthorizationHeaderValue(String authorizationHeaderValue) {
6264
try {
6365

64-
Matcher matcher = BEARER_PATTERN.matcher(request);
66+
Matcher matcher = BEARER_PATTERN.matcher(authorizationHeaderValue);
6567

6668
StringBuffer sb = new StringBuffer();
6769
while (matcher.find()) {
@@ -71,7 +73,20 @@ private static String maskApiToken(String request) {
7173

7274
return sb.toString();
7375
} catch (Exception e) {
74-
return "Failed to mask the API key. Therefore, avoid logging the entire request.";
76+
return "Failed to mask the API key.";
77+
}
78+
}
79+
80+
private static String maskApiKeyHeaderValue(String apiKeyHeaderValue) {
81+
try {
82+
if (apiKeyHeaderValue.length() <= 4) {
83+
return apiKeyHeaderValue;
84+
}
85+
return apiKeyHeaderValue.substring(0, 2)
86+
+ "..."
87+
+ apiKeyHeaderValue.substring(apiKeyHeaderValue.length() - 2);
88+
} catch (Exception e) {
89+
return "Failed to mask the API key.";
7590
}
7691
}
7792

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
package dev.ai4j.openai4j;
22

3-
import dev.ai4j.openai4j.completion.CompletionRequest;
3+
import dev.ai4j.openai4j.chat.ChatCompletionRequest;
44

5-
import static java.net.Proxy.Type.HTTP;
65
import static java.time.Duration.ofSeconds;
76

87
public class Test {
@@ -12,23 +11,24 @@ public static void main(String[] args) {
1211
String apiKey = System.getenv("OPENAI_API_KEY");
1312

1413
OpenAiClient client = OpenAiClient.builder()
15-
.baseUrl("https://my-resource.openai.azure.com/openai/deployments/my-deployment/")
16-
.apiVersion("2023-06-13")
17-
.apiKey(apiKey)
14+
.openAiApiKey(apiKey)
15+
// .baseUrl("https://resource-name.openai.azure.com/openai/deployments/deployment-id/")
16+
// .apiVersion("2023-05-15")
17+
// .azureApiKey("...")
1818
.callTimeout(ofSeconds(60))
1919
.connectTimeout(ofSeconds(60))
2020
.readTimeout(ofSeconds(60))
2121
.writeTimeout(ofSeconds(60))
22-
.proxy(HTTP, "103.154.230.129", 8080)
22+
// .proxy(HTTP, "103.154.230.129", 8080)
2323
.logRequests()
2424
.logResponses()
2525
.logStreamingResponses()
2626
.build();
2727

28-
CompletionRequest request = CompletionRequest.builder()
29-
.prompt("hello")
28+
ChatCompletionRequest request = ChatCompletionRequest.builder()
29+
.addUserMessage("hello")
3030
.build();
3131

32-
System.out.println(client.completion(request).execute().text());
32+
System.out.println(client.chatCompletion(request).execute().content());
3333
}
3434
}

src/test/java/dev/ai4j/openai4j/chat/ChatCompletionAsyncTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ class ChatCompletionAsyncTest extends RateLimitAwareTest {
2323
private static final String USER_MESSAGE = "write exactly the following 2 words: 'hello world'";
2424

2525
private final OpenAiClient client = OpenAiClient.builder()
26-
.apiKey(System.getenv("OPENAI_API_KEY"))
26+
.openAiApiKey(System.getenv("OPENAI_API_KEY"))
2727
.logRequests()
2828
.logResponses()
2929
.build();

src/test/java/dev/ai4j/openai4j/chat/ChatCompletionStreamingTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class ChatCompletionStreamingTest extends RateLimitAwareTest {
2121
private static final String USER_MESSAGE = "write exactly the following 2 words: 'hello world'";
2222

2323
private final OpenAiClient client = OpenAiClient.builder()
24-
.apiKey(System.getenv("OPENAI_API_KEY"))
24+
.openAiApiKey(System.getenv("OPENAI_API_KEY"))
2525
.logRequests()
2626
.logResponses()
2727
.logStreamingResponses()

src/test/java/dev/ai4j/openai4j/chat/ChatCompletionTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class ChatCompletionTest extends RateLimitAwareTest {
2222
private static final String USER_MESSAGE = "Write exactly the following 2 words: 'hello world'";
2323

2424
private final OpenAiClient client = OpenAiClient.builder()
25-
.apiKey(System.getenv("OPENAI_API_KEY"))
25+
.openAiApiKey(System.getenv("OPENAI_API_KEY"))
2626
.logRequests()
2727
.logResponses()
2828
.build();

src/test/java/dev/ai4j/openai4j/completion/CompletionAsyncTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class CompletionAsyncTest extends RateLimitAwareTest {
1414
private static final String PROMPT = "write exactly the following 2 words: 'hello world'";
1515

1616
private final OpenAiClient client = OpenAiClient.builder()
17-
.apiKey(System.getenv("OPENAI_API_KEY"))
17+
.openAiApiKey(System.getenv("OPENAI_API_KEY"))
1818
.logRequests()
1919
.logResponses()
2020
.build();

src/test/java/dev/ai4j/openai4j/completion/CompletionStreamingTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class CompletionStreamingTest extends RateLimitAwareTest {
1414
private static final String PROMPT = "write exactly the following 2 words: 'hello world'";
1515

1616
private final OpenAiClient client = OpenAiClient.builder()
17-
.apiKey(System.getenv("OPENAI_API_KEY"))
17+
.openAiApiKey(System.getenv("OPENAI_API_KEY"))
1818
.logRequests()
1919
.logResponses()
2020
.logStreamingResponses()

0 commit comments

Comments
 (0)