mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-04 01:18:34 +00:00
api bindings
This commit is contained in:
1 parent
cf1f4eb8c8
commit
26db6cdf32
8 files changed
+475
No files matched your search
+47
@@ -0,0 +1,47 @@
|
||||
use crate::requests::api::fal_request::FalRequest;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Default)]
|
||||
pub struct GptImage2EditImageInput {
|
||||
pub prompt: String,
|
||||
|
||||
pub image_urls: Vec<String>,
|
||||
|
||||
/// The URL of the mask image to use for the generation. This indicates what part of the image to edit.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub mask_url: Option<String>,
|
||||
|
||||
/// Possible enum values: square_hd, square, portrait_4_3, portrait_16_9, landscape_4_3, landscape_16_9, auto
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub image_size: Option<String>,
|
||||
|
||||
/// "low", "medium", "high"
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub quality: Option<String>,
|
||||
|
||||
/// 1 - 4
|
||||
/// Default: 1
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub num_images: Option<u8>,
|
||||
|
||||
/// "jpeg", "png", "webp"
|
||||
/// Default: "png"
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub output_format: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct GptImage2EditImageFile {
|
||||
pub url: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct GptImage2EditImageOutput {
|
||||
pub images: Vec<GptImage2EditImageFile>,
|
||||
}
|
||||
|
||||
pub fn gpt_image_2_edit_image(
|
||||
params: GptImage2EditImageInput,
|
||||
) -> FalRequest<GptImage2EditImageInput, GptImage2EditImageOutput> {
|
||||
FalRequest::new("fal-ai/gpt-image-2/edit", params)
|
||||
}
|
||||
@@ -5,6 +5,7 @@ pub mod http_gemini_25_flash_edit;
|
||||
pub mod http_gpt_image_1_edit_image;
|
||||
pub mod http_gpt_image_1_non_byok_edit_image;
|
||||
pub mod http_gpt_image_1p5_edit_image;
|
||||
pub mod http_gpt_image_2_edit_image;
|
||||
pub mod http_nano_banana_2_edit_image;
|
||||
pub mod http_nano_banana_pro_edit_image;
|
||||
pub mod http_qwen_image_edit;
|
||||
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
use crate::requests::api::fal_request::FalRequest;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Default)]
|
||||
pub struct GptImage2TextToImageInput {
|
||||
pub prompt: String,
|
||||
|
||||
/// "1024x768", "1024x1024", "1024x1536", "1920x1080", "2560x1440", "3840x2160"
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub image_size: Option<String>,
|
||||
|
||||
/// "low", "medium", "high"
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub quality: Option<String>,
|
||||
|
||||
/// 1 - 4
|
||||
/// Default: 1
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub num_images: Option<u8>,
|
||||
|
||||
/// "jpeg", "png", "webp"
|
||||
/// Default: "png"
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub output_format: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct GptImage2TextToImageFile {
|
||||
pub url: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct GptImage2TextToImageOutput {
|
||||
pub images: Vec<GptImage2TextToImageFile>,
|
||||
}
|
||||
|
||||
pub fn gpt_image_2_text_to_image(
|
||||
params: GptImage2TextToImageInput,
|
||||
) -> FalRequest<GptImage2TextToImageInput, GptImage2TextToImageOutput> {
|
||||
FalRequest::new("fal-ai/gpt-image-2", params)
|
||||
}
|
||||
@@ -6,6 +6,7 @@ pub mod http_gemini_25_flash_text_to_image;
|
||||
pub mod http_gpt_image_1_non_byok_text_to_image;
|
||||
pub mod http_gpt_image_1_text_to_image;
|
||||
pub mod http_gpt_image_1p5_text_to_image;
|
||||
pub mod http_gpt_image_2_text_to_image;
|
||||
pub mod http_nano_banana_2_text_to_image;
|
||||
pub mod http_nano_banana_pro_text_to_image;
|
||||
pub mod http_seedream_4_text_to_image;
|
||||
|
||||
+197
@@ -0,0 +1,197 @@
|
||||
use crate::creds::fal_api_key::FalApiKey;
|
||||
use crate::error::classify_fal_error::classify_fal_error;
|
||||
use crate::error::fal_error_plus::FalErrorPlus;
|
||||
use crate::requests::traits::fal_request_cost_calculator_trait::{FalRequestCostCalculator, UsdCents};
|
||||
use crate::requests::http::image::edit::http_gpt_image_2_edit_image::{gpt_image_2_edit_image, GptImage2EditImageInput};
|
||||
use crate::requests::api::webhook_response::WebhookResponse;
|
||||
use reqwest::IntoUrl;
|
||||
|
||||
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>,
|
||||
|
||||
// Fulfillment
|
||||
pub webhook_url: R,
|
||||
pub api_key: &'a FalApiKey,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum EnqueueGptImage2EditImageNumImages {
|
||||
One,
|
||||
Two,
|
||||
Three,
|
||||
Four,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum EnqueueGptImage2EditImageSize {
|
||||
/// 1024x768
|
||||
Landscape4x3,
|
||||
/// 1024x1024
|
||||
Square,
|
||||
/// 1024x1536
|
||||
Portrait,
|
||||
/// 1920x1080
|
||||
Landscape16x9,
|
||||
/// 2560x1440
|
||||
Qhd,
|
||||
/// 3840x2160
|
||||
Uhd4k,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum EnqueueGptImage2EditImageQuality {
|
||||
Low,
|
||||
Medium,
|
||||
High,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum EnqueueGptImage2EditImageOutputFormat {
|
||||
Jpeg,
|
||||
Png,
|
||||
Webp,
|
||||
}
|
||||
|
||||
|
||||
impl <U: IntoUrl> FalRequestCostCalculator for EnqueueGptImage2EditImageArgs<'_, U> {
|
||||
fn calculate_cost_in_cents(&self) -> UsdCents {
|
||||
// Cost table (per image):
|
||||
// 1024x768: low=$0.01, medium=$0.04, high=$0.15
|
||||
// 1024x1024: low=$0.01, medium=$0.06, high=$0.22
|
||||
// 1024x1536: low=$0.01, medium=$0.05, high=$0.17
|
||||
// 1920x1080: low=$0.01, medium=$0.04, high=$0.16
|
||||
// 2560x1440: low=$0.01, medium=$0.06, high=$0.23
|
||||
// 3840x2160: low=$0.02, medium=$0.11, high=$0.41
|
||||
let use_quality = self.quality.unwrap_or(EnqueueGptImage2EditImageQuality::High);
|
||||
let use_size = self.image_size.unwrap_or(EnqueueGptImage2EditImageSize::Square);
|
||||
let base_cost = match (use_quality, use_size) {
|
||||
(EnqueueGptImage2EditImageQuality::Low, EnqueueGptImage2EditImageSize::Uhd4k) => 2,
|
||||
(EnqueueGptImage2EditImageQuality::Low, _) => 1,
|
||||
(EnqueueGptImage2EditImageQuality::Medium, EnqueueGptImage2EditImageSize::Landscape4x3) => 4,
|
||||
(EnqueueGptImage2EditImageQuality::Medium, EnqueueGptImage2EditImageSize::Square) => 6,
|
||||
(EnqueueGptImage2EditImageQuality::Medium, EnqueueGptImage2EditImageSize::Portrait) => 5,
|
||||
(EnqueueGptImage2EditImageQuality::Medium, EnqueueGptImage2EditImageSize::Landscape16x9) => 4,
|
||||
(EnqueueGptImage2EditImageQuality::Medium, EnqueueGptImage2EditImageSize::Qhd) => 6,
|
||||
(EnqueueGptImage2EditImageQuality::Medium, EnqueueGptImage2EditImageSize::Uhd4k) => 11,
|
||||
(EnqueueGptImage2EditImageQuality::High, EnqueueGptImage2EditImageSize::Landscape4x3) => 15,
|
||||
(EnqueueGptImage2EditImageQuality::High, EnqueueGptImage2EditImageSize::Square) => 22,
|
||||
(EnqueueGptImage2EditImageQuality::High, EnqueueGptImage2EditImageSize::Portrait) => 17,
|
||||
(EnqueueGptImage2EditImageQuality::High, EnqueueGptImage2EditImageSize::Landscape16x9) => 16,
|
||||
(EnqueueGptImage2EditImageQuality::High, EnqueueGptImage2EditImageSize::Qhd) => 23,
|
||||
(EnqueueGptImage2EditImageQuality::High, EnqueueGptImage2EditImageSize::Uhd4k) => 41,
|
||||
};
|
||||
let cost = match self.num_images {
|
||||
EnqueueGptImage2EditImageNumImages::One => base_cost,
|
||||
EnqueueGptImage2EditImageNumImages::Two => base_cost * 2,
|
||||
EnqueueGptImage2EditImageNumImages::Three => base_cost * 3,
|
||||
EnqueueGptImage2EditImageNumImages::Four => base_cost * 4,
|
||||
};
|
||||
cost as UsdCents
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub async fn enqueue_gpt_image_2_edit_image_webhook<R: IntoUrl>(
|
||||
args: EnqueueGptImage2EditImageArgs<'_, R>
|
||||
) -> Result<WebhookResponse, FalErrorPlus> {
|
||||
|
||||
let num_images = match args.num_images {
|
||||
EnqueueGptImage2EditImageNumImages::One => 1,
|
||||
EnqueueGptImage2EditImageNumImages::Two => 2,
|
||||
EnqueueGptImage2EditImageNumImages::Three => 3,
|
||||
EnqueueGptImage2EditImageNumImages::Four => 4,
|
||||
};
|
||||
|
||||
let image_size = args.image_size
|
||||
.map(|s| match s {
|
||||
EnqueueGptImage2EditImageSize::Landscape4x3 => "1024x768",
|
||||
EnqueueGptImage2EditImageSize::Square => "1024x1024",
|
||||
EnqueueGptImage2EditImageSize::Portrait => "1024x1536",
|
||||
EnqueueGptImage2EditImageSize::Landscape16x9 => "1920x1080",
|
||||
EnqueueGptImage2EditImageSize::Qhd => "2560x1440",
|
||||
EnqueueGptImage2EditImageSize::Uhd4k => "3840x2160",
|
||||
})
|
||||
.map(|resolution| resolution.to_string());
|
||||
|
||||
let quality = args.quality
|
||||
.map(|s| match s {
|
||||
EnqueueGptImage2EditImageQuality::Low => "low",
|
||||
EnqueueGptImage2EditImageQuality::Medium => "medium",
|
||||
EnqueueGptImage2EditImageQuality::High => "high",
|
||||
})
|
||||
.map(|quality| quality.to_string());
|
||||
|
||||
let output_format = args.output_format
|
||||
.map(|s| match s {
|
||||
EnqueueGptImage2EditImageOutputFormat::Jpeg => "jpeg",
|
||||
EnqueueGptImage2EditImageOutputFormat::Png => "png",
|
||||
EnqueueGptImage2EditImageOutputFormat::Webp => "webp",
|
||||
})
|
||||
.map(|format| format.to_string())
|
||||
.unwrap_or_else(|| "png".to_string());
|
||||
|
||||
let request = GptImage2EditImageInput {
|
||||
prompt: args.prompt.to_string(),
|
||||
image_urls: args.image_urls,
|
||||
num_images: Some(num_images),
|
||||
output_format: Some(output_format),
|
||||
// Optionals
|
||||
mask_url: args.mask_url,
|
||||
image_size,
|
||||
quality,
|
||||
};
|
||||
|
||||
let result = gpt_image_2_edit_image(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_gpt_image_2_edit_image_webhook::{enqueue_gpt_image_2_edit_image_webhook, EnqueueGptImage2EditImageArgs, EnqueueGptImage2EditImageNumImages};
|
||||
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};
|
||||
|
||||
#[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 = 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,
|
||||
api_key: &api_key,
|
||||
webhook_url: "https://example.com/webhook",
|
||||
output_format: None,
|
||||
};
|
||||
|
||||
let result = enqueue_gpt_image_2_edit_image_webhook(args).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ pub mod enqueue_gemini_25_flash_edit_webhook;
|
||||
pub mod enqueue_gpt_image_1_byok_edit_image_webhook;
|
||||
pub mod enqueue_gpt_image_1_edit_image_webhook;
|
||||
pub mod enqueue_gpt_image_1p5_edit_image_webhook;
|
||||
pub mod enqueue_gpt_image_2_edit_image_webhook;
|
||||
pub mod enqueue_nano_banana_pro_edit_image_webhook;
|
||||
pub mod enqueue_qwen_image_edit_webhook;
|
||||
pub mod enqueue_seededit_v3_edit_webhook;
|
||||
+186
@@ -0,0 +1,186 @@
|
||||
use crate::creds::fal_api_key::FalApiKey;
|
||||
use crate::error::classify_fal_error::classify_fal_error;
|
||||
use crate::error::fal_error_plus::FalErrorPlus;
|
||||
use crate::requests::traits::fal_request_cost_calculator_trait::{FalRequestCostCalculator, UsdCents};
|
||||
use crate::requests::http::image::text::http_gpt_image_2_text_to_image::{gpt_image_2_text_to_image, GptImage2TextToImageInput};
|
||||
use crate::requests::api::webhook_response::WebhookResponse;
|
||||
use reqwest::IntoUrl;
|
||||
|
||||
pub struct EnqueueGptImage2TextToImageArgs<'a, R: IntoUrl> {
|
||||
// Request required
|
||||
pub prompt: &'a str,
|
||||
pub num_images: EnqueueGptImage2TextToImageNumImages,
|
||||
|
||||
// Optional args
|
||||
pub image_size: Option<EnqueueGptImage2TextToImageSize>,
|
||||
pub quality: Option<EnqueueGptImage2TextToImageQuality>,
|
||||
pub output_format: Option<EnqueueGptImage2TextToImageOutputFormat>,
|
||||
|
||||
// Fulfillment
|
||||
pub webhook_url: R,
|
||||
pub api_key: &'a FalApiKey,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum EnqueueGptImage2TextToImageNumImages {
|
||||
One,
|
||||
Two,
|
||||
Three,
|
||||
Four,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum EnqueueGptImage2TextToImageSize {
|
||||
/// 1024x768
|
||||
Landscape4x3,
|
||||
/// 1024x1024
|
||||
Square,
|
||||
/// 1024x1536
|
||||
Portrait,
|
||||
/// 1920x1080
|
||||
Landscape16x9,
|
||||
/// 2560x1440
|
||||
Qhd,
|
||||
/// 3840x2160
|
||||
Uhd4k,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum EnqueueGptImage2TextToImageQuality {
|
||||
Low,
|
||||
Medium,
|
||||
High,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum EnqueueGptImage2TextToImageOutputFormat {
|
||||
Jpeg,
|
||||
Png,
|
||||
Webp,
|
||||
}
|
||||
|
||||
|
||||
impl <U: IntoUrl> FalRequestCostCalculator for EnqueueGptImage2TextToImageArgs<'_, U> {
|
||||
fn calculate_cost_in_cents(&self) -> UsdCents {
|
||||
// Cost table (per image):
|
||||
// 1024x768: low=$0.01, medium=$0.04, high=$0.15
|
||||
// 1024x1024: low=$0.01, medium=$0.06, high=$0.22
|
||||
// 1024x1536: low=$0.01, medium=$0.05, high=$0.17
|
||||
// 1920x1080: low=$0.01, medium=$0.04, high=$0.16
|
||||
// 2560x1440: low=$0.01, medium=$0.06, high=$0.23
|
||||
// 3840x2160: low=$0.02, medium=$0.11, high=$0.41
|
||||
let use_quality = self.quality.unwrap_or(EnqueueGptImage2TextToImageQuality::High);
|
||||
let use_size = self.image_size.unwrap_or(EnqueueGptImage2TextToImageSize::Square);
|
||||
let base_cost = match (use_quality, use_size) {
|
||||
(EnqueueGptImage2TextToImageQuality::Low, EnqueueGptImage2TextToImageSize::Uhd4k) => 2,
|
||||
(EnqueueGptImage2TextToImageQuality::Low, _) => 1,
|
||||
(EnqueueGptImage2TextToImageQuality::Medium, EnqueueGptImage2TextToImageSize::Landscape4x3) => 4,
|
||||
(EnqueueGptImage2TextToImageQuality::Medium, EnqueueGptImage2TextToImageSize::Square) => 6,
|
||||
(EnqueueGptImage2TextToImageQuality::Medium, EnqueueGptImage2TextToImageSize::Portrait) => 5,
|
||||
(EnqueueGptImage2TextToImageQuality::Medium, EnqueueGptImage2TextToImageSize::Landscape16x9) => 4,
|
||||
(EnqueueGptImage2TextToImageQuality::Medium, EnqueueGptImage2TextToImageSize::Qhd) => 6,
|
||||
(EnqueueGptImage2TextToImageQuality::Medium, EnqueueGptImage2TextToImageSize::Uhd4k) => 11,
|
||||
(EnqueueGptImage2TextToImageQuality::High, EnqueueGptImage2TextToImageSize::Landscape4x3) => 15,
|
||||
(EnqueueGptImage2TextToImageQuality::High, EnqueueGptImage2TextToImageSize::Square) => 22,
|
||||
(EnqueueGptImage2TextToImageQuality::High, EnqueueGptImage2TextToImageSize::Portrait) => 17,
|
||||
(EnqueueGptImage2TextToImageQuality::High, EnqueueGptImage2TextToImageSize::Landscape16x9) => 16,
|
||||
(EnqueueGptImage2TextToImageQuality::High, EnqueueGptImage2TextToImageSize::Qhd) => 23,
|
||||
(EnqueueGptImage2TextToImageQuality::High, EnqueueGptImage2TextToImageSize::Uhd4k) => 41,
|
||||
};
|
||||
let cost = match self.num_images {
|
||||
EnqueueGptImage2TextToImageNumImages::One => base_cost,
|
||||
EnqueueGptImage2TextToImageNumImages::Two => base_cost * 2,
|
||||
EnqueueGptImage2TextToImageNumImages::Three => base_cost * 3,
|
||||
EnqueueGptImage2TextToImageNumImages::Four => base_cost * 4,
|
||||
};
|
||||
cost as UsdCents
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub async fn enqueue_gpt_image_2_text_to_image_webhook<R: IntoUrl>(
|
||||
args: EnqueueGptImage2TextToImageArgs<'_, R>
|
||||
) -> Result<WebhookResponse, FalErrorPlus> {
|
||||
|
||||
let num_images = match args.num_images {
|
||||
EnqueueGptImage2TextToImageNumImages::One => 1,
|
||||
EnqueueGptImage2TextToImageNumImages::Two => 2,
|
||||
EnqueueGptImage2TextToImageNumImages::Three => 3,
|
||||
EnqueueGptImage2TextToImageNumImages::Four => 4,
|
||||
};
|
||||
|
||||
let image_size = args.image_size
|
||||
.map(|s| match s {
|
||||
EnqueueGptImage2TextToImageSize::Landscape4x3 => "1024x768",
|
||||
EnqueueGptImage2TextToImageSize::Square => "1024x1024",
|
||||
EnqueueGptImage2TextToImageSize::Portrait => "1024x1536",
|
||||
EnqueueGptImage2TextToImageSize::Landscape16x9 => "1920x1080",
|
||||
EnqueueGptImage2TextToImageSize::Qhd => "2560x1440",
|
||||
EnqueueGptImage2TextToImageSize::Uhd4k => "3840x2160",
|
||||
})
|
||||
.map(|resolution| resolution.to_string());
|
||||
|
||||
let quality = args.quality
|
||||
.map(|s| match s {
|
||||
EnqueueGptImage2TextToImageQuality::Low => "low",
|
||||
EnqueueGptImage2TextToImageQuality::Medium => "medium",
|
||||
EnqueueGptImage2TextToImageQuality::High => "high",
|
||||
})
|
||||
.map(|quality| quality.to_string());
|
||||
|
||||
let output_format = args.output_format
|
||||
.map(|s| match s {
|
||||
EnqueueGptImage2TextToImageOutputFormat::Jpeg => "jpeg",
|
||||
EnqueueGptImage2TextToImageOutputFormat::Png => "png",
|
||||
EnqueueGptImage2TextToImageOutputFormat::Webp => "webp",
|
||||
})
|
||||
.map(|format| format.to_string())
|
||||
.unwrap_or_else(|| "png".to_string());
|
||||
|
||||
let request = GptImage2TextToImageInput {
|
||||
prompt: args.prompt.to_string(),
|
||||
num_images: Some(num_images),
|
||||
output_format: Some(output_format),
|
||||
// Optionals
|
||||
image_size,
|
||||
quality,
|
||||
};
|
||||
|
||||
let result = gpt_image_2_text_to_image(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::text::enqueue_gpt_image_2_text_to_image_webhook::{enqueue_gpt_image_2_text_to_image_webhook, EnqueueGptImage2TextToImageArgs, EnqueueGptImage2TextToImageNumImages};
|
||||
use errors::AnyhowResult;
|
||||
use std::fs::read_to_string;
|
||||
|
||||
#[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 = EnqueueGptImage2TextToImageArgs {
|
||||
prompt: "an anime girl riding on the back of a t-rex",
|
||||
num_images: EnqueueGptImage2TextToImageNumImages::Two,
|
||||
image_size: None,
|
||||
quality: None,
|
||||
api_key: &api_key,
|
||||
webhook_url: "https://example.com/webhook",
|
||||
output_format: None,
|
||||
};
|
||||
|
||||
let result = enqueue_gpt_image_2_text_to_image_webhook(args).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -10,4 +10,5 @@ pub mod enqueue_gemini_25_flash_text_to_image_webhook;
|
||||
pub mod enqueue_gpt_image_1_byok_text_to_image_webhook;
|
||||
pub mod enqueue_gpt_image_1_text_to_image_webhook;
|
||||
pub mod enqueue_gpt_image_1p5_text_to_image_webhook;
|
||||
pub mod enqueue_gpt_image_2_text_to_image_webhook;
|
||||
pub mod enqueue_nano_banana_pro_text_to_image_webhook;
|
||||
Reference in new issue
Block a user