diff --git a/crates/service/web/storyteller_web/src/docs/api_doc.rs b/crates/service/web/storyteller_web/src/docs/api_doc.rs index f146d39665..c4050dd3a8 100644 --- a/crates/service/web/storyteller_web/src/docs/api_doc.rs +++ b/crates/service/web/storyteller_web/src/docs/api_doc.rs @@ -18,6 +18,8 @@ use artcraft_api_defs::generate::image::generate_flux_pro_11_ultra_text_to_image use artcraft_api_defs::generate::image::generate_flux_pro_11_ultra_text_to_image::GenerateFluxPro11UltraTextToImageResponse; use artcraft_api_defs::generate::image::remove_image_background::RemoveImageBackgroundRequest; use artcraft_api_defs::generate::image::remove_image_background::RemoveImageBackgroundResponse; +use artcraft_api_defs::generate::object::generate_hunyuan_2_image_to_3d::GenerateHunyuan2ImageTo3dRequest; +use artcraft_api_defs::generate::object::generate_hunyuan_2_image_to_3d::GenerateHunyuan2ImageTo3dResponse; use billing_component::stripe::http_endpoints::checkout::create::stripe_create_checkout_session_error::CreateCheckoutSessionError; use billing_component::stripe::http_endpoints::checkout::create::stripe_create_checkout_session_json_handler::*; use billing_component::users::http_endpoints::list_active_user_subscriptions_handler::*; @@ -143,7 +145,6 @@ use crate::http_server::endpoints::media_files::upsert_upload::write_error::Medi use crate::http_server::endpoints::media_files::upsert_upload::write_scene_file::write_scene_file_media_file_handler::*; use crate::http_server::endpoints::model_download::enqueue_gptsovits_model_download_handler::*; use crate::http_server::endpoints::moderation::user_feature_flags::edit_user_feature_flags_handler::*; -use crate::http_server::endpoints::generate::image::generate_flux_pro_11_text_to_image_handler::generate_flux_pro_11_text_to_image_handler; use crate::http_server::endpoints::prompts::get_prompt_handler::*; use crate::http_server::endpoints::service::status_alert_handler::*; use crate::http_server::endpoints::stats::get_unified_queue_stats_handler::*; @@ -228,6 +229,7 @@ use crate::http_server::web_utils::response_success_helpers::*; crate::http_server::endpoints::media_files::get::get_media_file_handler::get_media_file_handler, crate::http_server::endpoints::media_files::list::list_featured_media_files_handler::list_featured_media_files_handler, crate::http_server::endpoints::media_files::list::list_media_files_by_batch_token_handler::list_media_files_by_batch_token_handler, + crate::http_server::endpoints::generate::object::generate_hunyuan2_image_to_3d_handler::generate_hunyuan_2_image_to_3d_handler, crate::http_server::endpoints::media_files::list::list_media_files_for_user_handler::list_media_files_for_user_handler, crate::http_server::endpoints::media_files::list::list_media_files_handler::list_media_files_handler, crate::http_server::endpoints::media_files::list::list_pinned_media_files_handler::list_pinned_media_files_handler, @@ -495,6 +497,8 @@ use crate::http_server::web_utils::response_success_helpers::*; GenerateFluxPro11UltraTextToImageNumImages, GenerateFluxPro11UltraTextToImageRequest, GenerateFluxPro11UltraTextToImageResponse, + GenerateHunyuan2ImageTo3dRequest, + GenerateHunyuan2ImageTo3dResponse, GetInferenceJobStatusError, GetInferenceJobStatusPathInfo, GetInferenceJobStatusSuccessResponse, diff --git a/crates/service/web/storyteller_web/src/http_server/endpoints/generate/object/generate_hunyuan2_image_to_3d_handler.rs b/crates/service/web/storyteller_web/src/http_server/endpoints/generate/object/generate_hunyuan2_image_to_3d_handler.rs index 14a824ae92..7dd60d38a0 100644 --- a/crates/service/web/storyteller_web/src/http_server/endpoints/generate/object/generate_hunyuan2_image_to_3d_handler.rs +++ b/crates/service/web/storyteller_web/src/http_server/endpoints/generate/object/generate_hunyuan2_image_to_3d_handler.rs @@ -2,6 +2,7 @@ use std::fmt; use std::sync::Arc; use crate::http_server::common_requests::media_file_token_path_info::MediaFileTokenPathInfo; +use crate::http_server::common_responses::common_web_error::CommonWebError; use crate::http_server::common_responses::media::media_links::MediaLinks; use crate::http_server::deprecated_endpoints::engine::create_scene_handler::CreateSceneError; use crate::http_server::endpoints::media_files::helpers::get_media_domain::get_media_domain; @@ -33,51 +34,13 @@ use mysql_queries::queries::media_files::get::get_media_file::{get_media_file, M use tokens::tokens::media_files::MediaFileToken; use utoipa::ToSchema; -// =============== Error Response =============== - - -#[derive(Debug, Serialize, ToSchema)] -pub enum GenerateHunyuan2ImageTo3dError { - BadInput(String), - NotFound, - NotAuthorized, - ServerError, -} - -impl ResponseError for GenerateHunyuan2ImageTo3dError { - fn status_code(&self) -> StatusCode { - match *self { - GenerateHunyuan2ImageTo3dError::BadInput(_) => StatusCode::BAD_REQUEST, - GenerateHunyuan2ImageTo3dError::NotFound => StatusCode::NOT_FOUND, - GenerateHunyuan2ImageTo3dError::NotAuthorized => StatusCode::UNAUTHORIZED, - GenerateHunyuan2ImageTo3dError::ServerError => StatusCode::INTERNAL_SERVER_ERROR, - } - } - - fn error_response(&self) -> HttpResponse { - serialize_as_json_error(self) - } -} - -// NB: Not using derive_more::Display since Clion doesn't understand it. -impl fmt::Display for GenerateHunyuan2ImageTo3dError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{:?}", self) - } -} - -// =============== Handler =============== - -/// Background removal +/// Hunyuan 2.0 Image to 3D #[utoipa::path( post, tag = "Generate Objects", path = "/v1/generate/object/hunyuan_2_image_to_3d", responses( (status = 200, description = "Success", body = GenerateHunyuan2ImageTo3dResponse), - (status = 400, description = "Bad input", body = GenerateHunyuan2ImageTo3dError), - (status = 401, description = "Not authorized", body = GenerateHunyuan2ImageTo3dError), - (status = 500, description = "Server error", body = GenerateHunyuan2ImageTo3dError), ), params( ("request" = GenerateHunyuan2ImageTo3dRequest, description = "Payload for Request"), @@ -87,14 +50,14 @@ pub async fn generate_hunyuan_2_image_to_3d_handler( http_request: HttpRequest, request: Json, server_state: web::Data> -) -> Result, GenerateHunyuan2ImageTo3dError> { +) -> Result, CommonWebError> { let maybe_user_session = server_state .session_checker .maybe_get_user_session(&http_request, &server_state.mysql_pool) .await .map_err(|e| { warn!("Session checker error: {:?}", e); - GenerateHunyuan2ImageTo3dError::ServerError + CommonWebError::ServerError })?; let maybe_avt_token = server_state @@ -107,7 +70,7 @@ pub async fn generate_hunyuan_2_image_to_3d_handler( // Some(session) => session, // None => { // warn!("not logged in"); - // return Err(GenerateHunyuan2ImageTo3dError::NotAuthorized); + // return Err(CommonWebError::NotAuthorized); // } //}; @@ -115,19 +78,19 @@ pub async fn generate_hunyuan_2_image_to_3d_handler( Some(token) => token, None => { warn!("No media file token provided"); - return Err(GenerateHunyuan2ImageTo3dError::BadInput("No media file token provided".to_string())); + return Err(CommonWebError::BadInputWithSimpleMessage("No media file token provided".to_string())); } }; if let Err(reason) = validate_idempotency_token_format(&request.uuid_idempotency_token) { - return Err(GenerateHunyuan2ImageTo3dError::BadInput(reason)); + return Err(CommonWebError::BadInputWithSimpleMessage(reason)); } insert_idempotency_token(&request.uuid_idempotency_token, &server_state.mysql_pool) .await .map_err(|err| { error!("Error inserting idempotency token: {:?}", err); - GenerateHunyuan2ImageTo3dError::BadInput("invalid idempotency token".to_string()) + CommonWebError::BadInputWithSimpleMessage("invalid idempotency token".to_string()) })?; const IS_MOD : bool = false; @@ -141,16 +104,16 @@ pub async fn generate_hunyuan_2_image_to_3d_handler( Ok(Some(media_file)) => media_file, Ok(None) => { warn!("MediaFile not found: {:?}", media_file_token); - return Err(GenerateHunyuan2ImageTo3dError::NotFound); + return Err(CommonWebError::NotFound); }, Err(err) => { warn!("Error looking up media_file: {:?}", err); - return Err(GenerateHunyuan2ImageTo3dError::ServerError); + return Err(CommonWebError::ServerError); } }; if !media_file.media_type.is_jpg_or_png_or_legacy_image() { - return Err(GenerateHunyuan2ImageTo3dError::BadInput("Media file must be a JPG or PNG image".to_string())); + return Err(CommonWebError::BadInputWithSimpleMessage("Media file must be a JPG or PNG image".to_string())); } let media_domain = get_media_domain(&http_request); @@ -177,13 +140,13 @@ pub async fn generate_hunyuan_2_image_to_3d_handler( .await .map_err(|err| { warn!("Error calling enqueue_hunyuan2_image_to_3d_webhook: {:?}", err); - GenerateHunyuan2ImageTo3dError::ServerError + CommonWebError::ServerError })?; let external_job_id = fal_result.request_id .ok_or_else(|| { warn!("Fal request_id is None"); - GenerateHunyuan2ImageTo3dError::ServerError + CommonWebError::ServerError })?; info!("Fal request_id: {}", external_job_id); @@ -206,7 +169,7 @@ pub async fn generate_hunyuan_2_image_to_3d_handler( Ok(token) => token, Err(err) => { warn!("Error inserting generic inference job for FAL queue: {:?}", err); - return Err(GenerateHunyuan2ImageTo3dError::ServerError); + return Err(CommonWebError::ServerError); } };