Генерация изображений на основе искусственного интеллекта с помощью Quarkus и OpenAI DALL.E
В этой статье мы рассмотрим, как интегрировать OpenAI API с Quarkus. Мы создадим приложение Quarkus, используя новый REST-клиент Reactive для вызова API OpenAI DALL.E.
Обзор API OpenAI
Прежде чем перейти к коду, давайте рассмотрим API OpenAI Create Image (создание изображений) и принцип его работы.
Создание запроса на изображение
Тело запроса состоит из следующих параметров:
prompt
: единственным обязательным параметром является описание желаемого изображения (не более 1000 символов)n
: количество желаемых изображений (от 1 до 10)size
: размер генерируемого изображения (по умолчанию 1024x1024, допускаются также 256x256, 512x512)
другими параметрами являются:
response_format
: для указания формата изображения ответа (по умолчанию url, также допускается b64_json)user
: идентификатор для отслеживания действий пользователя
Для аутентификации в API мы сгенерируем API-ключ. Этот ключ мы зададим в заголовке Authorization при вызове API.
Приведём пример запроса API:
curl https://api.openai.com/v1/images/generations \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI\_API\_KEY" \
-d '{
"prompt": "A cute baby sea otter",
"n": 2,
"size": "1024x1024"
}'
Создание ответного изображения
Ответ будет представлять собой JSON-объект с полями created
и data
. Поле data
будет представлять собой массив объектов. Каждый объект будет содержать поле url
, содержащее ответ на запрос.
Количество объектов в массиве данных будет равно опциональному параметру n
в запросе. Если параметр n
не указан, то массив данных будет содержать один объект.
Ниже приведён пример ответа API:
{
"created": 1589478378,
"data": [
{
"url": "https://..."
},
{
"url": "https://..."
}
]
}
Настройка приложения Quarkus
Чтобы запустить наше приложение, перейдите на сайт https://code.quarkus.io и настройте его, выбрав следующие расширения:
- RESTEasy Reactive Jackson
- RESTEasy Reactive
- REST Client Reactive
- REST Client Reactive Jackson
Или с помощью maven
командой:
mvn io.quarkus.platform:quarkus-maven-plugin:3.2.3.Final:create \
-DprojectGroupId=com.foojay.openai \
-DprojectArtifactId=quarkus-openai-app \
-Dextensions='resteasy-reactive-jackson,rest-client-reactive-jackson,resteasy-reactive' \
-DnoCode
После создания проекта добавьте в файл application.properties
свой ключ OpenAI API с помощью следующей строки.
# OpenAI properties
openai.api.key=$OPENAI_API_KEY
Модель
Теперь, отталкиваясь от того, что мы видели ранее, создадим класс для моделирования тела API-запроса на получение изображений от OpenAI Image Generation API:
public class CreateImageRequest {
@JsonProperty("prompt")
private String prompt;
@JsonProperty("n")
private int n;
@JsonProperty("size")
private String size;
public CreateImageRequest() {
}
public String getPrompt() {
return prompt;
}
public void setPrompt(String prompt) {
this.prompt = prompt;
}
public int getN() {
return n;
}
public void setN(int n) {
this.n = n;
}
public String getSize() {
return size;
}
public void setSize(String size) {
this.size = size;
}
}
Определим класс API-ответа:
public class CreateImageResponse {
@JsonProperty("created")
private Integer created;
@JsonProperty("data")
private List<Item> urls;
public List<Item> getUrls() {
return urls;
}
public void setUrls(List<Item> urls) {
this.urls = urls;
}
public Integer getCreated() {
return created;
}
public void setCreated(Integer created) {
this.created = created;
}
}
И, наконец, класс Item
public class Item {
@JsonProperty("url")
private String url;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}
REST-клиент
Для вызова API OpenAI мы определяем наш REST-клиент с помощью нового REST Client Reactive, который позволяет декларативно определить вызываемый API с помощью новых аннотаций Jakarta EE и Microprofile.
@RegisterRestClient(baseUri = "https://api.openai.com")
@Path("/v1")
public interface OpenAIRestClient {
@GET
@Path("/models")
@ClientHeaderParam(name = "Authorization", value = "Bearer ${openai.api.key}")
ModelResponse getModels();
@POST
@Path("/images/generations")
@ClientHeaderParam(name = "Authorization", value = "Bearer ${openai.api.key}")
CreateImageResponse generateImage(CreateImageRequest createImageRequest);
}
Свойство @RegisterRestClient
позволяет Quarkus узнать, что данный интерфейс должен быть доступен для инъекции CDI в качестве REST-клиента, свойства baseUri
определяют url, на который указывает клиент. Свойства @Path
, @POST
являются стандартными аннотациями Jakarta REST, определяющими способ доступа к API.
Для управления API-авторизацией, как мы уже видели, необходимо передать ключ API в заголовке запроса. Для этого в нашем клиенте мы используем @ClientHeaderParam
, передавая имя и значение записей. В данном случае мы читаем ключ из application.properties
, используя обозначение ${opena.ai.key}
, которое позволяет подставлять значение свойства напрямую.v
Тестирование клиента
Для тестирования нашего клиента давайте определим REST-ресурс, который мы будем вызывать из браузера.
@Path("/quarkus-openai")
public class OpenAIEndpoint {
@RestClient
private OpenAIRestClient openAIRestClient;
@GET
@Path("/generate-image")
@Produces(MediaType.APPLICATION_JSON)
public Response generateImage(@QueryParam("description") String description,
@DefaultValue("1") @QueryParam("n") int n,
@DefaultValue("1024x1024") @QueryParam("size") String size) {
final CreateImageRequest createImageRequest = new CreateImageRequest();
createImageRequest.setPrompt(description);
createImageRequest.setN(n);
createImageRequest.setSize(size);
URI uri;
try {
uri = new URI(
openAIRestClient.generateImage(createImageRequest).getUrls().get(0).getUrl());
} catch (URISyntaxException e) {
return Response.noContent().build();
}
return Response.seeOther(uri).build();
}
}
Мы определяем OpenAIEndpoint
и инжектируем REST-клиент с помощью аннотации @RestClient
. Затем мы создаем API generateImage
, который принимает запрос и, опционально, количество изображений и их размер.
Внутри метода мы формируем запрос и передаем его нашему клиенту, вызывая метод generateImage
, получаем результат и выполняем перенаправление на первый URL из полученного ответа.
Чтобы увидеть результат, запустим наш проект командой:
quarkus dev
и направляем браузер на этот пример url, передавая наш запрос в качестве значения параметров описания.
Попробуйте использовать другие варианты и наслаждайтесь результатами.
Заключение
В этой статье мы рассмотрели, как использовать API OpenAI DALL.E для генерации изображений из подсказок. Мы создали приложение Quarkus, вызывающее API с помощью нового REST-клиента Reactive и управляющее результатом.
Примеры кода для данного руководства доступны на GitHub.