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
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
* @author Stefan Vassilev
* @author Thomas Vitale
* @author Ilayaperumal Gopinathan
* @author lambochen
*/
@AutoConfiguration(after = { RestClientAutoConfiguration.class, WebClientAutoConfiguration.class,
SpringAiRetryAutoConfiguration.class })
Expand All @@ -75,6 +76,7 @@ public OpenAiImageModel openAiImageModel(OpenAiConnectionProperties commonProper
.baseUrl(resolved.baseUrl())
.apiKey(new SimpleApiKey(resolved.apiKey()))
.headers(resolved.headers())
.imagesPath(imageProperties.getImagesPath())
.restClientBuilder(restClientBuilderProvider.getIfAvailable(RestClient::builder))
.responseErrorHandler(responseErrorHandler)
.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,18 @@
* OpenAI Image autoconfiguration properties.
*
* @author Thomas Vitale
* @author lambochen
* @since 0.8.0
*/
@ConfigurationProperties(OpenAiImageProperties.CONFIG_PREFIX)
public class OpenAiImageProperties extends OpenAiParentProperties {

public static final String CONFIG_PREFIX = "spring.ai.openai.image";

public static final String DEFAULT_IMAGES_PATH = "v1/images/generations";

private String imagesPath = DEFAULT_IMAGES_PATH;

public static final String DEFAULT_IMAGE_MODEL = OpenAiImageApi.ImageModel.DALL_E_3.getValue();

/**
Expand All @@ -48,4 +53,12 @@ public void setOptions(OpenAiImageOptions options) {
this.options = options;
}

public String getImagesPath() {
return imagesPath;
}

public void setImagesPath(String imagesPath) {
this.imagesPath = imagesPath;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -39,22 +39,26 @@
* OpenAI Image API.
*
* @see <a href= "https://platform.openai.com/docs/api-reference/images">Images</a>
* @author lambochen
*/
public class OpenAiImageApi {

public static final String DEFAULT_IMAGE_MODEL = ImageModel.DALL_E_3.getValue();

private final RestClient restClient;

private final String imagesPath;

/**
* Create a new OpenAI Image API with the provided base URL.
* @param baseUrl the base URL for the OpenAI API.
* @param apiKey OpenAI apiKey.
* @param headers the http headers to use.
* @param imagesPath the images path to use.
* @param restClientBuilder the rest client builder to use.
* @param responseErrorHandler the response error handler to use.
*/
public OpenAiImageApi(String baseUrl, ApiKey apiKey, MultiValueMap<String, String> headers,
public OpenAiImageApi(String baseUrl, ApiKey apiKey, MultiValueMap<String, String> headers, String imagesPath,
RestClient.Builder restClientBuilder, ResponseErrorHandler responseErrorHandler) {

// @formatter:off
Expand All @@ -69,14 +73,16 @@ public OpenAiImageApi(String baseUrl, ApiKey apiKey, MultiValueMap<String, Strin
.defaultStatusHandler(responseErrorHandler)
.build();
// @formatter:on

this.imagesPath = imagesPath;
}

public ResponseEntity<OpenAiImageResponse> createImage(OpenAiImageRequest openAiImageRequest) {
Assert.notNull(openAiImageRequest, "Image request cannot be null.");
Assert.hasLength(openAiImageRequest.prompt(), "Prompt cannot be empty.");

return this.restClient.post()
.uri("v1/images/generations")
.uri(this.imagesPath)
.body(openAiImageRequest)
.retrieve()
.toEntity(OpenAiImageResponse.class);
Expand Down Expand Up @@ -163,12 +169,20 @@ public static class Builder {

private ResponseErrorHandler responseErrorHandler = RetryUtils.DEFAULT_RESPONSE_ERROR_HANDLER;

private String imagesPath = "v1/images/generations";

public Builder baseUrl(String baseUrl) {
Assert.hasText(baseUrl, "baseUrl cannot be null or empty");
this.baseUrl = baseUrl;
return this;
}

public Builder imagesPath(String imagesPath) {
Assert.hasText(imagesPath, "imagesPath cannot be null or empty");
this.imagesPath = imagesPath;
return this;
}

public Builder apiKey(ApiKey apiKey) {
Assert.notNull(apiKey, "apiKey cannot be null");
this.apiKey = apiKey;
Expand Down Expand Up @@ -201,7 +215,7 @@ public Builder responseErrorHandler(ResponseErrorHandler responseErrorHandler) {

public OpenAiImageApi build() {
Assert.notNull(this.apiKey, "apiKey must be set");
return new OpenAiImageApi(this.baseUrl, this.apiKey, this.headers, this.restClientBuilder,
return new OpenAiImageApi(this.baseUrl, this.apiKey, this.headers, this.imagesPath, this.restClientBuilder,
this.responseErrorHandler);
}

Expand Down