From 46a7993bfb9036fab6829c48fc7d8e2ee5dd34b7 Mon Sep 17 00:00:00 2001 From: Brandon Thomas Date: Sun, 17 May 2026 00:11:12 -0400 Subject: [PATCH] timeout for gmiclient --- .../api/video/seedance_2_0_260128/api.rs | 17 +++++++++-- .../api/video/seedance_2_0_fast_260128/api.rs | 17 +++++++++-- .../src/requests/common/create_request.rs | 30 +++++++++++++++++-- .../src/requests/context/mod.rs | 1 + .../src/requests/context/request_context.rs | 8 +++++ .../gmicloud_client/src/requests/mod.rs | 1 + 6 files changed, 67 insertions(+), 7 deletions(-) create mode 100644 crates/api_clients/gmicloud_client/src/requests/context/mod.rs create mode 100644 crates/api_clients/gmicloud_client/src/requests/context/request_context.rs diff --git a/crates/api_clients/gmicloud_client/src/requests/api/video/seedance_2_0_260128/api.rs b/crates/api_clients/gmicloud_client/src/requests/api/video/seedance_2_0_260128/api.rs index 1d19a29dc5..9ac0b5ead9 100644 --- a/crates/api_clients/gmicloud_client/src/requests/api/video/seedance_2_0_260128/api.rs +++ b/crates/api_clients/gmicloud_client/src/requests/api/video/seedance_2_0_260128/api.rs @@ -2,8 +2,10 @@ use crate::creds::gmicloud_api_key::GmiCloudApiKey; use crate::error::gmicloud_error::GmiCloudError; use crate::requests::api::video::seedance_2_0_260128::raw_request::Seedance20Payload; use crate::requests::common::create_request::{ - create_gmicloud_request, GmiCloudCreateRequest, GmiCloudCreateResponse, + create_gmicloud_request, create_gmicloud_request_with_context, + GmiCloudCreateRequest, GmiCloudCreateResponse, }; +use crate::requests::context::request_context::RequestContext; const MODEL_ID: &str = "seedance-2-0-260128"; @@ -113,12 +115,23 @@ impl Seedance20Request { pub async fn send_request( &self, api_key: &GmiCloudApiKey, + ) -> Result { + let context = RequestContext { + api_key, + maybe_timeout: None, + }; + self.send_request_with_context(&context).await + } + + pub async fn send_request_with_context( + &self, + context: &RequestContext<'_>, ) -> Result { let body = GmiCloudCreateRequest { model: MODEL_ID.to_string(), payload: self.to_raw_payload(), }; - create_gmicloud_request(api_key, &body).await + create_gmicloud_request_with_context(context, &body).await } pub fn model_id() -> &'static str { diff --git a/crates/api_clients/gmicloud_client/src/requests/api/video/seedance_2_0_fast_260128/api.rs b/crates/api_clients/gmicloud_client/src/requests/api/video/seedance_2_0_fast_260128/api.rs index 6b2eed5e38..3d836e9fcf 100644 --- a/crates/api_clients/gmicloud_client/src/requests/api/video/seedance_2_0_fast_260128/api.rs +++ b/crates/api_clients/gmicloud_client/src/requests/api/video/seedance_2_0_fast_260128/api.rs @@ -2,8 +2,10 @@ use crate::creds::gmicloud_api_key::GmiCloudApiKey; use crate::error::gmicloud_error::GmiCloudError; use crate::requests::api::video::seedance_2_0_fast_260128::raw_request::Seedance20FastPayload; use crate::requests::common::create_request::{ - create_gmicloud_request, GmiCloudCreateRequest, GmiCloudCreateResponse, + create_gmicloud_request, create_gmicloud_request_with_context, + GmiCloudCreateRequest, GmiCloudCreateResponse, }; +use crate::requests::context::request_context::RequestContext; const MODEL_ID: &str = "seedance-2-0-fast-260128"; @@ -111,12 +113,23 @@ impl Seedance20FastRequest { pub async fn send_request( &self, api_key: &GmiCloudApiKey, + ) -> Result { + let context = RequestContext { + api_key, + maybe_timeout: None, + }; + self.send_request_with_context(&context).await + } + + pub async fn send_request_with_context( + &self, + context: &RequestContext<'_>, ) -> Result { let body = GmiCloudCreateRequest { model: MODEL_ID.to_string(), payload: self.to_raw_payload(), }; - create_gmicloud_request(api_key, &body).await + create_gmicloud_request_with_context(context, &body).await } pub fn model_id() -> &'static str { diff --git a/crates/api_clients/gmicloud_client/src/requests/common/create_request.rs b/crates/api_clients/gmicloud_client/src/requests/common/create_request.rs index bd137a279b..56bb3636b8 100644 --- a/crates/api_clients/gmicloud_client/src/requests/common/create_request.rs +++ b/crates/api_clients/gmicloud_client/src/requests/common/create_request.rs @@ -1,3 +1,5 @@ +use std::time::Duration; + use log::warn; use serde::{Deserialize, Serialize}; @@ -5,9 +7,14 @@ use crate::creds::gmicloud_api_key::GmiCloudApiKey; use crate::error::gmicloud_error::GmiCloudError; use crate::error::gmicloud_generic_api_error::GmiCloudGenericApiError; use crate::error::gmicloud_specific_api_error::GmiCloudSpecificApiError; +use crate::requests::context::request_context::RequestContext; const BASE_URL: &str = "https://console.gmicloud.ai/api/v1/ie/requestqueue/apikey"; +/// Default request timeout. Video requests return quickly (async queue), +/// but image requests block until completion and can take 60+ seconds. +const DEFAULT_TIMEOUT: Duration = Duration::from_secs(180); + /// The top-level request body sent to `POST /requests`. #[derive(Debug, Serialize)] pub struct GmiCloudCreateRequest { @@ -23,17 +30,34 @@ pub struct GmiCloudCreateResponse { pub status: String, } -/// Submit a video generation request to GmiCloud. +/// Submit a request to GmiCloud using just an API key (default timeout). pub async fn create_gmicloud_request( api_key: &GmiCloudApiKey, body: &GmiCloudCreateRequest

, ) -> Result { + let context = RequestContext { + api_key, + maybe_timeout: None, + }; + create_gmicloud_request_with_context(&context, body).await +} + +/// Submit a request to GmiCloud with explicit context (custom timeout, etc.). +pub async fn create_gmicloud_request_with_context( + context: &RequestContext<'_>, + body: &GmiCloudCreateRequest

, +) -> Result { let url = format!("{}/requests", BASE_URL); + let timeout = context.maybe_timeout.unwrap_or(DEFAULT_TIMEOUT); + + let client = reqwest::Client::builder() + .timeout(timeout) + .build() + .map_err(GmiCloudGenericApiError::from)?; - let client = reqwest::Client::new(); let response = client .post(&url) - .header("Authorization", format!("Bearer {}", api_key.as_str())) + .header("Authorization", format!("Bearer {}", context.api_key.as_str())) .json(body) .send() .await diff --git a/crates/api_clients/gmicloud_client/src/requests/context/mod.rs b/crates/api_clients/gmicloud_client/src/requests/context/mod.rs new file mode 100644 index 0000000000..c5c6f6fabd --- /dev/null +++ b/crates/api_clients/gmicloud_client/src/requests/context/mod.rs @@ -0,0 +1 @@ +pub mod request_context; diff --git a/crates/api_clients/gmicloud_client/src/requests/context/request_context.rs b/crates/api_clients/gmicloud_client/src/requests/context/request_context.rs new file mode 100644 index 0000000000..a3af82918f --- /dev/null +++ b/crates/api_clients/gmicloud_client/src/requests/context/request_context.rs @@ -0,0 +1,8 @@ +use std::time::Duration; + +use crate::creds::gmicloud_api_key::GmiCloudApiKey; + +pub struct RequestContext<'a> { + pub api_key: &'a GmiCloudApiKey, + pub maybe_timeout: Option, +} diff --git a/crates/api_clients/gmicloud_client/src/requests/mod.rs b/crates/api_clients/gmicloud_client/src/requests/mod.rs index 12493e3cc9..b698f1a58d 100644 --- a/crates/api_clients/gmicloud_client/src/requests/mod.rs +++ b/crates/api_clients/gmicloud_client/src/requests/mod.rs @@ -1,3 +1,4 @@ pub mod api; pub mod common; +pub mod context; pub mod poll_request_queue;