diff --git a/crates/api_clients/muapi_client/src/api_types/mod.rs b/crates/api_clients/muapi_client/src/api_types/mod.rs new file mode 100644 index 0000000000..5df1059e4a --- /dev/null +++ b/crates/api_clients/muapi_client/src/api_types/mod.rs @@ -0,0 +1 @@ +pub mod request_id; diff --git a/crates/api_clients/muapi_client/src/api_types/request_id.rs b/crates/api_clients/muapi_client/src/api_types/request_id.rs new file mode 100644 index 0000000000..5a8c3a7b39 --- /dev/null +++ b/crates/api_clients/muapi_client/src/api_types/request_id.rs @@ -0,0 +1,24 @@ +/// ID for a prediction request in the Muapi API. +#[derive(Clone, Debug)] +pub struct RequestId(String); + +impl RequestId { + + pub fn new(value: String) -> Self { + RequestId(value) + } + + pub fn from_str(value: &str) -> Self { + RequestId(value.to_string()) + } + + pub fn as_str(&self) -> &str { + &self.0 + } +} + +impl std::fmt::Display for RequestId { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0) + } +} diff --git a/crates/api_clients/muapi_client/src/lib.rs b/crates/api_clients/muapi_client/src/lib.rs index 2d9dbdc26d..88321dab84 100644 --- a/crates/api_clients/muapi_client/src/lib.rs +++ b/crates/api_clients/muapi_client/src/lib.rs @@ -1,6 +1,7 @@ #[cfg(test)] pub (crate) mod test_utils; +pub mod api_types; pub mod creds; pub mod error; pub mod requests; diff --git a/crates/api_clients/muapi_client/src/requests/poll_prediction_result/poll_prediction_result.rs b/crates/api_clients/muapi_client/src/requests/poll_prediction_result/poll_prediction_result.rs index 627c62d11c..7682b80c6f 100644 --- a/crates/api_clients/muapi_client/src/requests/poll_prediction_result/poll_prediction_result.rs +++ b/crates/api_clients/muapi_client/src/requests/poll_prediction_result/poll_prediction_result.rs @@ -1,3 +1,4 @@ +use crate::api_types::request_id::RequestId; use crate::creds::muapi_session::MuapiSession; use crate::error::muapi_client_error::MuapiClientError; use crate::error::muapi_error::MuapiError; @@ -47,7 +48,7 @@ pub struct PollPredictionResultArgs<'a> { pub session: &'a MuapiSession, /// The request_id returned from a submission endpoint. - pub request_id: &'a str, + pub request_id: &'a RequestId, } pub struct PollPredictionResultApiResponse { @@ -55,7 +56,7 @@ pub struct PollPredictionResultApiResponse { pub status: PredictionStatus, /// Output URLs. Populated when `status` is `Completed`. - pub outputs: Option>, + pub output_urls: Option>, /// Error message. Populated when `status` is `Failed`. pub error: Option, @@ -66,7 +67,7 @@ pub struct PollPredictionResultApiResponse { pub async fn poll_prediction_result( args: PollPredictionResultArgs<'_>, ) -> Result { - let url = format!("{}/{}/result", PREDICTIONS_BASE_URL, args.request_id); + let url = format!("{}/{}/result", PREDICTIONS_BASE_URL, args.request_id.as_str()); info!("Polling Muapi prediction result: {}", url); @@ -100,9 +101,11 @@ pub async fn poll_prediction_result( let parsed: PollPredictionResultResponse = serde_json::from_str(&response_body) .map_err(|err| MuapiGenericApiError::SerdeResponseParseErrorWithBody(err, response_body))?; + let output_urls = parsed.outputs.and_then(|urls| if urls.is_empty() { None } else { Some(urls) }); + Ok(PollPredictionResultApiResponse { status: PredictionStatus::from_str(&parsed.status), - outputs: parsed.outputs, + output_urls, error: parsed.error, }) } @@ -120,17 +123,17 @@ mod tests { async fn test_poll_prediction_result() -> AnyhowResult<()> { setup_test_logging(LevelFilter::Trace); let session = get_test_api_key()?; - let request_id = "5fd7f575-4b9e-4c0a-b7f7-0eb036027b81"; // Corgi shiba I2V - let request_id = "8a4b578b-4514-443f-b444-4fb3bc5c2cbb"; // Cat TTV - let request_id = "671c2dee-2ca9-47d7-a12e-d16610b1b365"; // Corgi TTV - let request_id = "82d622b1-8911-4cac-8362-e18efaa743ed"; // Corgi I2V + let request_id = RequestId::from_str("5fd7f575-4b9e-4c0a-b7f7-0eb036027b81"); // Corgi shiba I2V + let request_id = RequestId::from_str("8a4b578b-4514-443f-b444-4fb3bc5c2cbb"); // Cat TTV + let request_id = RequestId::from_str("82d622b1-8911-4cac-8362-e18efaa743ed"); // Corgi I2V + let request_id = RequestId::from_str("671c2dee-2ca9-47d7-a12e-d16610b1b365"); // Corgi TTV let result = poll_prediction_result(PollPredictionResultArgs { session: &session, - request_id, + request_id: &request_id, }).await?; println!("Status: {:?}", result.status); - println!("Outputs: {:?}", result.outputs); + println!("Output URLs: {:?}", result.output_urls); println!("Error: {:?}", result.error); assert_eq!(1, 2); // NB: Intentional failure to inspect output. Ok(()) diff --git a/crates/api_clients/muapi_client/src/requests/seedance_2p0_image_to_video/seedance_2p0_image_to_video.rs b/crates/api_clients/muapi_client/src/requests/seedance_2p0_image_to_video/seedance_2p0_image_to_video.rs index bfdab1fb6f..8869af3bff 100644 --- a/crates/api_clients/muapi_client/src/requests/seedance_2p0_image_to_video/seedance_2p0_image_to_video.rs +++ b/crates/api_clients/muapi_client/src/requests/seedance_2p0_image_to_video/seedance_2p0_image_to_video.rs @@ -1,3 +1,4 @@ +use crate::api_types::request_id::RequestId; use crate::creds::muapi_session::MuapiSession; use crate::error::muapi_client_error::MuapiClientError; use crate::error::muapi_error::MuapiError; @@ -107,7 +108,7 @@ impl std::fmt::Debug for Seedance2p0ImageToVideoArgs<'_> { #[derive(Debug)] pub struct Seedance2p0ImageToVideoResponse { /// The request ID used to poll for results. - pub request_id: String, + pub request_id: RequestId, } // --- Implementation --- @@ -159,7 +160,7 @@ pub async fn seedance_2p0_image_to_video( .map_err(|err| MuapiGenericApiError::SerdeResponseParseErrorWithBody(err, response_body))?; Ok(Seedance2p0ImageToVideoResponse { - request_id: parsed.request_id, + request_id: RequestId::new(parsed.request_id), }) } @@ -190,7 +191,7 @@ mod tests { let result = seedance_2p0_image_to_video(args).await?; println!("Result: {:?}", result); println!("Request ID: {}", result.request_id); - assert!(!result.request_id.is_empty()); + assert!(!result.request_id.as_str().is_empty()); assert_eq!(1, 2); // NB: Intentional failure to inspect output. Ok(()) } @@ -213,7 +214,7 @@ mod tests { let result = seedance_2p0_image_to_video(args).await?; println!("Result: {:?}", result); println!("Request ID: {}", result.request_id); - assert!(!result.request_id.is_empty()); + assert!(!result.request_id.as_str().is_empty()); assert_eq!(1, 2); // NB: Intentional failure to inspect output. Ok(()) } diff --git a/crates/api_clients/muapi_client/src/requests/seedance_2p0_text_to_video/seedance_2p0_text_to_video.rs b/crates/api_clients/muapi_client/src/requests/seedance_2p0_text_to_video/seedance_2p0_text_to_video.rs index c2ea437b02..abc164585e 100644 --- a/crates/api_clients/muapi_client/src/requests/seedance_2p0_text_to_video/seedance_2p0_text_to_video.rs +++ b/crates/api_clients/muapi_client/src/requests/seedance_2p0_text_to_video/seedance_2p0_text_to_video.rs @@ -1,3 +1,4 @@ +use crate::api_types::request_id::RequestId; use crate::creds::muapi_session::MuapiSession; use crate::error::muapi_client_error::MuapiClientError; use crate::error::muapi_error::MuapiError; @@ -103,7 +104,7 @@ impl std::fmt::Debug for Seedance2p0TextToVideoArgs<'_> { #[derive(Debug)] pub struct Seedance2p0TextToVideoResponse { /// The request ID used to poll for results. - pub request_id: String, + pub request_id: RequestId, } // --- Implementation --- @@ -154,7 +155,7 @@ pub async fn seedance_2p0_text_to_video( .map_err(|err| MuapiGenericApiError::SerdeResponseParseErrorWithBody(err, response_body))?; Ok(Seedance2p0TextToVideoResponse { - request_id: parsed.request_id, + request_id: RequestId::new(parsed.request_id), }) } @@ -181,7 +182,7 @@ mod tests { let result = seedance_2p0_text_to_video(args).await?; println!("Result: {:?}", result); println!("Request ID: {}", result.request_id); - assert!(!result.request_id.is_empty()); + assert!(!result.request_id.as_str().is_empty()); assert_eq!(1, 2); // NB: Intentional failure to inspect output. Ok(()) } @@ -201,7 +202,7 @@ mod tests { let result = seedance_2p0_text_to_video(args).await?; println!("Result: {:?}", result); println!("Request ID: {}", result.request_id); - assert!(!result.request_id.is_empty()); + assert!(!result.request_id.as_str().is_empty()); assert_eq!(1, 2); // NB: Intentional failure to inspect output. Ok(()) }