Skip to main content

async_openai/
image.rs

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