mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-06 02:00:46 +00:00
wip
This commit is contained in:
1 parent
a499bf44d3
commit
e047736100
9 files changed
+265
-195
No files matched your search
+24
-14
@@ -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<U: IntoUrl>(
|
||||
args: Flux1DevEditImageArgs<'_, U>
|
||||
) -> Result<WebhookResponse, FalErrorPlus> {
|
||||
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<U: IntoUrl>(
|
||||
};
|
||||
|
||||
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",
|
||||
};
|
||||
|
||||
+23
-14
@@ -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<Flux1SchnellEditImageSize>,
|
||||
|
||||
// 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<U: IntoUrl>(
|
||||
args: Flux1SchnellEditImageArgs<'_, U>
|
||||
) -> Result<WebhookResponse, FalErrorPlus> {
|
||||
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<U: IntoUrl>(
|
||||
}.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",
|
||||
};
|
||||
|
||||
+15
-8
@@ -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<U: IntoUrl, R: IntoUrl>(
|
||||
args: FluxProKontextMaxArgs<'_, U, R>
|
||||
) -> Result<WebhookResponse, FalErrorPlus> {
|
||||
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<U: IntoUrl, R: IntoUrl>(
|
||||
};
|
||||
|
||||
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<U: IntoUrl, R: IntoUrl>(
|
||||
#[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?;
|
||||
|
||||
+27
-20
@@ -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<String>,
|
||||
pub num_images: Gemini25FlashEditNumImages,
|
||||
|
||||
// Optional
|
||||
pub aspect_ratio: Option<Gemini25FlashEditAspectRatio>,
|
||||
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<String>,
|
||||
pub num_images: Gemini25FlashEditNumImages,
|
||||
|
||||
// Optional
|
||||
pub aspect_ratio: Option<Gemini25FlashEditAspectRatio>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum Gemini25FlashEditNumImages {
|
||||
One,
|
||||
@@ -50,7 +54,7 @@ pub enum Gemini25FlashEditAspectRatio {
|
||||
}
|
||||
|
||||
|
||||
impl <U: IntoUrl> 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 <U: IntoUrl> FalRequestCostCalculator for Gemini25FlashEditArgs<'_, U> {
|
||||
pub async fn enqueue_gemini_25_flash_edit_webhook<R: IntoUrl>(
|
||||
args: Gemini25FlashEditArgs<'_, R>
|
||||
) -> Result<WebhookResponse, FalErrorPlus> {
|
||||
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<R: IntoUrl>(
|
||||
.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<R: IntoUrl>(
|
||||
#[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",
|
||||
};
|
||||
|
||||
+30
-23
@@ -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<String>,
|
||||
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<String>,
|
||||
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 <U: IntoUrl> 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 <U: IntoUrl> FalRequestCostCalculator for GptEditImageByokArgs<'_, U> {
|
||||
pub async fn enqueue_gpt_image_1_byok_edit_image_webhook<V: IntoUrl>(
|
||||
args: GptEditImageByokArgs<'_, V>
|
||||
) -> Result<WebhookResponse, FalErrorPlus> {
|
||||
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<V: IntoUrl>(
|
||||
};
|
||||
|
||||
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",
|
||||
|
||||
+36
-29
@@ -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<String>,
|
||||
pub num_images: EnqueueGptImage1EditImageNumImages,
|
||||
|
||||
@@ -27,10 +34,6 @@ pub struct EnqueueGptImage1EditImageArgs<'a, R: IntoUrl> {
|
||||
pub input_fidelity: Option<EnqueueGptImage1EditImageInputFidelity>,
|
||||
pub background: Option<EnqueueGptImage1EditImageBackground>,
|
||||
pub output_format: Option<EnqueueGptImage1EditImageOutputFormat>,
|
||||
|
||||
// Fulfillment
|
||||
pub webhook_url: R,
|
||||
pub api_key: &'a FalApiKey,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
@@ -79,7 +82,7 @@ pub enum EnqueueGptImage1EditImageOutputFormat {
|
||||
Webp,
|
||||
}
|
||||
|
||||
impl<U: IntoUrl> 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<U: IntoUrl> FalRequestCostCalculator for EnqueueGptImage1EditImageArgs<'_,
|
||||
pub async fn enqueue_gpt_image_1_edit_image_webhook<R: IntoUrl>(
|
||||
args: EnqueueGptImage1EditImageArgs<'_, R>,
|
||||
) -> Result<WebhookResponse, FalErrorPlus> {
|
||||
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<R: IntoUrl>(
|
||||
.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<R: IntoUrl>(
|
||||
.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<R: IntoUrl>(
|
||||
.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<R: IntoUrl>(
|
||||
.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<R: IntoUrl>(
|
||||
});
|
||||
|
||||
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",
|
||||
};
|
||||
|
||||
+42
-33
@@ -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<String>,
|
||||
pub num_images: EnqueueGptImage1p5EditImageNumImages,
|
||||
|
||||
// Optional args
|
||||
// Optional
|
||||
pub mask_image_url: Option<String>,
|
||||
pub image_size: Option<EnqueueGptImage1p5EditImageSize>,
|
||||
pub background: Option<EnqueueGptImage1p5EditImageBackground>,
|
||||
pub quality: Option<EnqueueGptImage1p5EditImageQuality>,
|
||||
pub input_fidelity: Option<EnqueueGptImage1p5EditImageInputFidelity>,
|
||||
pub output_format: Option<EnqueueGptImage1p5EditImageOutputFormat>,
|
||||
|
||||
// Fulfillment
|
||||
pub webhook_url: R,
|
||||
pub api_key: &'a FalApiKey,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
@@ -70,8 +75,7 @@ pub enum EnqueueGptImage1p5EditImageOutputFormat {
|
||||
Webp,
|
||||
}
|
||||
|
||||
|
||||
impl <U: IntoUrl> 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 <U: IntoUrl> FalRequestCostCalculator for EnqueueGptImage1p5EditImageArgs<'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub async fn enqueue_gpt_image_1p5_image_edit_webhook<R: IntoUrl>(
|
||||
args: EnqueueGptImage1p5EditImageArgs<'_, R>
|
||||
) -> Result<WebhookResponse, FalErrorPlus> {
|
||||
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<R: IntoUrl>(
|
||||
})
|
||||
.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<R: IntoUrl>(
|
||||
})
|
||||
.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<R: IntoUrl>(
|
||||
})
|
||||
.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<R: IntoUrl>(
|
||||
.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<R: IntoUrl>(
|
||||
#[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?;
|
||||
|
||||
+41
-32
@@ -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<String>,
|
||||
pub num_images: EnqueueGptImage2EditImageNumImages,
|
||||
|
||||
// Optional args
|
||||
pub mask_url: Option<String>,
|
||||
pub image_size: Option<EnqueueGptImage2EditImageSize>,
|
||||
pub quality: Option<EnqueueGptImage2EditImageQuality>,
|
||||
pub output_format: Option<EnqueueGptImage2EditImageOutputFormat>,
|
||||
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<String>,
|
||||
pub num_images: EnqueueGptImage2EditImageNumImages,
|
||||
|
||||
// Optional
|
||||
pub mask_url: Option<String>,
|
||||
pub image_size: Option<EnqueueGptImage2EditImageSize>,
|
||||
pub quality: Option<EnqueueGptImage2EditImageQuality>,
|
||||
pub output_format: Option<EnqueueGptImage2EditImageOutputFormat>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum EnqueueGptImage2EditImageNumImages {
|
||||
One,
|
||||
@@ -58,8 +63,7 @@ pub enum EnqueueGptImage2EditImageOutputFormat {
|
||||
Webp,
|
||||
}
|
||||
|
||||
|
||||
impl <U: IntoUrl> 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 <U: IntoUrl> FalRequestCostCalculator for EnqueueGptImage2EditImageArgs<'_,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub async fn enqueue_gpt_image_2_edit_image_webhook<R: IntoUrl>(
|
||||
args: EnqueueGptImage2EditImageArgs<'_, R>
|
||||
) -> Result<WebhookResponse, FalErrorPlus> {
|
||||
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<R: IntoUrl>(
|
||||
})
|
||||
.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<R: IntoUrl>(
|
||||
})
|
||||
.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<R: IntoUrl>(
|
||||
.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<R: IntoUrl>(
|
||||
#[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?;
|
||||
|
||||
+27
-22
@@ -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<String>,
|
||||
pub num_images: EnqueueNanoBananaProEditImageNumImages,
|
||||
|
||||
// Optional args
|
||||
pub resolution: Option<EnqueueNanoBananaProEditImageResolution>,
|
||||
pub aspect_ratio: Option<EnqueueNanoBananaProEditImageAspectRatio>,
|
||||
|
||||
// Fulfillment
|
||||
pub webhook_url: R,
|
||||
pub api_key: &'a FalApiKey,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
@@ -58,7 +60,7 @@ pub enum EnqueueNanoBananaProEditImageAspectRatio {
|
||||
}
|
||||
|
||||
|
||||
impl <U: IntoUrl> 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 <U: IntoUrl> FalRequestCostCalculator for EnqueueNanoBananaProEditImageArgs
|
||||
pub async fn enqueue_nano_banana_pro_image_edit_webhook<R: IntoUrl>(
|
||||
args: EnqueueNanoBananaProEditImageArgs<'_, R>
|
||||
) -> Result<WebhookResponse, FalErrorPlus> {
|
||||
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<R: IntoUrl>(
|
||||
})
|
||||
.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<R: IntoUrl>(
|
||||
.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<R: IntoUrl>(
|
||||
#[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",
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user