refactor to make intention of request prereq checks clear + reusable

This commit is contained in:
Brandon Thomas committed 2026-05-31 14:40:10 -04:00
1 parent e39fe7c106
commit 8ac4e534e1
8 files changed
+34 -19

No files matched your search

@@ -1,15 +1,15 @@
use std::sync::Arc;
use crate::http_server::common_responses::common_web_error::CommonWebError;
use crate::http_server::endpoints::omni_gen::generate::video::helpers::hydrate_router_request::hydrate_to_router_request;
use crate::http_server::endpoints::omni_gen::shared_utils::video::validate_video_request::validate_video_request;
use crate::state::server_state::ServerState;
use actix_web::web::Json;
use actix_web::{web, HttpRequest};
use artcraft_api_defs::omni_gen::cost_and_generate_requests::omni_gen_video_cost_and_generate_request::OmniGenVideoCostAndGenerateRequest;
use artcraft_api_defs::omni_gen::cost_response::omni_gen_video_cost_response::OmniGenVideoCostResponse;
use artcraft_router::api::router_provider::RouterProvider;
use log::warn;
use crate::http_server::common_responses::common_web_error::CommonWebError;
use crate::http_server::endpoints::omni_gen::generate::video::helpers::hydrate_router_request::hydrate_to_router_request;
use crate::http_server::endpoints::omni_gen::generate::video::helpers::validate_image_required::validate_image_required;
use crate::state::server_state::ServerState;
/// Estimate the cost of a video generation.
#[utoipa::path(
@@ -28,7 +28,7 @@ pub async fn omni_gen_video_cost_handler(
request: Json<OmniGenVideoCostAndGenerateRequest>,
_server_state: web::Data<Arc<ServerState>>,
) -> Result<Json<OmniGenVideoCostResponse>, CommonWebError> {
validate_image_required(&request)?;
validate_video_request(&request)?;
let mut builder = hydrate_to_router_request(&request)?;
@@ -4,4 +4,3 @@ pub(crate) mod hydrate_router_request;
pub mod pipeline_result;
pub mod resolve_kinovi_character_ids;
pub mod resolve_media_tokens_to_urls;
pub mod validate_image_required;
@@ -32,15 +32,15 @@ use tokens::tokens::non_unique::debug_logs_event_token::DebugLogEventToken;
use crate::http_server::common_responses::common_web_error::CommonWebError;
use crate::http_server::endpoints::generate::common::payments_error_test::payments_error_test;
use crate::http_server::endpoints::omni_gen::generate::video::helpers::hydrate_router_request::hydrate_to_router_request;
use crate::http_server::endpoints::omni_gen::generate::video::helpers::validate_image_required::validate_image_required;
use crate::http_server::endpoints::omni_gen::generate::video::helpers::resolve_kinovi_character_ids::resolve_kinovi_character_ids;
use crate::http_server::endpoints::omni_gen::generate::video::insert_db_job::insert_fal_job::{insert_fal_job, InsertFalJobArgs};
use crate::http_server::endpoints::omni_gen::generate::video::insert_db_job::insert_gmicloud_job::{insert_gmicloud_job, InsertGmiCloudJobArgs};
use crate::http_server::endpoints::omni_gen::generate::video::insert_db_job::insert_grok_api_job::{insert_grok_api_job, InsertGrokApiJobArgs};
use crate::http_server::endpoints::omni_gen::generate::video::insert_db_job::insert_seedance2pro_jobs::{insert_seedance2pro_jobs, InsertSeedance2proJobsArgs};
use crate::http_server::endpoints::omni_gen::generate::video::insert_db_job::shared_job_args::SharedJobArgs;
use crate::http_server::endpoints::omni_gen::generate::video::pipeline_v2::run_pipeline_v2::{run_pipeline_v2, RunPipelineV2Args};
use crate::http_server::endpoints::omni_gen::generate::video::helpers::resolve_kinovi_character_ids::resolve_kinovi_character_ids;
use crate::http_server::endpoints::omni_gen::generate::video::kinovi_account::KinoviAccount;
use crate::http_server::endpoints::omni_gen::generate::video::pipeline_v2::run_pipeline_v2::{run_pipeline_v2, RunPipelineV2Args};
use crate::http_server::endpoints::omni_gen::shared_utils::video::validate_video_request::validate_video_request;
use crate::http_server::session::lookup::user_session_feature_flags::UserSessionFeatureFlags;
use crate::http_server::validations::validate_idempotency_token_format::validate_idempotency_token_format;
use crate::state::server_state::ServerState;
@@ -70,7 +70,7 @@ pub async fn omni_gen_video_generate_handler(
// Reject doomed combos (e.g. grok_imagine_video_1p5 without an image)
// before any billable or DB-mutating work — see helper for the rules.
validate_image_required(&request)?;
validate_video_request(&request)?;
payments_error_test(&request.prompt.as_deref().unwrap_or(""))?;
@@ -1,3 +1,4 @@
pub mod cost;
pub mod generate;
pub mod models;
pub mod shared_utils;
@@ -0,0 +1,2 @@
pub mod validate_video_request;
mod validate_when_image_required;
@@ -0,0 +1,11 @@
use crate::http_server::common_responses::common_web_error::CommonWebError;
use crate::http_server::endpoints::omni_gen::shared_utils::video::validate_when_image_required::validate_when_image_required;
use artcraft_api_defs::omni_gen::cost_and_generate_requests::omni_gen_video_cost_and_generate_request::OmniGenVideoCostAndGenerateRequest;
/// Validate requests before they incur user costs or send API requests
pub fn validate_video_request(
request: &OmniGenVideoCostAndGenerateRequest,
) -> Result<(), CommonWebError> {
validate_when_image_required(request)?;
Ok(())
}
@@ -7,7 +7,7 @@ use crate::http_server::common_responses::common_web_error::CommonWebError;
/// the upstream API. Reject the request at the handler layer so callers see
/// a clean 400 with an actionable message and we don't charge their wallet
/// for an inference job we know will fail.
pub fn validate_image_required(
pub (super) fn validate_when_image_required(
request: &OmniGenVideoCostAndGenerateRequest,
) -> Result<(), CommonWebError> {
match request.model {
@@ -22,6 +22,7 @@ pub fn validate_image_required(
}
let has_start_frame = request.start_frame_image_media_token.is_some();
let has_reference_images = request
.reference_image_media_tokens
.as_ref()
@@ -69,7 +70,7 @@ mod tests {
#[test]
fn passes_when_model_is_none() {
let req = base_request();
assert!(validate_image_required(&req).is_ok());
assert!(validate_when_image_required(&req).is_ok());
}
#[test]
@@ -79,7 +80,7 @@ mod tests {
model: Some(CommonVideoModel::Seedance2p0),
..base_request()
};
assert!(validate_image_required(&req).is_ok());
assert!(validate_when_image_required(&req).is_ok());
}
#[test]
@@ -88,7 +89,7 @@ mod tests {
model: Some(CommonVideoModel::GrokImagineVideo1p5),
..base_request()
};
let err = validate_image_required(&req).expect_err("should reject");
let err = validate_when_image_required(&req).expect_err("should reject");
match err {
CommonWebError::BadInputWithSimpleMessage(msg) => {
assert_eq!(msg, "Image is required");
@@ -105,7 +106,7 @@ mod tests {
..base_request()
};
assert!(matches!(
validate_image_required(&req),
validate_when_image_required(&req),
Err(CommonWebError::BadInputWithSimpleMessage(_))
));
}
@@ -117,7 +118,7 @@ mod tests {
start_frame_image_media_token: Some(token("mf_start")),
..base_request()
};
assert!(validate_image_required(&req).is_ok());
assert!(validate_when_image_required(&req).is_ok());
}
#[test]
@@ -127,7 +128,7 @@ mod tests {
reference_image_media_tokens: Some(vec![token("mf_a"), token("mf_b")]),
..base_request()
};
assert!(validate_image_required(&req).is_ok());
assert!(validate_when_image_required(&req).is_ok());
}
#[test]
@@ -138,7 +139,7 @@ mod tests {
reference_image_media_tokens: Some(vec![token("mf_a")]),
..base_request()
};
assert!(validate_image_required(&req).is_ok());
assert!(validate_when_image_required(&req).is_ok());
}
#[test]
@@ -151,6 +152,6 @@ mod tests {
end_frame_image_media_token: Some(token("mf_end")),
..base_request()
};
assert!(validate_image_required(&req).is_err());
assert!(validate_when_image_required(&req).is_err());
}
}