mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-14 13:52:11 +00:00
more fal endpoints
This commit is contained in:
1 parent
92b68d3f9d
commit
04c2c524d7
10 files changed
+240
-1
No files matched your search
+2
@@ -57,6 +57,8 @@ pub async fn enqueue_seedance_1_lite_image_to_video_webhook<U: IntoUrl, T: IntoU
|
||||
// TODO: Add these later
|
||||
camera_fixed: None,
|
||||
seed: -1,
|
||||
// Static
|
||||
enable_safety_checker: Some(false),
|
||||
};
|
||||
|
||||
let result = image_to_video(request)
|
||||
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
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::bytedance::seedance::v1::pro::image_to_video::{seedance_v1_pro_image_to_video, SeedanceImageToVideoProRequest};
|
||||
use fal::webhook::WebhookResponse;
|
||||
use reqwest::IntoUrl;
|
||||
|
||||
pub struct Seedance1ProArgs<'a, U: IntoUrl, V: IntoUrl> {
|
||||
pub image_url: U,
|
||||
pub webhook_url: V,
|
||||
pub prompt: &'a str,
|
||||
pub api_key: &'a FalApiKey,
|
||||
pub camera_fixed: bool,
|
||||
pub duration: Seedance1ProDuration,
|
||||
pub resolution: Seedance1ProResolution,
|
||||
pub seed: Option<u32>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum Seedance1ProDuration {
|
||||
FiveSeconds,
|
||||
TenSeconds,
|
||||
TwelveSeconds,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum Seedance1ProResolution {
|
||||
FourEightyP, // 480p
|
||||
SevenTwentyP, // 720p
|
||||
TenEightyP, // 1080p
|
||||
}
|
||||
|
||||
pub async fn enqueue_seedance_1_pro_image_to_video_webhook<U: IntoUrl, V: IntoUrl>(
|
||||
args: Seedance1ProArgs<'_, U, V>
|
||||
) -> Result<WebhookResponse, FalErrorPlus> {
|
||||
let duration = match args.duration {
|
||||
Seedance1ProDuration::FiveSeconds => Some("5".to_string()),
|
||||
Seedance1ProDuration::TenSeconds => Some("10".to_string()),
|
||||
Seedance1ProDuration::TwelveSeconds => Some("12".to_string()),
|
||||
};
|
||||
|
||||
let resolution = match args.resolution {
|
||||
Seedance1ProResolution::FourEightyP => Some("480p".to_string()),
|
||||
Seedance1ProResolution::SevenTwentyP => Some("720p".to_string()),
|
||||
Seedance1ProResolution::TenEightyP => Some("1080p".to_string()),
|
||||
};
|
||||
|
||||
let image_url = args.image_url.as_str().to_string();
|
||||
|
||||
let request = SeedanceImageToVideoProRequest {
|
||||
image_url,
|
||||
prompt: args.prompt.to_string(),
|
||||
duration,
|
||||
resolution,
|
||||
// TODO: Add these later
|
||||
camera_fixed: None,
|
||||
// Static
|
||||
enable_safety_checker: Some(false),
|
||||
};
|
||||
|
||||
let result = seedance_v1_pro_image_to_video(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::video::enqueue_seedance_1_pro_image_to_video_webhook::{enqueue_seedance_1_pro_image_to_video_webhook, Seedance1ProArgs, Seedance1ProDuration, Seedance1ProResolution};
|
||||
use errors::AnyhowResult;
|
||||
use std::fs::read_to_string;
|
||||
use test_data::web::image_urls::TALL_MOCHI_WITH_GLASSES_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 = Seedance1ProArgs {
|
||||
image_url: TALL_MOCHI_WITH_GLASSES_IMAGE_URL,
|
||||
prompt: "shiba in glasses runs to the lake and stands by the shore",
|
||||
api_key: &api_key,
|
||||
camera_fixed: false,
|
||||
duration: Seedance1ProDuration::FiveSeconds,
|
||||
resolution: Seedance1ProResolution::SevenTwentyP,
|
||||
seed: None,
|
||||
webhook_url: "https://example.com/webhook",
|
||||
};
|
||||
|
||||
let result = enqueue_seedance_1_pro_image_to_video_webhook(args).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ pub mod enqueue_kling_16_pro_image_to_video_webhook;
|
||||
pub mod enqueue_kling_21_master_image_to_video_webhook;
|
||||
pub mod enqueue_kling_21_pro_image_to_video_webhook;
|
||||
pub mod enqueue_seedance_1_lite_image_to_video_webhook;
|
||||
pub mod enqueue_seedance_1_pro_image_to_video_webhook;
|
||||
pub mod enqueue_veo_2_image_to_video_webhook;
|
||||
pub mod enqueue_veo_3_fast_image_to_video_webhook;
|
||||
pub mod enqueue_veo_3_image_to_video_webhook;
|
||||
+3
@@ -26,6 +26,9 @@ pub struct ImageToVideoRequest {
|
||||
pub prompt: String,
|
||||
|
||||
pub seed: i32,
|
||||
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub enable_safety_checker: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Default)]
|
||||
|
||||
@@ -11,4 +11,5 @@
|
||||
feature = "endpoints_fal-ai_bytedance"
|
||||
)))
|
||||
)]
|
||||
pub mod lite;
|
||||
pub mod lite;
|
||||
pub mod pro;
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
#[allow(unused_imports)]
|
||||
use crate::prelude::*;
|
||||
#[allow(unused_imports)]
|
||||
use serde::{Deserialize, Serialize};
|
||||
#[allow(unused_imports)]
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Default)]
|
||||
pub struct SeedanceImageToVideoProRequest {
|
||||
pub prompt: String,
|
||||
|
||||
pub image_url: String,
|
||||
|
||||
/// The resolution of the generated video frame
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub resolution: Option<String>,
|
||||
|
||||
/// The duration of the generated video in seconds
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub duration: Option<String>,
|
||||
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub camera_fixed: Option<bool>,
|
||||
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub enable_safety_checker: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct I2VOutput {
|
||||
/// The generated video
|
||||
/// {"url":"https://v2.fal.media/files/36087878b0c1435bb75c19b64b7db178_output.mp4"}
|
||||
pub video: File,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Default)]
|
||||
pub struct File {
|
||||
/// The URL where the file can be downloaded from.
|
||||
pub url: String,
|
||||
|
||||
// /// The mime type of the file.
|
||||
// /// "image/png"
|
||||
// #[serde(skip_serializing_if = "Option::is_none")]
|
||||
// pub content_type: Option<String>,
|
||||
// /// File data
|
||||
// #[serde(skip_serializing_if = "Option::is_none")]
|
||||
// pub file_data: Option<String>,
|
||||
// /// The name of the file. It will be auto-generated if not provided.
|
||||
// /// "z9RV14K95DvU.png"
|
||||
// #[serde(skip_serializing_if = "Option::is_none")]
|
||||
// pub file_name: Option<String>,
|
||||
// /// The size of the file in bytes.
|
||||
// /// 4404019
|
||||
// #[serde(skip_serializing_if = "Option::is_none")]
|
||||
// pub file_size: Option<i64>,
|
||||
}
|
||||
|
||||
pub fn seedance_v1_pro_image_to_video(
|
||||
params: SeedanceImageToVideoProRequest,
|
||||
) -> FalRequest<SeedanceImageToVideoProRequest, I2VOutput> {
|
||||
FalRequest::new("fal-ai/bytedance/seedance/v1/pro/image-to-video", params)
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
pub mod image_to_video;
|
||||
@@ -0,0 +1,53 @@
|
||||
use crate::prelude::{Deserialize, FalRequest, Serialize};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Default)]
|
||||
pub struct Gemini25FlashImageEditInput {
|
||||
pub prompt: String,
|
||||
|
||||
pub image_urls: Vec<String>,
|
||||
|
||||
/// 1 - 4
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub num_images: Option<u8>,
|
||||
|
||||
/// "jpeg" or "png"
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub output_format: Option<String>,
|
||||
|
||||
/// Resolution, eg. "720p"
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub resolution: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Default)]
|
||||
pub struct File {
|
||||
/// The URL where the file can be downloaded from.
|
||||
pub url: String,
|
||||
|
||||
// /// The mime type of the file.
|
||||
// /// "image/png"
|
||||
// #[serde(skip_serializing_if = "Option::is_none")]
|
||||
// pub content_type: Option<String>,
|
||||
// /// File data
|
||||
// #[serde(skip_serializing_if = "Option::is_none")]
|
||||
// pub file_data: Option<String>,
|
||||
// /// The name of the file. It will be auto-generated if not provided.
|
||||
// /// "z9RV14K95DvU.png"
|
||||
// #[serde(skip_serializing_if = "Option::is_none")]
|
||||
// pub file_name: Option<String>,
|
||||
// /// The size of the file in bytes.
|
||||
// /// 4404019
|
||||
// #[serde(skip_serializing_if = "Option::is_none")]
|
||||
// pub file_size: Option<i64>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct Gemini25FlashImageEditOutput {
|
||||
pub images: Vec<File>,
|
||||
}
|
||||
|
||||
pub fn gemini_25_flash_image_edit(
|
||||
params: Gemini25FlashImageEditInput,
|
||||
) -> FalRequest<Gemini25FlashImageEditInput, Gemini25FlashImageEditOutput> {
|
||||
FalRequest::new("fal-ai/gemini-25-flash-image/edit", params)
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
pub mod edit;
|
||||
@@ -893,6 +893,20 @@ pub mod fooocus;
|
||||
feature = "endpoints_fal-ai_gemini-flash-edit"
|
||||
)))
|
||||
)]
|
||||
pub mod gemini_25_flash_image;
|
||||
#[cfg(any(
|
||||
feature = "endpoints",
|
||||
feature = "endpoints_fal-ai",
|
||||
feature = "endpoints_fal-ai_gemini-flash-edit"
|
||||
))]
|
||||
#[cfg_attr(
|
||||
docsrs,
|
||||
doc(cfg(any(
|
||||
feature = "endpoints",
|
||||
feature = "endpoints_fal-ai",
|
||||
feature = "endpoints_fal-ai_gemini-flash-edit"
|
||||
)))
|
||||
)]
|
||||
pub mod gemini_flash_edit;
|
||||
#[cfg(any(
|
||||
feature = "endpoints",
|
||||
|
||||
Reference in new issue
Block a user