enqueue fbx to gltf

This commit is contained in:
Brandon Thomas committed 2024-01-29 22:23:18 -05:00
1 parent 57ca10f23d
commit eeb6d486e1
5 files changed
+231 -5

No files matched your search

@@ -0,0 +1,216 @@
#![forbid(unused_mut)]
use std::fmt::Debug;
use std::sync::Arc;
use actix_web::{HttpRequest, HttpResponse, web};
use actix_web::error::ResponseError;
use actix_web::http::StatusCode;
use log::warn;
use serde::Deserialize;
use serde::Serialize;
use utoipa::ToSchema;
use enums::by_table::generic_inference_jobs::inference_category::InferenceCategory;
use enums::by_table::generic_inference_jobs::inference_model_type::InferenceModelType;
use enums::common::visibility::Visibility;
use http_server_common::request::get_request_header_optional::get_request_header_optional;
use http_server_common::request::get_request_ip::get_request_ip;
use mysql_queries::payloads::generic_inference_args::generic_inference_args::{
GenericInferenceArgs,
InferenceCategoryAbbreviated,
};
use mysql_queries::queries::generic_inference::web::insert_generic_inference_job::{
insert_generic_inference_job,
InsertGenericInferenceArgs,
};
use tokens::tokens::generic_inference_jobs::InferenceJobToken;
use tokens::tokens::media_files::MediaFileToken;
use tokens::tokens::users::UserToken;
use crate::configs::plans::get_correct_plan_for_session::get_correct_plan_for_session;
use crate::http_server::web_utils::response_error_helpers::to_simple_json_error;
use crate::server_state::ServerState;
/// Debug requests can get routed to special "debug-only" workers, which can
/// be used to trial new code, run debugging, etc.
const DEBUG_HEADER_NAME: &str = "enable-debug-mode";
/// The routing tag header can send workloads to particular k8s hosts.
/// This is useful for catching the live logs or intercepting the job.
const ROUTING_TAG_HEADER_NAME: &str = "routing-tag";
#[derive(Deserialize, ToSchema)]
pub struct EnqueueFbxToGltfRequest {
// Entropy for idempotency
uuid_idempotency_token: String,
// The existing FBX media file token
media_file_token: MediaFileToken,
}
#[derive(Serialize, ToSchema)]
pub struct EnqueueFbxToGltfRequestSuccessResponse {
pub success: bool,
pub inference_job_token: InferenceJobToken,
}
#[derive(Debug, ToSchema)]
pub enum EnqueueFbxToGltfRequestError {
BadInput(String),
NotAuthorized,
ServerError,
RateLimited,
}
impl ResponseError for EnqueueFbxToGltfRequestError {
fn status_code(&self) -> StatusCode {
match *self {
EnqueueFbxToGltfRequestError::BadInput(_) => StatusCode::BAD_REQUEST,
EnqueueFbxToGltfRequestError::NotAuthorized => StatusCode::UNAUTHORIZED,
EnqueueFbxToGltfRequestError::ServerError => StatusCode::INTERNAL_SERVER_ERROR,
EnqueueFbxToGltfRequestError::RateLimited => StatusCode::TOO_MANY_REQUESTS,
}
}
fn error_response(&self) -> HttpResponse {
let error_reason = match self {
EnqueueFbxToGltfRequestError::BadInput(reason) => reason.to_string(),
EnqueueFbxToGltfRequestError::NotAuthorized => "unauthorized".to_string(),
EnqueueFbxToGltfRequestError::ServerError => "server error".to_string(),
EnqueueFbxToGltfRequestError::RateLimited => "rate limited".to_string(),
};
to_simple_json_error(&error_reason, self.status_code())
}
}
impl std::fmt::Display for EnqueueFbxToGltfRequestError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self)
}
}
#[utoipa::path(
post,
path = "/v1/conversion/enqueue_fbx_to_gltf",
responses(
(
status = 200,
description = "Enqueue FBX to GLTF",
body = EnqueueFbxToGltfRequestSuccessResponse,
),
(status = 400, description = "Bad input", body = EnqueueFbxToGltfRequestError),
(status = 401, description = "Not authorized", body = EnqueueFbxToGltfRequestError),
(status = 429, description = "Rate limited", body = EnqueueFbxToGltfRequestError),
(status = 500, description = "Server error", body = EnqueueFbxToGltfRequestError)
),
params(("request" = EnqueueFbxToGltfRequest, description = "Payload for FBX to GLTF Request"))
)]
pub async fn enqueue_fbx_to_gltf_handler(
http_request: HttpRequest,
request: web::Json<EnqueueFbxToGltfRequest>,
server_state: web::Data<Arc<ServerState>>
) -> Result<HttpResponse, EnqueueFbxToGltfRequestError> {
let mut maybe_user_token: Option<UserToken> = None;
let mut mysql_connection = server_state.mysql_pool.acquire().await.map_err(|err| {
warn!("MySql pool error: {:?}", err);
EnqueueFbxToGltfRequestError::ServerError
})?;
// ==================== USER SESSION ==================== //
let maybe_user_session = server_state.session_checker
.maybe_get_user_session_extended_from_connection(&http_request, &mut mysql_connection).await
.map_err(|e| {
warn!("Session checker error: {:?}", e);
EnqueueFbxToGltfRequestError::ServerError
})?;
if let Some(user_session) = maybe_user_session.as_ref() {
maybe_user_token = Some(UserToken::new_from_str(&user_session.user_token));
}
// Plan should handle "first anonymous use" and "investor" cases.
let plan = get_correct_plan_for_session(
server_state.server_environment,
maybe_user_session.as_ref()
);
// Separate priority for animation.
let priority_level = plan.web_vc_base_priority_level();
// ==================== DEBUG MODE + ROUTING TAG ==================== //
let is_debug_request = get_request_header_optional(&http_request, DEBUG_HEADER_NAME).is_some();
let maybe_routing_tag = get_request_header_optional(&http_request, ROUTING_TAG_HEADER_NAME).map(
|routing_tag| routing_tag.trim().to_string()
);
// ==================== BANNED USERS ==================== //
if let Some(ref user) = maybe_user_session {
if user.role.is_banned {
return Err(EnqueueFbxToGltfRequestError::NotAuthorized);
}
}
// ==================== RATE LIMIT ==================== //
let rate_limiter = match maybe_user_session {
None => &server_state.redis_rate_limiters.logged_out,
Some(ref _user) => &server_state.redis_rate_limiters.logged_in,
};
if let Err(_err) = rate_limiter.rate_limit_request(&http_request) {
return Err(EnqueueFbxToGltfRequestError::RateLimited);
}
let ip_address = get_request_ip(&http_request);
let maybe_avt_token = server_state.avt_cookie_manager
.get_avt_token_from_request(&http_request);
let query_result = insert_generic_inference_job(InsertGenericInferenceArgs {
uuid_idempotency_token: &request.uuid_idempotency_token,
inference_category: InferenceCategory::ImageGeneration,
maybe_model_type: Some(InferenceModelType::ConvertFbxToGltf),
maybe_model_token: None,
maybe_input_source_token: Some(&request.media_file_token.as_str()),
maybe_input_source_token_type: None,
maybe_raw_inference_text: None,
maybe_max_duration_seconds: None,
maybe_inference_args: Some(GenericInferenceArgs {
inference_category: Some(InferenceCategoryAbbreviated::FormatConversion),
args: None, // NB: no format conversion args for now
}),
maybe_creator_user_token: maybe_user_token.as_ref(),
maybe_avt_token: maybe_avt_token.as_ref(),
creator_ip_address: &ip_address,
creator_set_visibility: Visibility::Public,
priority_level,
requires_keepalive: true,
is_debug_request,
maybe_routing_tag: maybe_routing_tag.as_deref(),
mysql_pool: &server_state.mysql_pool,
}).await;
let job_token = match query_result {
Ok((job_token, _id)) => job_token,
Err(err) => {
warn!("New generic inference job creation DB error: {:?}", err);
return Err(EnqueueFbxToGltfRequestError::ServerError);
}
};
let response: EnqueueFbxToGltfRequestSuccessResponse = EnqueueFbxToGltfRequestSuccessResponse {
success: true,
inference_job_token: job_token,
};
let body = serde_json::to_string(&response)
.map_err(|_e| EnqueueFbxToGltfRequestError::ServerError)?;
Ok(HttpResponse::Ok().content_type("application/json").body(body))
}
@@ -0,0 +1 @@
pub mod enqueue_fbx_to_gltf_handler;
@@ -2,9 +2,11 @@ pub mod animation;
pub mod api_tokens;
pub mod categories;
pub mod comments;
pub mod conversion;
pub mod download_job;
pub mod events;
pub mod flags;
pub mod image_gen;
pub mod inference_job;
pub mod investor_demo;
pub mod leaderboard;
@@ -19,14 +21,13 @@ pub mod subscriptions;
pub mod trending;
pub mod tts;
pub mod twitch;
pub mod user_bookmarks;
pub mod user_ratings;
pub mod vocoders;
pub mod voice_clone_requests;
pub mod voice_conversion;
pub mod voice_designer;
pub mod w2l;
pub mod user_bookmarks;
pub mod weights;
pub mod image_gen;
pub(crate) mod mocap;
pub(crate) mod workflows;
@@ -15,6 +15,7 @@ use utoipa::ToSchema;
use enums::by_table::generic_inference_jobs::inference_category::InferenceCategory;
use enums::by_table::generic_inference_jobs::inference_model_type::InferenceModelType;
use enums::common::visibility::Visibility;
use http_server_common::request::get_request_header_optional::get_request_header_optional;
use http_server_common::request::get_request_ip::get_request_ip;
use mysql_queries::payloads::generic_inference_args::generic_inference_args::{
@@ -202,7 +203,7 @@ pub async fn enqueue_tts_request(
maybe_creator_user_token: maybe_user_token.as_ref(),
maybe_avt_token: maybe_avt_token.as_ref(),
creator_ip_address: &ip_address,
creator_set_visibility: enums::common::visibility::Visibility::Public,
creator_set_visibility: Visibility::Public,
priority_level,
requires_keepalive: true, // do we need this? I think so
is_debug_request,
@@ -26,11 +26,13 @@ use crate::http_server::endpoints::categories::tts::list_tts_model_assigned_cate
use crate::http_server::endpoints::comments::create_comment_handler::create_comment_handler;
use crate::http_server::endpoints::comments::delete_comment_handler::delete_comment_handler;
use crate::http_server::endpoints::comments::list_comments_handler::list_comments_handler;
use crate::http_server::endpoints::conversion::enqueue_fbx_to_gltf_handler::enqueue_fbx_to_gltf_handler;
use crate::http_server::endpoints::download_job::enqueue_generic_download::enqueue_generic_download_handler;
use crate::http_server::endpoints::download_job::get_generic_upload_job_status::get_generic_download_job_status_handler;
use crate::http_server::endpoints::events::list_events::list_events_handler;
use crate::http_server::endpoints::flags::design_refresh_flag::disable_design_refresh_flag_handler::disable_design_refresh_flag_handler;
use crate::http_server::endpoints::flags::design_refresh_flag::enable_design_refresh_flag_handler::enable_design_refresh_flag_handler;
use crate::http_server::endpoints::image_gen::enqueue_image_generation::enqueue_image_generation_request;
use crate::http_server::endpoints::inference_job::get_inference_job_status::get_inference_job_status_handler;
use crate::http_server::endpoints::inference_job::get_pending_inference_job_count::get_pending_inference_job_count_handler;
use crate::http_server::endpoints::inference_job::kill_inference_jobs::kill_generic_inference_jobs_handler;
@@ -55,7 +57,6 @@ use crate::http_server::endpoints::misc::enable_alpha_easy_handler::enable_alpha
use crate::http_server::endpoints::misc::enable_alpha_handler::enable_alpha_handler;
use crate::http_server::endpoints::misc::root_index::get_root_index;
use crate::http_server::endpoints::mocap::enqueue_mocapnet::enqueue_mocapnet_handler;
use crate::http_server::endpoints::workflows::enqueue_comfy_ui::enqueue_comfy_ui_handler;
use crate::http_server::endpoints::moderation::approval::pending_w2l_templates::get_pending_w2l_templates_handler;
use crate::http_server::endpoints::moderation::categories::delete_category::delete_category_handler;
use crate::http_server::endpoints::moderation::categories::edit_category::edit_category_handler;
@@ -167,7 +168,7 @@ use crate::http_server::endpoints::weights::list_weights_by_user::list_weights_b
use crate::http_server::endpoints::weights::search_model_weights_handler::search_model_weights_handler;
use crate::http_server::endpoints::weights::set_model_weight_cover_image::set_model_weight_cover_image_handler;
use crate::http_server::endpoints::weights::update_weight::update_weight_handler;
use crate::http_server::endpoints::image_gen::enqueue_image_generation::enqueue_image_generation_request;
use crate::http_server::endpoints::workflows::enqueue_comfy_ui::enqueue_comfy_ui_handler;
pub fn add_routes<T, B> (app: App<T>, server_environment: ServerEnvironment) -> App<T>
where
@@ -250,6 +251,12 @@ pub fn add_routes<T, B> (app: App<T>, server_environment: ServerEnvironment) ->
.add_get("/v1/model_inference/queue_length", get_pending_inference_job_count_handler)
.into_app();
// ==================== Format Conversion ====================
let mut app = RouteBuilder::from_app(app)
.add_post("/v1/conversion/enqueue_fbx_to_gltf", enqueue_fbx_to_gltf_handler)
.into_app();
// ==================== Stats ====================
let mut app = RouteBuilder::from_app(app)