diff --git a/crates/schema/database/mysql_queries/src/queries/media_files/get/batch_get_media_files_by_tokens.rs b/crates/schema/database/mysql_queries/src/queries/media_files/get/batch_get_media_files_by_tokens.rs index 6a3f74ee8a..c0a70ea2d4 100644 --- a/crates/schema/database/mysql_queries/src/queries/media_files/get/batch_get_media_files_by_tokens.rs +++ b/crates/schema/database/mysql_queries/src/queries/media_files/get/batch_get_media_files_by_tokens.rs @@ -1,7 +1,7 @@ use chrono::{DateTime, Utc}; use sqlx::mysql::MySqlRow; use sqlx::{Acquire, FromRow, MySql, MySqlPool, QueryBuilder, Row}; - +use sqlx::pool::PoolConnection; use enums::by_table::media_files::media_file_animation_type::MediaFileAnimationType; use enums::by_table::media_files::media_file_class::MediaFileClass; use enums::by_table::media_files::media_file_engine_category::MediaFileEngineCategory; @@ -84,6 +84,18 @@ pub async fn batch_get_media_files_by_tokens( ).await } +pub async fn batch_get_media_files_by_tokens_with_connection( + mysql_connection: &mut PoolConnection, + media_file_tokens: &[MediaFileToken], + can_see_deleted: bool +) -> AnyhowResult> { + batch_get_media_files_by_tokens_with_transactor( + Transactor::Connection{ connection: mysql_connection }, + media_file_tokens, + can_see_deleted + ).await +} + pub async fn batch_get_media_files_by_tokens_with_transactor( transactor: Transactor<'_, '_>, media_file_tokens: &[MediaFileToken], diff --git a/crates/service/web/storyteller_web/src/http_server/endpoints/generate/image/edit/gpt_image_1_edit_image_handler.rs b/crates/service/web/storyteller_web/src/http_server/endpoints/generate/image/edit/gpt_image_1_edit_image_handler.rs index 97511dd03e..6766c3eeec 100644 --- a/crates/service/web/storyteller_web/src/http_server/endpoints/generate/image/edit/gpt_image_1_edit_image_handler.rs +++ b/crates/service/web/storyteller_web/src/http_server/endpoints/generate/image/edit/gpt_image_1_edit_image_handler.rs @@ -9,6 +9,7 @@ use actix_web::web::Json; use actix_web::{web, HttpRequest}; use artcraft_api_defs::generate::image::edit::gpt_image_1_edit_image::{GptImage1EditImageImageQuality, GptImage1EditImageImageSize, GptImage1EditImageNumImages, GptImage1EditImageRequest, GptImage1EditImageResponse}; use bucket_paths::legacy::typified_paths::public::media_files::bucket_file_path::MediaFileBucketPath; +use enums::by_table::prompts::prompt_type::PromptType; use enums::common::visibility::Visibility; use fal_client::creds::open_ai_api_key::OpenAiApiKey; use fal_client::requests::webhook::image::enqueue_gpt_image_1_edit_image_webhook::enqueue_gpt_image_1_edit_image_webhook; @@ -20,7 +21,9 @@ use mysql_queries::queries::generic_inference::fal::insert_generic_inference_job use mysql_queries::queries::generic_inference::fal::insert_generic_inference_job_for_fal_queue::FalCategory; use mysql_queries::queries::generic_inference::fal::insert_generic_inference_job_for_fal_queue::InsertGenericInferenceForFalArgs; use mysql_queries::queries::idepotency_tokens::insert_idempotency_token::insert_idempotency_token; -use mysql_queries::queries::media_files::get::batch_get_media_files_by_tokens::batch_get_media_files_by_tokens; +use mysql_queries::queries::media_files::get::batch_get_media_files_by_tokens::{batch_get_media_files_by_tokens, batch_get_media_files_by_tokens_with_connection}; +use mysql_queries::queries::prompts::insert_prompt::{insert_prompt, InsertPromptArgs}; +use sqlx::Acquire; use utoipa::ToSchema; /// Gpt Image 1 Image Editing @@ -40,9 +43,17 @@ pub async fn gpt_image_1_edit_image_handler( request: Json, server_state: web::Data> ) -> Result, CommonWebError> { + let mut mysql_connection = server_state.mysql_pool + .acquire() + .await + .map_err(|err| { + error!("MySql pool error: {:?}", err); + CommonWebError::ServerError + })?; + let maybe_user_session = server_state .session_checker - .maybe_get_user_session(&http_request, &server_state.mysql_pool) + .maybe_get_user_session_from_connection(&http_request, &mut mysql_connection) .await .map_err(|e| { warn!("Session checker error: {:?}", e); @@ -77,8 +88,8 @@ pub async fn gpt_image_1_edit_image_handler( } }; - let result = batch_get_media_files_by_tokens( - &server_state.mysql_pool, + let result = batch_get_media_files_by_tokens_with_connection( + &mut mysql_connection, tokens, CAN_SEE_DELETED, ).await; @@ -116,7 +127,7 @@ pub async fn gpt_image_1_edit_image_handler( }) .collect::>(); - insert_idempotency_token(&request.uuid_idempotency_token, &server_state.mysql_pool) + insert_idempotency_token(&request.uuid_idempotency_token, &mut *mysql_connection) .await .map_err(|err| { error!("Error inserting idempotency token: {:?}", err); @@ -180,17 +191,48 @@ pub async fn gpt_image_1_edit_image_handler( let ip_address = get_request_ip(&http_request); + let mut transaction = mysql_connection + .begin() + .await + .map_err(|err| { + error!("Error starting MySQL transaction: {:?}", err); + CommonWebError::ServerError + })?; + + // NB: Don't fail the job if the query fails. + let prompt_result = insert_prompt(InsertPromptArgs { + maybe_apriori_prompt_token: None, + prompt_type: PromptType::ArtcraftApp, + maybe_creator_user_token: maybe_user_session + .as_ref() + .map(|s| &s.user_token), + maybe_positive_prompt: request.prompt.as_deref(), + maybe_negative_prompt: None, + maybe_other_args: None, + creator_ip_address: &ip_address, + mysql_executor: &mut *transaction, + phantom: Default::default(), + }).await; + + let prompt_token = match prompt_result { + Ok(token) => Some(token), + Err(err) => { + warn!("Error inserting prompt: {:?}", err); + None // Don't fail the job if the prompt insertion fails. + } + }; + let db_result = insert_generic_inference_job_for_fal_queue(InsertGenericInferenceForFalArgs { uuid_idempotency_token: &request.uuid_idempotency_token, maybe_external_third_party_id: &external_job_id, fal_category: FalCategory::ImageGeneration, maybe_inference_args: None, - maybe_prompt_token: None, + maybe_prompt_token: prompt_token.as_ref(), maybe_creator_user_token: maybe_user_session.as_ref().map(|s| &s.user_token), maybe_avt_token: maybe_avt_token.as_ref(), creator_ip_address: &ip_address, creator_set_visibility: Visibility::Public, - mysql_executor: &server_state.mysql_pool, + mysql_executor: &mut *transaction, phantom: Default::default(), }).await; @@ -201,6 +243,14 @@ pub async fn gpt_image_1_edit_image_handler( return Err(CommonWebError::ServerError); } }; + + let _r = transaction + .commit() + .await + .map_err(|err| { + error!("Error committing MySQL transaction: {:?}", err); + CommonWebError::ServerError + })?; Ok(Json(GptImage1EditImageResponse { success: true,