comfyui_api/api/
view.rs

1use reqwest::Url;
2
3use crate::models::Image;
4
5/// Errors that can occur when interacting with `ViewApi`.
6#[derive(thiserror::Error, Debug)]
7#[non_exhaustive]
8pub enum ViewApiError {
9    /// Error parsing endpoint URL
10    #[error("Failed to parse endpoint URL")]
11    ParseError(#[from] url::ParseError),
12    /// Error sending request
13    #[error("Failed to send request")]
14    RequestFailed(#[from] reqwest::Error),
15    /// An error occurred getting response bytes.
16    #[error("Failed to get response bytes")]
17    GetBytesFailed(#[source] reqwest::Error),
18    /// An error occurred getting response text.
19    #[error("Failed to get response text")]
20    GetTextFailed(#[source] reqwest::Error),
21    /// Server returned an error when uploading file
22    #[error("Failed to upload image: {status}: {error}")]
23    ViewImageFailed {
24        status: reqwest::StatusCode,
25        error: String,
26    },
27}
28
29type Result<T> = std::result::Result<T, ViewApiError>;
30
31/// Struct representing a connection to the ComfyUI API `view` endpoint.
32#[derive(Clone, Debug)]
33pub struct ViewApi {
34    client: reqwest::Client,
35    endpoint: Url,
36}
37
38impl ViewApi {
39    /// Constructs a new `ViewApi` client with a given `reqwest::Client` and ComfyUI API
40    /// endpoint.
41    ///
42    /// # Arguments
43    ///
44    /// * `client` - A `reqwest::Client` used to send requests.
45    /// * `endpoint` - A `str` representation of the endpoint url.
46    ///
47    /// # Returns
48    ///
49    /// A `Result` containing a new `ViewApi` instance on success, or an error if url parsing failed.
50    pub fn new<S>(client: reqwest::Client, endpoint: S) -> Result<Self>
51    where
52        S: AsRef<str>,
53    {
54        Ok(Self::new_with_url(client, Url::parse(endpoint.as_ref())?))
55    }
56
57    /// Constructs a new `ViewApi` client with a given `reqwest::Client` and endpoint `Url`.
58    ///
59    /// # Arguments
60    ///
61    /// * `client` - A `reqwest::Client` used to send requests.
62    /// * `endpoint` - A `Url` representing the endpoint url.
63    ///
64    /// # Returns
65    ///
66    /// A new `ViewApi` instance.
67    pub fn new_with_url(client: reqwest::Client, endpoint: Url) -> Self {
68        Self { client, endpoint }
69    }
70
71    /// Sends a view request using the `ViewApi` client.
72    ///
73    /// # Arguments
74    ///
75    /// * `image` - An `Image` struct containing the information about the image to view.
76    ///
77    /// # Returns
78    ///
79    /// A `Result` containing a `Vec<u8>` representation of the image on
80    /// success, or an error if the request failed.
81    pub async fn get(&self, image: &Image) -> Result<Vec<u8>> {
82        let response = self
83            .client
84            .get(self.endpoint.clone())
85            .query(&image)
86            .send()
87            .await?;
88        if response.status().is_success() {
89            return Ok(response
90                .bytes()
91                .await
92                .map_err(ViewApiError::GetBytesFailed)?
93                .to_vec());
94        }
95        let status = response.status();
96        let text = response.text().await.map_err(ViewApiError::GetTextFailed)?;
97        Err(ViewApiError::ViewImageFailed {
98            status,
99            error: text,
100        })
101    }
102}