async_openai/
image.rs

1use crate::{
2    config::Config,
3    error::OpenAIError,
4    types::images::{
5        CreateImageEditRequest, CreateImageRequest, CreateImageVariationRequest, ImageEditStream,
6        ImageGenStream, ImagesResponse,
7    },
8    Client,
9};
10
11/// Given a prompt and/or an input image, the model will generate a new image.
12///
13/// Related guide: [Image generation](https://platform.openai.com/docs/guides/images)
14pub struct Images<'c, C: Config> {
15    client: &'c Client<C>,
16}
17
18impl<'c, C: Config> Images<'c, C> {
19    pub fn new(client: &'c Client<C>) -> Self {
20        Self { client }
21    }
22
23    /// Creates an image given a prompt.
24    #[crate::byot(T0 = serde::Serialize, R = serde::de::DeserializeOwned)]
25    pub async fn generate(
26        &self,
27        request: CreateImageRequest,
28    ) -> Result<ImagesResponse, OpenAIError> {
29        self.client.post("/images/generations", request).await
30    }
31
32    /// Creates an image given a prompt.
33    #[crate::byot(
34        T0 = serde::Serialize,
35        R = serde::de::DeserializeOwned,
36        stream = "true",
37        where_clause = "R: std::marker::Send + 'static"
38    )]
39    #[allow(unused_mut)]
40    pub async fn generate_stream(
41        &self,
42        mut request: CreateImageRequest,
43    ) -> Result<ImageGenStream, OpenAIError> {
44        #[cfg(not(feature = "byot"))]
45        {
46            if request.stream.is_some() && !request.stream.unwrap() {
47                return Err(OpenAIError::InvalidArgument(
48                    "When stream is false, use Image::generate".into(),
49                ));
50            }
51
52            request.stream = Some(true);
53        }
54
55        Ok(self
56            .client
57            .post_stream("/images/generations", request)
58            .await)
59    }
60
61    /// Creates an edited or extended image given one or more source images and a prompt.
62    /// This endpoint only supports gpt-image-1 and dall-e-2.
63    #[crate::byot(
64        T0 = Clone,
65        R = serde::de::DeserializeOwned,
66        where_clause =  "reqwest::multipart::Form: crate::traits::AsyncTryFrom<T0, Error = OpenAIError>",
67    )]
68    pub async fn edit(
69        &self,
70        request: CreateImageEditRequest,
71    ) -> Result<ImagesResponse, OpenAIError> {
72        self.client.post_form("/images/edits", request).await
73    }
74
75    /// Creates an edited or extended image given one or more source images and a prompt.
76    /// This endpoint only supports gpt-image-1 and dall-e-2.
77    #[crate::byot(
78        T0 = Clone,
79        R = serde::de::DeserializeOwned,
80        stream = "true",
81        where_clause = "R: std::marker::Send + 'static, reqwest::multipart::Form: crate::traits::AsyncTryFrom<T0, Error = OpenAIError>"
82    )]
83    #[allow(unused_mut)]
84    pub async fn edit_stream(
85        &self,
86        mut request: CreateImageEditRequest,
87    ) -> Result<ImageEditStream, OpenAIError> {
88        #[cfg(not(feature = "byot"))]
89        {
90            if let Some(stream) = request.stream {
91                if !stream {
92                    return Err(OpenAIError::InvalidArgument(
93                        "When stream is false, use Image::edit".into(),
94                    ));
95                }
96            }
97            request.stream = Some(true);
98        }
99        self.client.post_form_stream("/images/edits", request).await
100    }
101
102    /// Creates a variation of a given image. This endpoint only supports dall-e-2.
103    #[crate::byot(
104        T0 = Clone,
105        R = serde::de::DeserializeOwned,
106        where_clause =  "reqwest::multipart::Form: crate::traits::AsyncTryFrom<T0, Error = OpenAIError>",
107    )]
108    pub async fn create_variation(
109        &self,
110        request: CreateImageVariationRequest,
111    ) -> Result<ImagesResponse, OpenAIError> {
112        self.client.post_form("/images/variations", request).await
113    }
114}