From 063168e4c42e12f62bea152f5ed4e073d2b71e3a Mon Sep 17 00:00:00 2001 From: Brandon Thomas Date: Thu, 28 Aug 2025 00:27:58 -0400 Subject: [PATCH] gemini flash --- .../enqueue_gemini_25_flash_edit_webhook.rs | 87 +++++++++++++++++++ .../enqueue_gpt_image_1_edit_image_webhook.rs | 4 +- .../src/requests/webhook/image/edit/mod.rs | 2 + .../src/requests/webhook/image/mod.rs | 1 - crates/lib/test_data/src/web/image_urls.rs | 3 + .../fal_ai/gemini_25_flash_image/edit.rs | 6 +- 6 files changed, 97 insertions(+), 6 deletions(-) create mode 100644 crates/api_clients/fal_client/src/requests/webhook/image/edit/enqueue_gemini_25_flash_edit_webhook.rs rename crates/api_clients/fal_client/src/requests/webhook/image/{ => edit}/enqueue_gpt_image_1_edit_image_webhook.rs (93%) 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 new file mode 100644 index 0000000000..f31e685162 --- /dev/null +++ b/crates/api_clients/fal_client/src/requests/webhook/image/edit/enqueue_gemini_25_flash_edit_webhook.rs @@ -0,0 +1,87 @@ +use crate::creds::fal_api_key::FalApiKey; +use crate::error::classify_fal_error::classify_fal_error; +use crate::error::fal_error_plus::FalErrorPlus; +use fal::endpoints::fal_ai::gemini_25_flash_image::edit::gemini_25_flash_image_edit; +use fal::prelude::fal_ai::gemini_25_flash_image::edit::Gemini25FlashImageEditInput; +use fal::webhook::WebhookResponse; +use reqwest::IntoUrl; + +pub struct Gemini25FlashEditArgs<'a, R: IntoUrl> { + // Request required + pub prompt: &'a str, + pub image_urls: Vec, + pub num_images: Gemini25FlashEditNumImages, + + // Fulfillment + pub webhook_url: R, + pub api_key: &'a FalApiKey, +} + +#[derive(Copy, Clone, Debug)] +pub enum Gemini25FlashEditNumImages { + One, + Two, + Three, + Four, +} + + +pub async fn enqueue_gemini_25_flash_edit_webhook( + args: Gemini25FlashEditArgs<'_, R> +) -> Result { + + let num_images = match args.num_images { + Gemini25FlashEditNumImages::One => 1, + Gemini25FlashEditNumImages::Two => 2, + Gemini25FlashEditNumImages::Three => 3, + Gemini25FlashEditNumImages::Four => 4, + }; + + let request = Gemini25FlashImageEditInput { + prompt: args.prompt.to_string(), + image_urls: args.image_urls, + // Constants + num_images: Some(num_images), + output_format: Some("png".to_string()), + }; + + let result = gemini_25_flash_image_edit(request) + .with_api_key(&args.api_key.0) + .queue_webhook(args.webhook_url) + .await; + + result.map_err(|err| classify_fal_error(err)) +} + +#[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 errors::AnyhowResult; + use std::fs::read_to_string; + use test_data::web::image_urls::{GHOST_IMAGE_URL, TREX_SKELETON_IMAGE_URL}; + + #[tokio::test] + #[ignore] + async fn test() -> AnyhowResult<()> { + // XXX: Don't commit secrets! + let secret = read_to_string("/Users/bt/Artcraft/credentials/fal_api_key.txt")?; + + 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, + prompt: "add the ghost to the image of the t-rex skeleton, make it look spooky but friendly", + api_key: &api_key, + webhook_url: "https://example.com/webhook", + }; + + let result = enqueue_gemini_25_flash_edit_webhook(args).await?; + + Ok(()) + } +} diff --git a/crates/api_clients/fal_client/src/requests/webhook/image/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 similarity index 93% rename from crates/api_clients/fal_client/src/requests/webhook/image/enqueue_gpt_image_1_edit_image_webhook.rs rename to crates/api_clients/fal_client/src/requests/webhook/image/edit/enqueue_gpt_image_1_edit_image_webhook.rs index 92b0497324..389f18dfb2 100644 --- a/crates/api_clients/fal_client/src/requests/webhook/image/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 @@ -21,7 +21,7 @@ pub struct GptEditImageByokArgs<'a, V: IntoUrl> { } #[derive(Copy, Clone, Debug)] -pub enum GptEditImageSize{ +pub enum GptEditImageSize { Auto, Square, Horizontal, @@ -92,7 +92,7 @@ pub async fn enqueue_gpt_image_1_edit_image_webhook( mod tests { use crate::creds::fal_api_key::FalApiKey; use crate::creds::open_ai_api_key::OpenAiApiKey; - use crate::requests::webhook::image::enqueue_gpt_image_1_edit_image_webhook::{enqueue_gpt_image_1_edit_image_webhook, GptEditImageByokArgs, GptEditImageNumImages, GptEditImageQuality, GptEditImageSize}; + use crate::requests::webhook::image::edit::enqueue_gpt_image_1_edit_image_webhook::{enqueue_gpt_image_1_edit_image_webhook, GptEditImageByokArgs, GptEditImageNumImages, GptEditImageQuality, GptEditImageSize}; use errors::AnyhowResult; use std::fs::read_to_string; use test_data::web::image_urls::{ERNEST_SCARED_STUPID_IMAGE_URL, GHOST_IMAGE_URL, GRASSY_HILL_TRANSPARENT_IMAGE_URL}; diff --git a/crates/api_clients/fal_client/src/requests/webhook/image/edit/mod.rs b/crates/api_clients/fal_client/src/requests/webhook/image/edit/mod.rs index b9b58ed7d9..aaf27b4faf 100644 --- a/crates/api_clients/fal_client/src/requests/webhook/image/edit/mod.rs +++ b/crates/api_clients/fal_client/src/requests/webhook/image/edit/mod.rs @@ -1,3 +1,5 @@ pub mod enqueue_flux_pro_kontext_max_edit_webhook; +pub mod enqueue_gemini_25_flash_edit_webhook; +pub mod enqueue_gpt_image_1_edit_image_webhook; pub mod enqueue_qwen_image_edit_webhook; pub mod enqueue_seededit_v3_edit_webhook; \ No newline at end of file diff --git a/crates/api_clients/fal_client/src/requests/webhook/image/mod.rs b/crates/api_clients/fal_client/src/requests/webhook/image/mod.rs index cd64404830..3c32e1f5e7 100644 --- a/crates/api_clients/fal_client/src/requests/webhook/image/mod.rs +++ b/crates/api_clients/fal_client/src/requests/webhook/image/mod.rs @@ -3,7 +3,6 @@ pub mod enqueue_flux_1_dev_text_to_image_webhook; pub mod enqueue_flux_1_schnell_text_to_image_webhook; pub mod enqueue_flux_pro_11_text_to_image_webhook; pub mod enqueue_flux_pro_11_ultra_text_to_image_webhook; -pub mod enqueue_gpt_image_1_edit_image_webhook; pub mod enqueue_gpt_image_1_text_to_image_webhook; pub mod infill; pub mod remove_background_rembg_webhook; diff --git a/crates/lib/test_data/src/web/image_urls.rs b/crates/lib/test_data/src/web/image_urls.rs index e7b83a2812..d4eb40880a 100644 --- a/crates/lib/test_data/src/web/image_urls.rs +++ b/crates/lib/test_data/src/web/image_urls.rs @@ -32,3 +32,6 @@ pub const TALL_MOCHI_WITH_GLASSES_IMAGE_URL : &str = "https://cdn-2.fakeyou.com/ // media token: m_7x18h6qnyay4a42kyyyw2xctasx5k9 pub const TALL_MOCHI_WITH_GLASSES_GLASSES_MASK_IMAGE_URL : &str = "https://cdn-2.fakeyou.com/media/r/e/j/b/p/rejbp61m56hqx4a498xh7j47vkjd7jnh/upload_rejbp61m56hqx4a498xh7j47vkjd7jnh.png"; + +// media token: m_77cpdyaby60z0qv9g6tv67gw2a1337 +pub const TREX_SKELETON_IMAGE_URL : &str = "https://cdn-2.fakeyou.com/media/f/4/j/5/3/f4j53296sc35wqs3csgw4j4vvjf5yyxe/image_f4j53296sc35wqs3csgw4j4vvjf5yyxe.png"; diff --git a/crates/vendor/fal-rs/src/endpoints/fal_ai/gemini_25_flash_image/edit.rs b/crates/vendor/fal-rs/src/endpoints/fal_ai/gemini_25_flash_image/edit.rs index 1ecf259fbd..0a07eaa3ee 100644 --- a/crates/vendor/fal-rs/src/endpoints/fal_ai/gemini_25_flash_image/edit.rs +++ b/crates/vendor/fal-rs/src/endpoints/fal_ai/gemini_25_flash_image/edit.rs @@ -14,9 +14,9 @@ pub struct Gemini25FlashImageEditInput { #[serde(skip_serializing_if = "Option::is_none")] pub output_format: Option, - /// Resolution, eg. "720p" - #[serde(skip_serializing_if = "Option::is_none")] - pub resolution: Option, + // /// Resolution, eg. "720p" + // #[serde(skip_serializing_if = "Option::is_none")] + // pub resolution: Option, } #[derive(Debug, Serialize, Deserialize, Default)]