Skip to content

Commit b936a9c

Browse files
paulbakkerilayaperumalg
authored andcommitted
Possible fix for issue #2218, allowing to disable setting the Authorization header.
Signed-off-by: pbakker <pbakker@netflix.com>
1 parent 0d0eafe commit b936a9c

File tree

5 files changed

+55
-7
lines changed

5 files changed

+55
-7
lines changed

models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiApi.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import org.springframework.ai.model.ApiKey;
3535
import org.springframework.ai.model.ChatModelDescription;
3636
import org.springframework.ai.model.ModelOptionsUtils;
37+
import org.springframework.ai.model.NoopApiKey;
3738
import org.springframework.ai.model.SimpleApiKey;
3839
import org.springframework.ai.openai.api.common.OpenAiApiConstants;
3940
import org.springframework.ai.retry.RetryUtils;
@@ -200,7 +201,10 @@ public OpenAiApi(String baseUrl, ApiKey apiKey, MultiValueMap<String, String> he
200201
this.embeddingsPath = embeddingsPath;
201202
// @formatter:off
202203
Consumer<HttpHeaders> finalHeaders = h -> {
203-
h.setBearerAuth(apiKey.getValue());
204+
if(!(apiKey instanceof NoopApiKey)) {
205+
h.setBearerAuth(apiKey.getValue());
206+
}
207+
204208
h.setContentType(MediaType.APPLICATION_JSON);
205209
h.addAll(headers);
206210
};

models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiAudioApi.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,14 @@ public OpenAiAudioApi(String openAiToken) {
7272
public OpenAiAudioApi(String baseUrl, String openAiToken, RestClient.Builder restClientBuilder,
7373
ResponseErrorHandler responseErrorHandler) {
7474

75-
Consumer<HttpHeaders> authHeaders = h -> h.setBearerAuth(openAiToken);
75+
Consumer<HttpHeaders> authHeaders;
76+
if (openAiToken != null && !openAiToken.isEmpty()) {
77+
authHeaders = h -> h.setBearerAuth(openAiToken);
78+
}
79+
else {
80+
authHeaders = h -> {
81+
};
82+
}
7683

7784
this.restClient = restClientBuilder.baseUrl(baseUrl)
7885
.defaultHeaders(authHeaders)
@@ -111,7 +118,9 @@ public OpenAiAudioApi(String baseUrl, String apiKey, MultiValueMap<String, Strin
111118
ResponseErrorHandler responseErrorHandler) {
112119

113120
Consumer<HttpHeaders> authHeaders = h -> {
114-
h.setBearerAuth(apiKey);
121+
if (apiKey != null && !apiKey.isEmpty()) {
122+
h.setBearerAuth(apiKey);
123+
}
115124
h.addAll(headers);
116125
// h.setContentType(MediaType.APPLICATION_JSON);
117126
};
@@ -135,7 +144,7 @@ public ResponseEntity<byte[]> createSpeech(SpeechRequest requestBody) {
135144

136145
/**
137146
* Streams audio generated from the input text.
138-
*
147+
* <p>
139148
* This method sends a POST request to the OpenAI API to generate audio from the
140149
* provided text. The audio is streamed back as a Flux of ResponseEntity objects, each
141150
* containing a byte array of the audio data.

models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiImageApi.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,9 @@ public OpenAiImageApi(String baseUrl, String apiKey, MultiValueMap<String, Strin
8787
// @formatter:off
8888
this.restClient = restClientBuilder.baseUrl(baseUrl)
8989
.defaultHeaders(h -> {
90-
h.setBearerAuth(apiKey);
90+
if(apiKey != null && !apiKey.isEmpty()) {
91+
h.setBearerAuth(apiKey);
92+
}
9193
h.setContentType(MediaType.APPLICATION_JSON);
9294
h.addAll(headers);
9395
})

models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiModerationApi.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import com.fasterxml.jackson.annotation.JsonProperty;
2121
import com.fasterxml.jackson.databind.DeserializationFeature;
2222
import com.fasterxml.jackson.databind.ObjectMapper;
23-
2423
import org.springframework.ai.retry.RetryUtils;
2524
import org.springframework.http.MediaType;
2625
import org.springframework.http.ResponseEntity;
@@ -59,7 +58,9 @@ public OpenAiModerationApi(String baseUrl, String openAiToken, RestClient.Builde
5958
this.objectMapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
6059

6160
this.restClient = restClientBuilder.baseUrl(baseUrl).defaultHeaders(h -> {
62-
h.setBearerAuth(openAiToken);
61+
if (openAiToken != null && !openAiToken.isEmpty()) {
62+
h.setBearerAuth(openAiToken);
63+
}
6364
h.setContentType(MediaType.APPLICATION_JSON);
6465
}).defaultStatusHandler(responseErrorHandler).build();
6566
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright 2025-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.ai.model;
18+
19+
/**
20+
* This implementation of ApiKey indicates that no API key should be used, e.g. no HTTP
21+
* headers should be set.
22+
*
23+
* @author Paul Bakker
24+
*/
25+
public class NoopApiKey implements ApiKey {
26+
27+
@Override
28+
public String getValue() {
29+
return "";
30+
}
31+
32+
}

0 commit comments

Comments
 (0)