mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-10 03:51:25 +00:00
third request
This commit is contained in:
1 parent
42e3eb6739
commit
6c996c6bc1
4 files changed
+145
-2
No files matched your search
+9
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"upload_id": "cf326bd0-b7eb-454c-b433-54f36eb4d5a6/asset.jpg",
|
||||
"upload_url": "https://storage.googleapis.com/wlt-training-gsc-marble-assets-prod/temp/objects/cf326bd0-b7eb-454c-b433-54f36eb4d5a6/asset.jpg?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=wlt-training-gsc-sa%40wlt-training-gsc.iam.gserviceaccount.com%2F20251210%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20251210T001237Z&X-Goog-Expires=3600&X-Goog-SignedHeaders=content-type%3Bhost%3Bx-goog-content-length-range&X-Goog-Signature=338a4058e69f0f4d717e64ffbd9ac5609b63a67a43a9cb5027a65822edafee2dcf6769dafda8d82f812b0a009c53af77df6c8163e2d884bee2ab1a33ce63894e43f5faac07553528feadcc009f71f9b6195f6a2f73c1c3f8e5772a63d53c7c0ffc937d3c96b221cf760367bf435318f6c463b029d7879f26064acb5ab8e404d18a16b9263a0157b4edcfffe840b682a6e8198f342dcee51b928f235e1618aa98fdd7ee55bca8f27017738037b81b3041f12a72903c0decbc0d83b3fd39bb0edd3b750441bc21e9a226723876e4a52164b61659678e24f8af001451fa84a14c01b372d71cd55abaacd67e2b32df55f65a49f6ba0640b5239ab23b7eb45ad30d54",
|
||||
"required_headers": {
|
||||
"Content-Type": "image/jpeg",
|
||||
"x-goog-content-length-range": "0,1048576000"
|
||||
},
|
||||
"curl_example": "curl -X PUT -H 'Content-Type: image/jpeg' -H 'x-goog-content-length-range: 0,1048576000' --upload-file my-file 'https://storage.googleapis.com/wlt-training-gsc-marble-assets-prod/temp/objects/cf326bd0-b7eb-454c-b433-54f36eb4d5a6/asset.jpg?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=wlt-training-gsc-sa%40wlt-training-gsc.iam.gserviceaccount.com%2F20251210%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20251210T001237Z&X-Goog-Expires=3600&X-Goog-SignedHeaders=content-type%3Bhost%3Bx-goog-content-length-range&X-Goog-Signature=338a4058e69f0f4d717e64ffbd9ac5609b63a67a43a9cb5027a65822edafee2dcf6769dafda8d82f812b0a009c53af77df6c8163e2d884bee2ab1a33ce63894e43f5faac07553528feadcc009f71f9b6195f6a2f73c1c3f8e5772a63d53c7c0ffc937d3c96b221cf760367bf435318f6c463b029d7879f26064acb5ab8e404d18a16b9263a0157b4edcfffe840b682a6e8198f342dcee51b928f235e1618aa98fdd7ee55bca8f27017738037b81b3041f12a72903c0decbc0d83b3fd39bb0edd3b750441bc21e9a226723876e4a52164b61659678e24f8af001451fa84a14c01b372d71cd55abaacd67e2b32df55f65a49f6ba0640b5239ab23b7eb45ad30d54'"
|
||||
}
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"upload_id":"cf326bd0-b7eb-454c-b433-54f36eb4d5a6/asset.jpg","upload_url":"https://storage.googleapis.com/wlt-training-gsc-marble-assets-prod/temp/objects/cf326bd0-b7eb-454c-b433-54f36eb4d5a6/asset.jpg?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=wlt-training-gsc-sa%40wlt-training-gsc.iam.gserviceaccount.com%2F20251210%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20251210T001237Z&X-Goog-Expires=3600&X-Goog-SignedHeaders=content-type%3Bhost%3Bx-goog-content-length-range&X-Goog-Signature=338a4058e69f0f4d717e64ffbd9ac5609b63a67a43a9cb5027a65822edafee2dcf6769dafda8d82f812b0a009c53af77df6c8163e2d884bee2ab1a33ce63894e43f5faac07553528feadcc009f71f9b6195f6a2f73c1c3f8e5772a63d53c7c0ffc937d3c96b221cf760367bf435318f6c463b029d7879f26064acb5ab8e404d18a16b9263a0157b4edcfffe840b682a6e8198f342dcee51b928f235e1618aa98fdd7ee55bca8f27017738037b81b3041f12a72903c0decbc0d83b3fd39bb0edd3b750441bc21e9a226723876e4a52164b61659678e24f8af001451fa84a14c01b372d71cd55abaacd67e2b32df55f65a49f6ba0640b5239ab23b7eb45ad30d54","required_headers":{"Content-Type":"image/jpeg","x-goog-content-length-range":"0,1048576000"},"curl_example":"curl -X PUT -H 'Content-Type: image/jpeg' -H 'x-goog-content-length-range: 0,1048576000' --upload-file my-file 'https://storage.googleapis.com/wlt-training-gsc-marble-assets-prod/temp/objects/cf326bd0-b7eb-454c-b433-54f36eb4d5a6/asset.jpg?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=wlt-training-gsc-sa%40wlt-training-gsc.iam.gserviceaccount.com%2F20251210%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20251210T001237Z&X-Goog-Expires=3600&X-Goog-SignedHeaders=content-type%3Bhost%3Bx-goog-content-length-range&X-Goog-Signature=338a4058e69f0f4d717e64ffbd9ac5609b63a67a43a9cb5027a65822edafee2dcf6769dafda8d82f812b0a009c53af77df6c8163e2d884bee2ab1a33ce63894e43f5faac07553528feadcc009f71f9b6195f6a2f73c1c3f8e5772a63d53c7c0ffc937d3c96b221cf760367bf435318f6c463b029d7879f26064acb5ab8e404d18a16b9263a0157b4edcfffe840b682a6e8198f342dcee51b928f235e1618aa98fdd7ee55bca8f27017738037b81b3041f12a72903c0decbc0d83b3fd39bb0edd3b750441bc21e9a226723876e4a52164b61659678e24f8af001451fa84a14c01b372d71cd55abaacd67e2b32df55f65a49f6ba0640b5239ab23b7eb45ad30d54'"}
|
||||
+134
@@ -0,0 +1,134 @@
|
||||
use crate::api::api_types::object_id::ObjectId;
|
||||
use crate::api::api_types::upload_id::UploadId;
|
||||
use crate::api::api_types::upload_mime_type::UploadMimeType;
|
||||
use crate::api::common::common_header_values::{ORIGIN_VALUE, REFERER_VALUE};
|
||||
use crate::credentials::world_labs_bearer_token::WorldLabsBearerToken;
|
||||
use crate::credentials::world_labs_cookies::WorldLabsCookies;
|
||||
use crate::error::world_labs_client_error::WorldLabsClientError;
|
||||
use crate::error::world_labs_error::WorldLabsError;
|
||||
use crate::error::world_labs_generic_api_error::WorldLabsGenericApiError;
|
||||
use chrono::Utc;
|
||||
use http_headers::names::{PRIORITY, SEC_FETCH_DEST, SEC_FETCH_MODE, SEC_FETCH_SITE, SEC_GPC};
|
||||
use http_headers::values::accept::ACCEPT_ALL;
|
||||
use http_headers::values::cache_control::CACHE_CONTROL_NO_CACHE;
|
||||
use http_headers::values::connection::CONNECTION_KEEP_ALIVE;
|
||||
use http_headers::values::content_type::CONTENT_TYPE_APPLICATION_JSON;
|
||||
use http_headers::values::pragma::PRAGMA_NO_CACHE;
|
||||
use http_headers::values::priority::PRIORITY_4;
|
||||
use http_headers::values::sec::{SEC_FETCH_DEST_EMPTY, SEC_FETCH_MODE_CORS, SEC_FETCH_SITE_CROSS_SITE};
|
||||
use http_headers::values::te::TE_TRAILERS;
|
||||
use log::error;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::time::Duration;
|
||||
use uuid::Uuid;
|
||||
use wreq::header::{ACCEPT, ACCEPT_ENCODING, ACCEPT_LANGUAGE, AUTHORIZATION, CACHE_CONTROL, CONNECTION, CONTENT_LENGTH, CONTENT_TYPE, ORIGIN, PRAGMA, REFERER, TE};
|
||||
use wreq::Client;
|
||||
use wreq_util::Emulation;
|
||||
|
||||
const BASE_URL : &str = "https://marble2-kgw-prod-iac1.wlt-ai.art/api/v1/objects";
|
||||
|
||||
fn get_url(object_id: &ObjectId) -> String {
|
||||
format!("{}/{}:upload", BASE_URL, object_id.0)
|
||||
}
|
||||
|
||||
pub struct BeginObjectImageUploadArgs<'a> {
|
||||
pub cookies: &'a WorldLabsCookies,
|
||||
pub bearer_token: &'a WorldLabsBearerToken,
|
||||
pub upload_mime_type: UploadMimeType,
|
||||
pub object_id: &'a ObjectId,
|
||||
pub request_timeout: Option<Duration>,
|
||||
}
|
||||
|
||||
pub struct BeginObjectImageUploadResponse {
|
||||
pub upload_url: String,
|
||||
}
|
||||
|
||||
/// Marble Image-to-World
|
||||
/// This request follows object attachment and signals upload. It returns the upload URL.
|
||||
/// Request #3 (of ~10)
|
||||
pub async fn begin_object_image_upload(args: BeginObjectImageUploadArgs<'_>) -> Result<BeginObjectImageUploadResponse, WorldLabsError> {
|
||||
let client = Client::builder()
|
||||
.emulation(Emulation::Firefox143)
|
||||
.build()
|
||||
.map_err(|err| WorldLabsClientError::WreqClientError(err))?;
|
||||
|
||||
let url = get_url(args.object_id);
|
||||
|
||||
let mut request_builder = client.post(url)
|
||||
.header(ACCEPT, ACCEPT_ALL)
|
||||
.header(ACCEPT_LANGUAGE, "en-US,en;q=0.5")
|
||||
.header(ACCEPT_ENCODING, "gzip, deflate, br, zstd")
|
||||
.header(REFERER, REFERER_VALUE)
|
||||
.header(CONTENT_TYPE, CONTENT_TYPE_APPLICATION_JSON)
|
||||
.header(AUTHORIZATION, args.bearer_token.to_bearer_token_string())
|
||||
.header(ORIGIN, ORIGIN_VALUE)
|
||||
.header(SEC_GPC, "1")
|
||||
.header(CONNECTION, CONNECTION_KEEP_ALIVE)
|
||||
.header(SEC_FETCH_DEST, SEC_FETCH_DEST_EMPTY)
|
||||
.header(SEC_FETCH_MODE, SEC_FETCH_MODE_CORS)
|
||||
.header(SEC_FETCH_SITE, SEC_FETCH_SITE_CROSS_SITE)
|
||||
.header(PRIORITY, PRIORITY_4)
|
||||
.header(PRAGMA, PRAGMA_NO_CACHE)
|
||||
.header(CACHE_CONTROL, CACHE_CONTROL_NO_CACHE)
|
||||
.header(CONTENT_LENGTH, 0)
|
||||
.header(TE, TE_TRAILERS);
|
||||
|
||||
if let Some(timeout) = args.request_timeout {
|
||||
request_builder = request_builder.timeout(timeout);
|
||||
}
|
||||
|
||||
let http_request = request_builder
|
||||
.build()
|
||||
.map_err(|err| {
|
||||
error!("Error building request: {:?}", err);
|
||||
WorldLabsClientError::WreqClientError(err)
|
||||
})?;
|
||||
|
||||
let response = client.execute(http_request)
|
||||
.await
|
||||
.map_err(|err| {
|
||||
error!("Error during request execution: {:?}", err);
|
||||
WorldLabsGenericApiError::WreqError(err)
|
||||
})?;
|
||||
|
||||
let status = response.status();
|
||||
|
||||
let response_body = response.text()
|
||||
.await
|
||||
.map_err(|err| {
|
||||
error!("Error reading response body: {:?}", err);
|
||||
WorldLabsGenericApiError::WreqError(err)
|
||||
})?;
|
||||
|
||||
// TODO: Handle errors (Cloudflare, Grok, etc.)
|
||||
if !status.is_success() {
|
||||
error!("Request returned an error (code {}) : {:?}", status.as_u16(), response_body);
|
||||
//return Err(classify_general_http_status_code_and_body(status, response_body));
|
||||
}
|
||||
|
||||
let response : RawResponse = serde_json::from_str(&response_body)
|
||||
.map_err(|err| WorldLabsGenericApiError::SerdeResponseParseErrorWithBody(err, response_body.to_string()))?;
|
||||
|
||||
Ok(BeginObjectImageUploadResponse {
|
||||
upload_url: response.upload_url,
|
||||
})
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct RawResponse {
|
||||
/// eg. "https://storage.googleapis.com/wlt-training-gsc-marble-assets-prod/temp/objects/{...}",
|
||||
pub upload_url: String,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::api::api_types::object_id::ObjectId;
|
||||
use crate::api::requests::objects::begin_object_image_upload::get_url;
|
||||
|
||||
#[test]
|
||||
fn test_get_url() {
|
||||
let object_id = ObjectId("foo-bar-baz-bin".to_string());
|
||||
let expected = "https://marble2-kgw-prod-iac1.wlt-ai.art/api/v1/objects/foo-bar-baz-bin:upload";
|
||||
assert_eq!(get_url(&object_id), expected);
|
||||
}
|
||||
}
|
||||
@@ -1,2 +1,3 @@
|
||||
pub mod create_object;
|
||||
mod begin_object_image_attachment;
|
||||
pub mod begin_object_image_attachment;
|
||||
pub mod begin_object_image_upload;
|
||||
Reference in new issue
Block a user