使用Quarkus和Openai Dall.E生成基于AI的图像
#openai #java #quarkus

(最初在https://foojay.io/today/images-generation-with-quarkus-and-openai/上出版)

介绍

在本文中,我们探讨了如何将OpenAI API与Quarkus集成。我们将使用新的REST客户端反应式创建一个Quarkus应用程序,以调用OpenAi dall.e API

OpenAI API概述

跳入代码之前,让我们探索Openai Create Image API及其工作原理。

创建图像请求

主体请求是由以下参数制成的:

  • 提示:唯一必需的参数是所需图像(最大1000个字符)的描述
  • n :所需图像的数量(从1到10)
  • size :生成图像的大小(默认的1024x1024,也录取了256x256,512x512)

其他参数为:

  • Response_format :指定响应映像格式(默认URL,也录取了B64_JSON)
  • 用户:跟踪用户活动的标识符。

要使用API​​进行身份验证,我们将生成一个API key。调用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"
}'

创建图像响应

响应将是具有创建 data field的JSON对象。每个对象将具有包含对提示的响应的字段。

data array中的对象数将等于请求中的可选 n '。未指定, data narray将包含一个对象。

这是样本API响应:

{
"created": 1589478378,
"data": [
   {
      "url": "https://..."
   },
   {
      "url": "https://..."
   }
]
}

设置Quarkus应用程序

要启动我们的应用程序,请转到https://code.quarkus.io并通过选择以下扩展名来配置它:

  • reteasy反应性杰克逊
  • reteasy反应性
  • 休息客户反应
  • 休息客户反应式杰克逊

或使用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

该模型

现在从我们以前看到的开始,我们创建一个类,以建模OpenAI Image Generation API的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 class

public class Item {
    @JsonProperty("url")
    private String url;

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }
}

休息客户

为了调用OpenAI API,我们使用新的REST客户端反应式定义了我们的REST客户端,该端允许使用新的Jakarta EE和MicroproFile注释来定义API的声明性方法。


@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是标准的雅加达休息注释,定义了如何访问API。

要管理API AUTH,如我们之前所见,我们需要在请求的标题内传递API键。为了在我们的客户端中执行此操作,我们使用@ClientHeaderParam传递名称和条目的值。在这种情况下,我们使用符号 $ {opena.ai.key} 读取 application.properties 的键,该键可以直接注入属性的值。

测试客户

要测试我们的客户端,让\'定义一个我们将从浏览器调用的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();
    }
}

我们使用@RestClient注释来定义OpenAIEndpoint并注入REST客户端。然后,我们创建接受提示的API generateImage,并可选地使用图像数及其大小。

在方法内,我们构建请求并将其传递给客户;调用方法generateImage,我们得到结果,然后重定向到响应有效载荷的第一个URL。

查看结果让我们的项目从命令开始:

quarkus dev

并将浏览器指向此示例URL将我们的提示传递为 description 参数的值:

http://localhost:8080/quarkus-openai/generate-image?description=a%20photo%20of%20a%20happy%20corgi%20puppy%20sitting%20and%20facing%20forward,%20studio%20light,%20longshot

尝试其他提示并享受结果。

结论

本文我们探讨了如何使用OpenAi dall.e API从提示中生成图像。我们创建了一个Quarkus应用程序,该应用程序使用新的REST客户端进行反应调用API并管理结果。

本教程的代码示例可在GitHub中找到。

参考