diff --git a/crates/api_clients/fal_client/src/requests/webhook/image/edit/enqueue_flux_1_dev_edit_image_webhook.rs b/crates/api_clients/fal_client/src/requests/webhook/image/edit/enqueue_flux_1_dev_edit_image_webhook.rs index 761614d087..ec87413e04 100644 --- a/crates/api_clients/fal_client/src/requests/webhook/image/edit/enqueue_flux_1_dev_edit_image_webhook.rs +++ b/crates/api_clients/fal_client/src/requests/webhook/image/edit/enqueue_flux_1_dev_edit_image_webhook.rs @@ -6,15 +6,18 @@ use crate::requests::api::webhook_response::WebhookResponse; use reqwest::IntoUrl; pub struct Flux1DevEditImageArgs<'a, U: IntoUrl> { - pub prompt: &'a str, - pub image_url: String, - pub num_images: Flux1DevEditImageNumImages, - - // Fulfillment + pub request: Flux1DevEditImageRequest, pub webhook_url: U, pub api_key: &'a FalApiKey, } +#[derive(Clone, Debug)] +pub struct Flux1DevEditImageRequest { + pub prompt: String, + pub image_url: String, + pub num_images: Flux1DevEditImageNumImages, +} + #[derive(Copy, Clone, Debug)] pub enum Flux1DevEditImageNumImages { One, @@ -26,7 +29,9 @@ pub enum Flux1DevEditImageNumImages { pub async fn enqueue_flux_1_dev_edit_image_webhook( args: Flux1DevEditImageArgs<'_, U> ) -> Result { - let num_images = match args.num_images { + let req = args.request; + + let num_images = match req.num_images { Flux1DevEditImageNumImages::One => 1, Flux1DevEditImageNumImages::Two => 2, Flux1DevEditImageNumImages::Three => 3, @@ -34,8 +39,8 @@ pub async fn enqueue_flux_1_dev_edit_image_webhook( }; let request = Flux1DevEditImageInput { - prompt: args.prompt.to_string(), - image_url: args.image_url, + prompt: req.prompt, + image_url: req.image_url, num_images: Some(num_images), enable_safety_checker: Some(false), output_format: Some("png".to_string()), @@ -55,6 +60,7 @@ mod tests { use crate::creds::fal_api_key::FalApiKey; use crate::requests::webhook::image::edit::enqueue_flux_1_dev_edit_image_webhook::{ enqueue_flux_1_dev_edit_image_webhook, Flux1DevEditImageArgs, Flux1DevEditImageNumImages, + Flux1DevEditImageRequest, }; use errors::AnyhowResult; use std::fs::read_to_string; @@ -67,9 +73,11 @@ mod tests { let api_key = FalApiKey::from_str(&secret); let args = Flux1DevEditImageArgs { - prompt: "make this image look like a watercolor painting", - image_url: GHOST_IMAGE_URL.to_string(), - num_images: Flux1DevEditImageNumImages::One, + request: Flux1DevEditImageRequest { + prompt: "make this image look like a watercolor painting".to_string(), + image_url: GHOST_IMAGE_URL.to_string(), + num_images: Flux1DevEditImageNumImages::One, + }, api_key: &api_key, webhook_url: "https://example.com/webhook", }; @@ -86,9 +94,11 @@ mod tests { let api_key = FalApiKey::from_str(&secret); let args = Flux1DevEditImageArgs { - prompt: "turn this into a cyberpunk scene with neon lights", - image_url: GHOST_IMAGE_URL.to_string(), - num_images: Flux1DevEditImageNumImages::Two, + request: Flux1DevEditImageRequest { + prompt: "turn this into a cyberpunk scene with neon lights".to_string(), + image_url: GHOST_IMAGE_URL.to_string(), + num_images: Flux1DevEditImageNumImages::Two, + }, api_key: &api_key, webhook_url: "https://example.com/webhook", }; diff --git a/crates/api_clients/fal_client/src/requests/webhook/image/edit/enqueue_flux_1_schnell_edit_image_webhook.rs b/crates/api_clients/fal_client/src/requests/webhook/image/edit/enqueue_flux_1_schnell_edit_image_webhook.rs index f6dcf73844..f36caa6c24 100644 --- a/crates/api_clients/fal_client/src/requests/webhook/image/edit/enqueue_flux_1_schnell_edit_image_webhook.rs +++ b/crates/api_clients/fal_client/src/requests/webhook/image/edit/enqueue_flux_1_schnell_edit_image_webhook.rs @@ -6,13 +6,16 @@ use crate::requests::api::webhook_response::WebhookResponse; use reqwest::IntoUrl; pub struct Flux1SchnellEditImageArgs<'a, U: IntoUrl> { + pub request: Flux1SchnellEditImageRequest, + pub webhook_url: U, + pub api_key: &'a FalApiKey, +} + +#[derive(Clone, Debug)] +pub struct Flux1SchnellEditImageRequest { pub image_url: String, pub num_images: Flux1SchnellEditImageNumImages, pub image_size: Option, - - // Fulfillment - pub webhook_url: U, - pub api_key: &'a FalApiKey, } #[derive(Copy, Clone, Debug)] @@ -36,14 +39,16 @@ pub enum Flux1SchnellEditImageSize { pub async fn enqueue_flux_1_schnell_edit_image_webhook( args: Flux1SchnellEditImageArgs<'_, U> ) -> Result { - let num_images = match args.num_images { + let req = args.request; + + let num_images = match req.num_images { Flux1SchnellEditImageNumImages::One => 1, Flux1SchnellEditImageNumImages::Two => 2, Flux1SchnellEditImageNumImages::Three => 3, Flux1SchnellEditImageNumImages::Four => 4, }; - let image_size = args.image_size.map(|s| match s { + let image_size = req.image_size.map(|s| match s { Flux1SchnellEditImageSize::Square => "square", Flux1SchnellEditImageSize::SquareHd => "square_hd", Flux1SchnellEditImageSize::LandscapeFourByThree => "landscape_4_3", @@ -53,7 +58,7 @@ pub async fn enqueue_flux_1_schnell_edit_image_webhook( }.to_string()); let request = Flux1SchnellEditImageInput { - image_url: args.image_url, + image_url: req.image_url, num_images: Some(num_images), image_size, enable_safety_checker: Some(false), @@ -74,7 +79,7 @@ mod tests { use crate::creds::fal_api_key::FalApiKey; use crate::requests::webhook::image::edit::enqueue_flux_1_schnell_edit_image_webhook::{ enqueue_flux_1_schnell_edit_image_webhook, Flux1SchnellEditImageArgs, - Flux1SchnellEditImageNumImages, Flux1SchnellEditImageSize, + Flux1SchnellEditImageNumImages, Flux1SchnellEditImageRequest, Flux1SchnellEditImageSize, }; use errors::AnyhowResult; use std::fs::read_to_string; @@ -87,9 +92,11 @@ mod tests { let api_key = FalApiKey::from_str(&secret); let args = Flux1SchnellEditImageArgs { - image_url: GHOST_IMAGE_URL.to_string(), - num_images: Flux1SchnellEditImageNumImages::One, - image_size: None, + request: Flux1SchnellEditImageRequest { + image_url: GHOST_IMAGE_URL.to_string(), + num_images: Flux1SchnellEditImageNumImages::One, + image_size: None, + }, api_key: &api_key, webhook_url: "https://example.com/webhook", }; @@ -106,9 +113,11 @@ mod tests { let api_key = FalApiKey::from_str(&secret); let args = Flux1SchnellEditImageArgs { - image_url: GHOST_IMAGE_URL.to_string(), - num_images: Flux1SchnellEditImageNumImages::Two, - image_size: Some(Flux1SchnellEditImageSize::LandscapeSixteenByNine), + request: Flux1SchnellEditImageRequest { + image_url: GHOST_IMAGE_URL.to_string(), + num_images: Flux1SchnellEditImageNumImages::Two, + image_size: Some(Flux1SchnellEditImageSize::LandscapeSixteenByNine), + }, api_key: &api_key, webhook_url: "https://example.com/webhook", }; diff --git a/crates/api_clients/fal_client/src/requests/webhook/image/edit/enqueue_flux_pro_kontext_max_edit_webhook.rs b/crates/api_clients/fal_client/src/requests/webhook/image/edit/enqueue_flux_pro_kontext_max_edit_webhook.rs index 9ca28e00c6..d06ab62fa3 100644 --- a/crates/api_clients/fal_client/src/requests/webhook/image/edit/enqueue_flux_pro_kontext_max_edit_webhook.rs +++ b/crates/api_clients/fal_client/src/requests/webhook/image/edit/enqueue_flux_pro_kontext_max_edit_webhook.rs @@ -6,16 +6,20 @@ use crate::requests::api::webhook_response::WebhookResponse; use reqwest::IntoUrl; pub struct FluxProKontextMaxArgs<'a, U: IntoUrl, R: IntoUrl> { - // Request - pub prompt: &'a str, + pub request: FluxProKontextMaxRequest, pub image_url: U, - pub num_images: FluxProKontextMaxNumImages, // Fulfillment pub webhook_url: R, pub api_key: &'a FalApiKey, } +#[derive(Clone, Debug)] +pub struct FluxProKontextMaxRequest { + pub prompt: String, + pub num_images: FluxProKontextMaxNumImages, +} + #[derive(Copy, Clone, Debug)] pub enum FluxProKontextMaxNumImages { One, // Default @@ -27,8 +31,9 @@ pub enum FluxProKontextMaxNumImages { pub async fn enqueue_flux_pro_kontext_max_edit_webhook( args: FluxProKontextMaxArgs<'_, U, R> ) -> Result { + let req = args.request; - let num_images = match args.num_images { + let num_images = match req.num_images { FluxProKontextMaxNumImages::One => 1, FluxProKontextMaxNumImages::Two => 2, FluxProKontextMaxNumImages::Three => 3, @@ -36,7 +41,7 @@ pub async fn enqueue_flux_pro_kontext_max_edit_webhook( }; let request = FluxProKontextMaxEditInput { - prompt: args.prompt.to_string(), + prompt: req.prompt, image_url: args.image_url.as_str().to_string(), num_images: Some(num_images), @@ -61,7 +66,7 @@ pub async fn enqueue_flux_pro_kontext_max_edit_webhook( #[cfg(test)] mod tests { use crate::creds::fal_api_key::FalApiKey; - use crate::requests::webhook::image::edit::enqueue_flux_pro_kontext_max_edit_webhook::{enqueue_flux_pro_kontext_max_edit_webhook, FluxProKontextMaxArgs, FluxProKontextMaxNumImages}; + use crate::requests::webhook::image::edit::enqueue_flux_pro_kontext_max_edit_webhook::{enqueue_flux_pro_kontext_max_edit_webhook, FluxProKontextMaxArgs, FluxProKontextMaxNumImages, FluxProKontextMaxRequest}; use errors::AnyhowResult; use std::fs::read_to_string; use test_data::web::image_urls::TALL_MOCHI_WITH_GLASSES_IMAGE_URL; @@ -75,11 +80,13 @@ mod tests { let api_key = FalApiKey::from_str(&secret); let args = FluxProKontextMaxArgs { + request: FluxProKontextMaxRequest { + prompt: "turn the glasses into sunglasses, make them sleek sunglasses with black rims, square shaped".to_string(), + num_images: FluxProKontextMaxNumImages::One, + }, image_url: TALL_MOCHI_WITH_GLASSES_IMAGE_URL, - prompt: "turn the glasses into sunglasses, make them sleek sunglasses with black rims, square shaped", api_key: &api_key, webhook_url: "https://example.com/webhook", - num_images: FluxProKontextMaxNumImages::One, }; let result = enqueue_flux_pro_kontext_max_edit_webhook(args).await?; diff --git a/crates/api_clients/fal_client/src/requests/webhook/image/edit/enqueue_gemini_25_flash_edit_webhook.rs b/crates/api_clients/fal_client/src/requests/webhook/image/edit/enqueue_gemini_25_flash_edit_webhook.rs index 9328386ffe..e64124dbd9 100644 --- a/crates/api_clients/fal_client/src/requests/webhook/image/edit/enqueue_gemini_25_flash_edit_webhook.rs +++ b/crates/api_clients/fal_client/src/requests/webhook/image/edit/enqueue_gemini_25_flash_edit_webhook.rs @@ -7,19 +7,23 @@ use crate::requests::api::webhook_response::WebhookResponse; use reqwest::IntoUrl; pub struct Gemini25FlashEditArgs<'a, R: IntoUrl> { - // Request required - pub prompt: &'a str, - pub image_urls: Vec, - pub num_images: Gemini25FlashEditNumImages, - - // Optional - pub aspect_ratio: Option, + pub request: Gemini25FlashEditRequest, // Fulfillment pub webhook_url: R, pub api_key: &'a FalApiKey, } +#[derive(Clone, Debug)] +pub struct Gemini25FlashEditRequest { + pub prompt: String, + pub image_urls: Vec, + pub num_images: Gemini25FlashEditNumImages, + + // Optional + pub aspect_ratio: Option, +} + #[derive(Copy, Clone, Debug)] pub enum Gemini25FlashEditNumImages { One, @@ -50,7 +54,7 @@ pub enum Gemini25FlashEditAspectRatio { } -impl FalRequestCostCalculator for Gemini25FlashEditArgs<'_, U> { +impl FalRequestCostCalculator for Gemini25FlashEditRequest { fn calculate_cost_in_cents(&self) -> UsdCents { // Your request will cost $0.039 per image. For $1.00, you can run this model 25 times. match self.num_images { @@ -66,15 +70,16 @@ impl FalRequestCostCalculator for Gemini25FlashEditArgs<'_, U> { pub async fn enqueue_gemini_25_flash_edit_webhook( args: Gemini25FlashEditArgs<'_, R> ) -> Result { + let req = args.request; - let num_images = match args.num_images { + let num_images = match req.num_images { Gemini25FlashEditNumImages::One => 1, Gemini25FlashEditNumImages::Two => 2, Gemini25FlashEditNumImages::Three => 3, Gemini25FlashEditNumImages::Four => 4, }; - let aspect_ratio = args.aspect_ratio + let aspect_ratio = req.aspect_ratio .map(|aspect_ratio| match aspect_ratio { // Auto Gemini25FlashEditAspectRatio::Auto => "auto", @@ -95,8 +100,8 @@ pub async fn enqueue_gemini_25_flash_edit_webhook( .map(|aspect_ratio| aspect_ratio.to_string()); let request = Gemini25FlashEditInput { - prompt: args.prompt.to_string(), - image_urls: args.image_urls, + prompt: req.prompt, + image_urls: req.image_urls, aspect_ratio, // Constants num_images: Some(num_images), @@ -114,7 +119,7 @@ pub async fn enqueue_gemini_25_flash_edit_webhook( #[cfg(test)] mod tests { use crate::creds::fal_api_key::FalApiKey; - use crate::requests::webhook::image::edit::enqueue_gemini_25_flash_edit_webhook::{enqueue_gemini_25_flash_edit_webhook, Gemini25FlashEditArgs, Gemini25FlashEditNumImages}; + use crate::requests::webhook::image::edit::enqueue_gemini_25_flash_edit_webhook::{enqueue_gemini_25_flash_edit_webhook, Gemini25FlashEditArgs, Gemini25FlashEditNumImages, Gemini25FlashEditRequest}; use errors::AnyhowResult; use std::fs::read_to_string; use test_data::web::image_urls::{GHOST_IMAGE_URL, TREX_SKELETON_IMAGE_URL}; @@ -128,13 +133,15 @@ mod tests { let api_key = FalApiKey::from_str(&secret); let args = Gemini25FlashEditArgs { - image_urls: vec![ - GHOST_IMAGE_URL.to_string(), - TREX_SKELETON_IMAGE_URL.to_string(), - ], - num_images: Gemini25FlashEditNumImages::Two, - aspect_ratio: None, - prompt: "add the ghost to the image of the t-rex skeleton, make it look spooky but friendly", + request: Gemini25FlashEditRequest { + image_urls: vec![ + GHOST_IMAGE_URL.to_string(), + TREX_SKELETON_IMAGE_URL.to_string(), + ], + num_images: Gemini25FlashEditNumImages::Two, + aspect_ratio: None, + prompt: "add the ghost to the image of the t-rex skeleton, make it look spooky but friendly".to_string(), + }, api_key: &api_key, webhook_url: "https://example.com/webhook", }; diff --git a/crates/api_clients/fal_client/src/requests/webhook/image/edit/enqueue_gpt_image_1_byok_edit_image_webhook.rs b/crates/api_clients/fal_client/src/requests/webhook/image/edit/enqueue_gpt_image_1_byok_edit_image_webhook.rs index 9d4f5f47e3..4995ead100 100644 --- a/crates/api_clients/fal_client/src/requests/webhook/image/edit/enqueue_gpt_image_1_byok_edit_image_webhook.rs +++ b/crates/api_clients/fal_client/src/requests/webhook/image/edit/enqueue_gpt_image_1_byok_edit_image_webhook.rs @@ -13,12 +13,7 @@ use crate::requests::api::webhook_response::WebhookResponse; use reqwest::IntoUrl; pub struct GptEditImageByokArgs<'a, V: IntoUrl> { - // Request - pub image_urls: Vec, - pub prompt: &'a str, - pub image_size: GptEditImageSize, - pub num_images: GptEditImageNumImages, - pub quality: GptEditImageQuality, + pub request: GptEditImageByokRequest, // Fulfillment pub api_key: &'a FalApiKey, @@ -26,6 +21,15 @@ pub struct GptEditImageByokArgs<'a, V: IntoUrl> { pub webhook_url: V, } +#[derive(Clone, Debug)] +pub struct GptEditImageByokRequest { + pub image_urls: Vec, + pub prompt: String, + pub image_size: GptEditImageSize, + pub num_images: GptEditImageNumImages, + pub quality: GptEditImageQuality, +} + #[derive(Copy, Clone, Debug)] pub enum GptEditImageSize { Auto, @@ -52,7 +56,7 @@ pub enum GptEditImageNumImages{ // NB: These are BYOK, so they're not Fal's prices -impl FalRequestCostCalculator for GptEditImageByokArgs<'_, U> { +impl FalRequestCostCalculator for GptEditImageByokRequest { fn calculate_cost_in_cents(&self) -> UsdCents { let base_cost = match self.quality { GptEditImageQuality::Auto => 17, @@ -74,22 +78,23 @@ impl FalRequestCostCalculator for GptEditImageByokArgs<'_, U> { pub async fn enqueue_gpt_image_1_byok_edit_image_webhook( args: GptEditImageByokArgs<'_, V> ) -> Result { + let req = args.request; - let image_size = match args.image_size { + let image_size = match req.image_size { GptEditImageSize::Auto => "auto", GptEditImageSize::Square => "1024x1024", GptEditImageSize::Horizontal => "1536x1024", GptEditImageSize::Vertical => "1024x1536", }; - let quality = match args.quality { + let quality = match req.quality { GptEditImageQuality::Auto => "auto", GptEditImageQuality::Low => "low", GptEditImageQuality::Medium => "medium", GptEditImageQuality::High => "high", }; - let num_images = match args.num_images { + let num_images = match req.num_images { GptEditImageNumImages::One => 1, GptEditImageNumImages::Two => 2, GptEditImageNumImages::Three => 3, @@ -97,8 +102,8 @@ pub async fn enqueue_gpt_image_1_byok_edit_image_webhook( }; let request = GptImage1EditImageInput { - image_urls: args.image_urls, - prompt: args.prompt.to_string(), + image_urls: req.image_urls, + prompt: req.prompt, image_size: image_size.to_string(), num_images, quality: quality.to_string(), @@ -118,8 +123,8 @@ mod tests { use crate::creds::fal_api_key::FalApiKey; use crate::creds::open_ai_api_key::OpenAiApiKey; use crate::requests::webhook::image::edit::enqueue_gpt_image_1_byok_edit_image_webhook::{ - enqueue_gpt_image_1_byok_edit_image_webhook, GptEditImageByokArgs, GptEditImageNumImages, - GptEditImageQuality, GptEditImageSize, + enqueue_gpt_image_1_byok_edit_image_webhook, GptEditImageByokArgs, GptEditImageByokRequest, + GptEditImageNumImages, GptEditImageQuality, GptEditImageSize, }; use errors::AnyhowResult; use std::fs::read_to_string; @@ -138,15 +143,17 @@ mod tests { let openai_api_key = OpenAiApiKey::from_str(&openai_secret); let args = GptEditImageByokArgs { - image_urls: vec![ - GHOST_IMAGE_URL.to_string(), - TREX_SKELETON_IMAGE_URL.to_string(), - ERNEST_SCARED_STUPID_IMAGE_URL.to_string(), - ], - prompt: "add the ghost and scared man to the image of the t-rex skeleton, make it look spooky but friendly", - image_size: GptEditImageSize::Horizontal, - num_images: GptEditImageNumImages::One, - quality: GptEditImageQuality::High, + request: GptEditImageByokRequest { + image_urls: vec![ + GHOST_IMAGE_URL.to_string(), + TREX_SKELETON_IMAGE_URL.to_string(), + ERNEST_SCARED_STUPID_IMAGE_URL.to_string(), + ], + prompt: "add the ghost and scared man to the image of the t-rex skeleton, make it look spooky but friendly".to_string(), + image_size: GptEditImageSize::Horizontal, + num_images: GptEditImageNumImages::One, + quality: GptEditImageQuality::High, + }, api_key: &fal_api_key, openai_api_key: &openai_api_key, webhook_url: "https://example.com/webhook", diff --git a/crates/api_clients/fal_client/src/requests/webhook/image/edit/enqueue_gpt_image_1_edit_image_webhook.rs b/crates/api_clients/fal_client/src/requests/webhook/image/edit/enqueue_gpt_image_1_edit_image_webhook.rs index a875412754..c6c2b8f2d3 100644 --- a/crates/api_clients/fal_client/src/requests/webhook/image/edit/enqueue_gpt_image_1_edit_image_webhook.rs +++ b/crates/api_clients/fal_client/src/requests/webhook/image/edit/enqueue_gpt_image_1_edit_image_webhook.rs @@ -15,8 +15,15 @@ use reqwest::IntoUrl; /// (The BYOK variant lives in `enqueue_gpt_image_1_byok_edit_image_webhook.rs` /// and is deprecated.) pub struct EnqueueGptImage1EditImageArgs<'a, R: IntoUrl> { + pub request: EnqueueGptImage1EditImageRequest, + pub webhook_url: R, + pub api_key: &'a FalApiKey, +} + +#[derive(Clone, Debug)] +pub struct EnqueueGptImage1EditImageRequest { // Required - pub prompt: &'a str, + pub prompt: String, pub image_urls: Vec, pub num_images: EnqueueGptImage1EditImageNumImages, @@ -27,10 +34,6 @@ pub struct EnqueueGptImage1EditImageArgs<'a, R: IntoUrl> { pub input_fidelity: Option, pub background: Option, pub output_format: Option, - - // Fulfillment - pub webhook_url: R, - pub api_key: &'a FalApiKey, } #[derive(Copy, Clone, Debug)] @@ -79,7 +82,7 @@ pub enum EnqueueGptImage1EditImageOutputFormat { Webp, } -impl FalRequestCostCalculator for EnqueueGptImage1EditImageArgs<'_, U> { +impl FalRequestCostCalculator for EnqueueGptImage1EditImageRequest { fn calculate_cost_in_cents(&self) -> UsdCents { // Per fal docs (fal-ai/gpt-image-1/edit-image), pricing matches // text-to-image (input image tokens are billed separately and not included @@ -115,14 +118,16 @@ impl FalRequestCostCalculator for EnqueueGptImage1EditImageArgs<'_, pub async fn enqueue_gpt_image_1_edit_image_webhook( args: EnqueueGptImage1EditImageArgs<'_, R>, ) -> Result { - let num_images: u8 = match args.num_images { + let req = args.request; + + let num_images: u8 = match req.num_images { EnqueueGptImage1EditImageNumImages::One => 1, EnqueueGptImage1EditImageNumImages::Two => 2, EnqueueGptImage1EditImageNumImages::Three => 3, EnqueueGptImage1EditImageNumImages::Four => 4, }; - let image_size = args.image_size.map(|s| { + let image_size = req.image_size.map(|s| { match s { EnqueueGptImage1EditImageSize::Auto => "auto", EnqueueGptImage1EditImageSize::Square => "1024x1024", @@ -132,7 +137,7 @@ pub async fn enqueue_gpt_image_1_edit_image_webhook( .to_string() }); - let quality = args.quality.map(|q| { + let quality = req.quality.map(|q| { match q { EnqueueGptImage1EditImageQuality::Low => "low", EnqueueGptImage1EditImageQuality::Medium => "medium", @@ -141,7 +146,7 @@ pub async fn enqueue_gpt_image_1_edit_image_webhook( .to_string() }); - let input_fidelity = args.input_fidelity.map(|f| { + let input_fidelity = req.input_fidelity.map(|f| { match f { EnqueueGptImage1EditImageInputFidelity::Low => "low", EnqueueGptImage1EditImageInputFidelity::High => "high", @@ -149,7 +154,7 @@ pub async fn enqueue_gpt_image_1_edit_image_webhook( .to_string() }); - let background = args.background.map(|b| { + let background = req.background.map(|b| { match b { EnqueueGptImage1EditImageBackground::Auto => "auto", EnqueueGptImage1EditImageBackground::Transparent => "transparent", @@ -158,7 +163,7 @@ pub async fn enqueue_gpt_image_1_edit_image_webhook( .to_string() }); - let output_format = args.output_format.map(|f| { + let output_format = req.output_format.map(|f| { match f { EnqueueGptImage1EditImageOutputFormat::Jpeg => "jpeg", EnqueueGptImage1EditImageOutputFormat::Png => "png", @@ -168,9 +173,9 @@ pub async fn enqueue_gpt_image_1_edit_image_webhook( }); let request = GptImage1NonByokEditImageInput { - prompt: args.prompt.to_string(), - image_urls: args.image_urls, - mask_image_url: args.mask_image_url, + prompt: req.prompt, + image_urls: req.image_urls, + mask_image_url: req.mask_image_url, num_images: Some(num_images), image_size, quality, @@ -193,7 +198,7 @@ mod tests { use crate::requests::webhook::image::edit::enqueue_gpt_image_1_edit_image_webhook::{ enqueue_gpt_image_1_edit_image_webhook, EnqueueGptImage1EditImageArgs, EnqueueGptImage1EditImageNumImages, EnqueueGptImage1EditImageQuality, - EnqueueGptImage1EditImageSize, + EnqueueGptImage1EditImageRequest, EnqueueGptImage1EditImageSize, }; use errors::AnyhowResult; use std::fs::read_to_string; @@ -209,19 +214,21 @@ mod tests { let api_key = FalApiKey::from_str(&secret); let args = EnqueueGptImage1EditImageArgs { - prompt: "add the ghost and scared man to the image of the t-rex skeleton, make it look spooky but friendly", - image_urls: vec![ - GHOST_IMAGE_URL.to_string(), - TREX_SKELETON_IMAGE_URL.to_string(), - ERNEST_SCARED_STUPID_IMAGE_URL.to_string(), - ], - num_images: EnqueueGptImage1EditImageNumImages::One, - mask_image_url: None, - image_size: Some(EnqueueGptImage1EditImageSize::Horizontal), - quality: Some(EnqueueGptImage1EditImageQuality::Medium), - input_fidelity: None, - background: None, - output_format: None, + request: EnqueueGptImage1EditImageRequest { + prompt: "add the ghost and scared man to the image of the t-rex skeleton, make it look spooky but friendly".to_string(), + image_urls: vec![ + GHOST_IMAGE_URL.to_string(), + TREX_SKELETON_IMAGE_URL.to_string(), + ERNEST_SCARED_STUPID_IMAGE_URL.to_string(), + ], + num_images: EnqueueGptImage1EditImageNumImages::One, + mask_image_url: None, + image_size: Some(EnqueueGptImage1EditImageSize::Horizontal), + quality: Some(EnqueueGptImage1EditImageQuality::Medium), + input_fidelity: None, + background: None, + output_format: None, + }, api_key: &api_key, webhook_url: "https://example.com/webhook", }; diff --git a/crates/api_clients/fal_client/src/requests/webhook/image/edit/enqueue_gpt_image_1p5_edit_image_webhook.rs b/crates/api_clients/fal_client/src/requests/webhook/image/edit/enqueue_gpt_image_1p5_edit_image_webhook.rs index 5decf21909..84c03d0489 100644 --- a/crates/api_clients/fal_client/src/requests/webhook/image/edit/enqueue_gpt_image_1p5_edit_image_webhook.rs +++ b/crates/api_clients/fal_client/src/requests/webhook/image/edit/enqueue_gpt_image_1p5_edit_image_webhook.rs @@ -7,22 +7,27 @@ use crate::requests::api::webhook_response::WebhookResponse; use reqwest::IntoUrl; pub struct EnqueueGptImage1p5EditImageArgs<'a, R: IntoUrl> { - // Request required - pub prompt: &'a str, + pub request: EnqueueGptImage1p5EditImageRequest, + + // Fulfillment + pub webhook_url: R, + pub api_key: &'a FalApiKey, +} + +#[derive(Clone, Debug)] +pub struct EnqueueGptImage1p5EditImageRequest { + // Required + pub prompt: String, pub image_urls: Vec, pub num_images: EnqueueGptImage1p5EditImageNumImages, - // Optional args + // Optional pub mask_image_url: Option, pub image_size: Option, pub background: Option, pub quality: Option, pub input_fidelity: Option, pub output_format: Option, - - // Fulfillment - pub webhook_url: R, - pub api_key: &'a FalApiKey, } #[derive(Copy, Clone, Debug)] @@ -70,8 +75,7 @@ pub enum EnqueueGptImage1p5EditImageOutputFormat { Webp, } - -impl FalRequestCostCalculator for EnqueueGptImage1p5EditImageArgs<'_, U> { +impl FalRequestCostCalculator for EnqueueGptImage1p5EditImageRequest { fn calculate_cost_in_cents(&self) -> UsdCents { // Your request will cost different amounts based on the number of images, quality, and size. // For low quality, you will be charged $0.009 for 1024x1024 or $0.013 for any other size per image. @@ -97,19 +101,19 @@ impl FalRequestCostCalculator for EnqueueGptImage1p5EditImageArgs<' } } - pub async fn enqueue_gpt_image_1p5_image_edit_webhook( args: EnqueueGptImage1p5EditImageArgs<'_, R> ) -> Result { + let req = args.request; - let num_images = match args.num_images { + let num_images = match req.num_images { EnqueueGptImage1p5EditImageNumImages::One => 1, EnqueueGptImage1p5EditImageNumImages::Two => 2, EnqueueGptImage1p5EditImageNumImages::Three => 3, EnqueueGptImage1p5EditImageNumImages::Four => 4, }; - let image_size = args.image_size + let image_size = req.image_size .map(|s| match s { EnqueueGptImage1p5EditImageSize::Square => "1024x1024", EnqueueGptImage1p5EditImageSize::Wide => "1536x1024", @@ -117,7 +121,7 @@ pub async fn enqueue_gpt_image_1p5_image_edit_webhook( }) .map(|resolution| resolution.to_string()); - let background = args.background + let background = req.background .map(|s| match s { EnqueueGptImage1p5EditImageBackground::Auto => "auto", EnqueueGptImage1p5EditImageBackground::Transparent => "transparent", @@ -125,7 +129,7 @@ pub async fn enqueue_gpt_image_1p5_image_edit_webhook( }) .map(|aspect_ratio| aspect_ratio.to_string()); - let quality = args.quality + let quality = req.quality .map(|s| match s { EnqueueGptImage1p5EditImageQuality::Low => "low", EnqueueGptImage1p5EditImageQuality::Medium => "medium", @@ -133,14 +137,14 @@ pub async fn enqueue_gpt_image_1p5_image_edit_webhook( }) .map(|aspect_ratio| aspect_ratio.to_string()); - let input_fidelity = args.input_fidelity + let input_fidelity = req.input_fidelity .map(|s| match s { EnqueueGptImage1p5EditImageInputFidelity::Low => "low", EnqueueGptImage1p5EditImageInputFidelity::High => "high", }) .map(|aspect_ratio| aspect_ratio.to_string()); - let output_format = args.output_format + let output_format = req.output_format .map(|s| match s { EnqueueGptImage1p5EditImageOutputFormat::Jpeg => "jpeg", EnqueueGptImage1p5EditImageOutputFormat::Png => "png", @@ -150,12 +154,12 @@ pub async fn enqueue_gpt_image_1p5_image_edit_webhook( .unwrap_or_else(|| "png".to_string()); let request = GptImage1p5EditImageInput { - prompt: args.prompt.to_string(), - image_urls: args.image_urls, + prompt: req.prompt, + image_urls: req.image_urls, num_images: Some(num_images), output_format: Some(output_format), // Optionals - mask_image_url: args.mask_image_url, + mask_image_url: req.mask_image_url, image_size, background, quality, @@ -173,7 +177,10 @@ pub async fn enqueue_gpt_image_1p5_image_edit_webhook( #[cfg(test)] mod tests { use crate::creds::fal_api_key::FalApiKey; - use crate::requests::webhook::image::edit::enqueue_gpt_image_1p5_edit_image_webhook::{enqueue_gpt_image_1p5_image_edit_webhook, EnqueueGptImage1p5EditImageArgs, EnqueueGptImage1p5EditImageNumImages}; + use crate::requests::webhook::image::edit::enqueue_gpt_image_1p5_edit_image_webhook::{ + enqueue_gpt_image_1p5_image_edit_webhook, EnqueueGptImage1p5EditImageArgs, + EnqueueGptImage1p5EditImageNumImages, EnqueueGptImage1p5EditImageRequest, + }; use errors::AnyhowResult; use std::fs::read_to_string; use test_data::web::image_urls::{ERNEST_SCARED_STUPID_IMAGE_URL, GHOST_IMAGE_URL, TREX_SKELETON_IMAGE_URL}; @@ -187,21 +194,23 @@ mod tests { let api_key = FalApiKey::from_str(&secret); let args = EnqueueGptImage1p5EditImageArgs { - image_urls: vec![ - GHOST_IMAGE_URL.to_string(), - TREX_SKELETON_IMAGE_URL.to_string(), - ERNEST_SCARED_STUPID_IMAGE_URL.to_string(), - ], - prompt: "add the ghost and scared man to the image of the t-rex skeleton, make it look spooky but friendly", - num_images: EnqueueGptImage1p5EditImageNumImages::Two, - mask_image_url: None, - image_size: None, - background: None, - quality: None, - input_fidelity: None, + request: EnqueueGptImage1p5EditImageRequest { + image_urls: vec![ + GHOST_IMAGE_URL.to_string(), + TREX_SKELETON_IMAGE_URL.to_string(), + ERNEST_SCARED_STUPID_IMAGE_URL.to_string(), + ], + prompt: "add the ghost and scared man to the image of the t-rex skeleton, make it look spooky but friendly".to_string(), + num_images: EnqueueGptImage1p5EditImageNumImages::Two, + mask_image_url: None, + image_size: None, + background: None, + quality: None, + input_fidelity: None, + output_format: None, + }, api_key: &api_key, webhook_url: "https://example.com/webhook", - output_format: None, }; let result = enqueue_gpt_image_1p5_image_edit_webhook(args).await?; diff --git a/crates/api_clients/fal_client/src/requests/webhook/image/edit/enqueue_gpt_image_2_edit_image_webhook.rs b/crates/api_clients/fal_client/src/requests/webhook/image/edit/enqueue_gpt_image_2_edit_image_webhook.rs index b6ac2900cc..2848276b9d 100644 --- a/crates/api_clients/fal_client/src/requests/webhook/image/edit/enqueue_gpt_image_2_edit_image_webhook.rs +++ b/crates/api_clients/fal_client/src/requests/webhook/image/edit/enqueue_gpt_image_2_edit_image_webhook.rs @@ -9,22 +9,27 @@ use crate::requests::webhook::image::edit::enqueue_gpt_image_2_edit_image_webhoo use crate::requests::webhook::image::edit::enqueue_gpt_image_2_edit_image_webhook::EnqueueGptImage2EditImageSize::SquareHd; pub struct EnqueueGptImage2EditImageArgs<'a, R: IntoUrl> { - // Request required - pub prompt: &'a str, - pub image_urls: Vec, - pub num_images: EnqueueGptImage2EditImageNumImages, - - // Optional args - pub mask_url: Option, - pub image_size: Option, - pub quality: Option, - pub output_format: Option, + pub request: EnqueueGptImage2EditImageRequest, // Fulfillment pub webhook_url: R, pub api_key: &'a FalApiKey, } +#[derive(Clone, Debug)] +pub struct EnqueueGptImage2EditImageRequest { + // Required + pub prompt: String, + pub image_urls: Vec, + pub num_images: EnqueueGptImage2EditImageNumImages, + + // Optional + pub mask_url: Option, + pub image_size: Option, + pub quality: Option, + pub output_format: Option, +} + #[derive(Copy, Clone, Debug)] pub enum EnqueueGptImage2EditImageNumImages { One, @@ -58,8 +63,7 @@ pub enum EnqueueGptImage2EditImageOutputFormat { Webp, } - -impl FalRequestCostCalculator for EnqueueGptImage2EditImageArgs<'_, U> { +impl FalRequestCostCalculator for EnqueueGptImage2EditImageRequest { fn calculate_cost_in_cents(&self) -> UsdCents { // Cost table (per image) by approximate pixel dimensions: // @@ -99,19 +103,19 @@ impl FalRequestCostCalculator for EnqueueGptImage2EditImageArgs<'_, } } - pub async fn enqueue_gpt_image_2_edit_image_webhook( args: EnqueueGptImage2EditImageArgs<'_, R> ) -> Result { + let req = args.request; - let num_images = match args.num_images { + let num_images = match req.num_images { EnqueueGptImage2EditImageNumImages::One => 1, EnqueueGptImage2EditImageNumImages::Two => 2, EnqueueGptImage2EditImageNumImages::Three => 3, EnqueueGptImage2EditImageNumImages::Four => 4, }; - let image_size = args.image_size + let image_size = req.image_size .map(|s| match s { EnqueueGptImage2EditImageSize::SquareHd => "square_hd", EnqueueGptImage2EditImageSize::Square => "square", @@ -123,7 +127,7 @@ pub async fn enqueue_gpt_image_2_edit_image_webhook( }) .map(|size| size.to_string()); - let quality = args.quality + let quality = req.quality .map(|s| match s { EnqueueGptImage2EditImageQuality::Low => "low", EnqueueGptImage2EditImageQuality::Medium => "medium", @@ -131,7 +135,7 @@ pub async fn enqueue_gpt_image_2_edit_image_webhook( }) .map(|quality| quality.to_string()); - let output_format = args.output_format + let output_format = req.output_format .map(|s| match s { EnqueueGptImage2EditImageOutputFormat::Jpeg => "jpeg", EnqueueGptImage2EditImageOutputFormat::Png => "png", @@ -141,12 +145,12 @@ pub async fn enqueue_gpt_image_2_edit_image_webhook( .unwrap_or_else(|| "png".to_string()); let request = GptImage2EditImageInput { - prompt: args.prompt.to_string(), - image_urls: args.image_urls, + prompt: req.prompt, + image_urls: req.image_urls, num_images: Some(num_images), output_format: Some(output_format), // Optionals - mask_url: args.mask_url, + mask_url: req.mask_url, image_size, quality, }; @@ -162,7 +166,10 @@ pub async fn enqueue_gpt_image_2_edit_image_webhook( #[cfg(test)] mod tests { use crate::creds::fal_api_key::FalApiKey; - use crate::requests::webhook::image::edit::enqueue_gpt_image_2_edit_image_webhook::{enqueue_gpt_image_2_edit_image_webhook, EnqueueGptImage2EditImageArgs, EnqueueGptImage2EditImageNumImages}; + use crate::requests::webhook::image::edit::enqueue_gpt_image_2_edit_image_webhook::{ + enqueue_gpt_image_2_edit_image_webhook, EnqueueGptImage2EditImageArgs, + EnqueueGptImage2EditImageNumImages, EnqueueGptImage2EditImageRequest, + }; use errors::AnyhowResult; use std::fs::read_to_string; use test_data::web::image_urls::{ERNEST_SCARED_STUPID_IMAGE_URL, GHOST_IMAGE_URL, TREX_SKELETON_IMAGE_URL}; @@ -176,19 +183,21 @@ mod tests { let api_key = FalApiKey::from_str(&secret); let args = EnqueueGptImage2EditImageArgs { - image_urls: vec![ - GHOST_IMAGE_URL.to_string(), - TREX_SKELETON_IMAGE_URL.to_string(), - ERNEST_SCARED_STUPID_IMAGE_URL.to_string(), - ], - prompt: "add the ghost and scared man to the image of the t-rex skeleton, make it look spooky but friendly", - num_images: EnqueueGptImage2EditImageNumImages::Two, - mask_url: None, - image_size: None, - quality: None, + request: EnqueueGptImage2EditImageRequest { + image_urls: vec![ + GHOST_IMAGE_URL.to_string(), + TREX_SKELETON_IMAGE_URL.to_string(), + ERNEST_SCARED_STUPID_IMAGE_URL.to_string(), + ], + prompt: "add the ghost and scared man to the image of the t-rex skeleton, make it look spooky but friendly".to_string(), + num_images: EnqueueGptImage2EditImageNumImages::Two, + mask_url: None, + image_size: None, + quality: None, + output_format: None, + }, api_key: &api_key, webhook_url: "https://example.com/webhook", - output_format: None, }; let result = enqueue_gpt_image_2_edit_image_webhook(args).await?; diff --git a/crates/api_clients/fal_client/src/requests/webhook/image/edit/enqueue_nano_banana_pro_edit_image_webhook.rs b/crates/api_clients/fal_client/src/requests/webhook/image/edit/enqueue_nano_banana_pro_edit_image_webhook.rs index 94369c1f29..ded123f82e 100644 --- a/crates/api_clients/fal_client/src/requests/webhook/image/edit/enqueue_nano_banana_pro_edit_image_webhook.rs +++ b/crates/api_clients/fal_client/src/requests/webhook/image/edit/enqueue_nano_banana_pro_edit_image_webhook.rs @@ -7,18 +7,20 @@ use crate::requests::api::webhook_response::WebhookResponse; use reqwest::IntoUrl; pub struct EnqueueNanoBananaProEditImageArgs<'a, R: IntoUrl> { - // Request required - pub prompt: &'a str, + pub request: EnqueueNanoBananaProEditImageRequest, + pub webhook_url: R, + pub api_key: &'a FalApiKey, +} + +#[derive(Clone, Debug)] +pub struct EnqueueNanoBananaProEditImageRequest { + pub prompt: String, pub image_urls: Vec, pub num_images: EnqueueNanoBananaProEditImageNumImages, // Optional args pub resolution: Option, pub aspect_ratio: Option, - - // Fulfillment - pub webhook_url: R, - pub api_key: &'a FalApiKey, } #[derive(Copy, Clone, Debug)] @@ -58,7 +60,7 @@ pub enum EnqueueNanoBananaProEditImageAspectRatio { } -impl FalRequestCostCalculator for EnqueueNanoBananaProEditImageArgs<'_, U> { +impl FalRequestCostCalculator for EnqueueNanoBananaProEditImageRequest { fn calculate_cost_in_cents(&self) -> UsdCents { // Your request will cost $0.15 per image. // For $1.00, you can run this model 7 times. @@ -84,15 +86,16 @@ impl FalRequestCostCalculator for EnqueueNanoBananaProEditImageArgs pub async fn enqueue_nano_banana_pro_image_edit_webhook( args: EnqueueNanoBananaProEditImageArgs<'_, R> ) -> Result { + let req = args.request; - let num_images = match args.num_images { + let num_images = match req.num_images { EnqueueNanoBananaProEditImageNumImages::One => 1, EnqueueNanoBananaProEditImageNumImages::Two => 2, EnqueueNanoBananaProEditImageNumImages::Three => 3, EnqueueNanoBananaProEditImageNumImages::Four => 4, }; - let resolution = args.resolution + let resolution = req.resolution .map(|resolution| match resolution { EnqueueNanoBananaProEditImageResolution::OneK => "1K", EnqueueNanoBananaProEditImageResolution::TwoK => "2K", @@ -100,7 +103,7 @@ pub async fn enqueue_nano_banana_pro_image_edit_webhook( }) .map(|resolution| resolution.to_string()); - let aspect_ratio = args.aspect_ratio + let aspect_ratio = req.aspect_ratio .map(|aspect_ratio| match aspect_ratio { // Auto EnqueueNanoBananaProEditImageAspectRatio::Auto => "auto", @@ -121,8 +124,8 @@ pub async fn enqueue_nano_banana_pro_image_edit_webhook( .map(|aspect_ratio| aspect_ratio.to_string()); let request = NanoBananaProEditImageInput { - prompt: args.prompt.to_string(), - image_urls: args.image_urls, + prompt: req.prompt, + image_urls: req.image_urls, num_images: Some(num_images), // Optionals aspect_ratio, @@ -142,7 +145,7 @@ pub async fn enqueue_nano_banana_pro_image_edit_webhook( #[cfg(test)] mod tests { use crate::creds::fal_api_key::FalApiKey; - use crate::requests::webhook::image::edit::enqueue_nano_banana_pro_edit_image_webhook::{enqueue_nano_banana_pro_image_edit_webhook, EnqueueNanoBananaProEditImageArgs, EnqueueNanoBananaProEditImageAspectRatio, EnqueueNanoBananaProEditImageNumImages, EnqueueNanoBananaProEditImageResolution}; + use crate::requests::webhook::image::edit::enqueue_nano_banana_pro_edit_image_webhook::{enqueue_nano_banana_pro_image_edit_webhook, EnqueueNanoBananaProEditImageArgs, EnqueueNanoBananaProEditImageAspectRatio, EnqueueNanoBananaProEditImageNumImages, EnqueueNanoBananaProEditImageRequest, EnqueueNanoBananaProEditImageResolution}; use errors::AnyhowResult; use std::fs::read_to_string; use test_data::web::image_urls::{ERNEST_SCARED_STUPID_IMAGE_URL, GHOST_IMAGE_URL, TREX_SKELETON_IMAGE_URL}; @@ -156,15 +159,17 @@ mod tests { let api_key = FalApiKey::from_str(&secret); let args = EnqueueNanoBananaProEditImageArgs { - image_urls: vec![ - GHOST_IMAGE_URL.to_string(), - TREX_SKELETON_IMAGE_URL.to_string(), - ERNEST_SCARED_STUPID_IMAGE_URL.to_string(), - ], - prompt: "add the ghost and scared man to the image of the t-rex skeleton, make it look spooky but friendly", - num_images: EnqueueNanoBananaProEditImageNumImages::Two, - aspect_ratio: Some(EnqueueNanoBananaProEditImageAspectRatio::SixteenByNine), - resolution: Some(EnqueueNanoBananaProEditImageResolution::TwoK), + request: EnqueueNanoBananaProEditImageRequest { + image_urls: vec![ + GHOST_IMAGE_URL.to_string(), + TREX_SKELETON_IMAGE_URL.to_string(), + ERNEST_SCARED_STUPID_IMAGE_URL.to_string(), + ], + prompt: "add the ghost and scared man to the image of the t-rex skeleton, make it look spooky but friendly".to_string(), + num_images: EnqueueNanoBananaProEditImageNumImages::Two, + aspect_ratio: Some(EnqueueNanoBananaProEditImageAspectRatio::SixteenByNine), + resolution: Some(EnqueueNanoBananaProEditImageResolution::TwoK), + }, api_key: &api_key, webhook_url: "https://example.com/webhook", };