From f521a8a6eb6d6dbb0a034c23d96814a8d00a034c Mon Sep 17 00:00:00 2001 From: Brandon Thomas Date: Tue, 9 Dec 2025 21:10:22 -0500 Subject: [PATCH] request wip --- .../r1_objects_request_json.json | 11 ++ .../objects/objects_create_initial.rs | 121 ++++++++++++++---- 2 files changed, 110 insertions(+), 22 deletions(-) create mode 100644 crates/api_clients/world_labs_client/src/requests/_metadata/request_flow_3_firefox/r1_objects_request_json.json diff --git a/crates/api_clients/world_labs_client/src/requests/_metadata/request_flow_3_firefox/r1_objects_request_json.json b/crates/api_clients/world_labs_client/src/requests/_metadata/request_flow_3_firefox/r1_objects_request_json.json new file mode 100644 index 0000000000..d7142135b4 --- /dev/null +++ b/crates/api_clients/world_labs_client/src/requests/_metadata/request_flow_3_firefox/r1_objects_request_json.json @@ -0,0 +1,11 @@ +{ + "metadata": { + "version": "0.0.1", + "createdAt": 1765325556528, + "updatedAt": 1765325556528, + "useAdvancedEditing": false, + "draftMode": false, + "nodes": {} + }, + "mime_type": "application/run+json" +} diff --git a/crates/api_clients/world_labs_client/src/requests/objects/objects_create_initial.rs b/crates/api_clients/world_labs_client/src/requests/objects/objects_create_initial.rs index 204e36379e..a96d517830 100644 --- a/crates/api_clients/world_labs_client/src/requests/objects/objects_create_initial.rs +++ b/crates/api_clients/world_labs_client/src/requests/objects/objects_create_initial.rs @@ -3,6 +3,7 @@ use crate::credentials::world_labs_cookies::WorldLabsCookies; use crate::error::world_labs_client_error::WorldLabsClientError; use crate::error::world_labs_error::WorldLabsError; use crate::requests::common::common_header_values::{ORIGIN_VALUE, REFERER_VALUE}; +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; @@ -12,9 +13,13 @@ use http_headers::values::pragma::PRAGMA_NO_CACHE; use http_headers::values::priority::PRIORITY_HIGHEST; 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 serde::Serialize; +use std::time::Duration; +use log::error; use wreq::header::{ACCEPT, ACCEPT_ENCODING, ACCEPT_LANGUAGE, AUTHORIZATION, CACHE_CONTROL, CONNECTION, CONTENT_TYPE, ORIGIN, PRAGMA, REFERER, TE}; use wreq::Client; use wreq_util::Emulation; +use crate::error::world_labs_generic_api_error::WorldLabsGenericApiError; const URL : &str = "https://marble2-kgw-prod-iac1.wlt-ai.art/api/v1/objects"; @@ -23,6 +28,7 @@ pub struct ObjectsCreateInitialArgs<'a> { pub cookies: &'a WorldLabsCookies, pub bearer_token: &'a WorldLabsBearerToken, + pub request_timeout: Option, } pub async fn objects_create_initial(args: ObjectsCreateInitialArgs<'_>) -> Result<(), WorldLabsError> { @@ -31,27 +37,6 @@ pub async fn objects_create_initial(args: ObjectsCreateInitialArgs<'_>) -> Resul .build() .map_err(|err| WorldLabsClientError::WreqClientError(err))?; - /* - -H 'User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0' \ - -H 'Accept: * / *' \ - -H 'Accept-Language: en-US,en;q=0.5' \ - -H 'Accept-Encoding: gzip, deflate, br, zstd' \ - -H 'Referer: https://marble.worldlabs.ai/' \ - -H 'content-type: application/json' \ - -H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6Ijk1MTg5MTkxMTA3NjA1NDM0NGUxNWUyNTY0MjViYjQyNWVlYjNhNWMiLCJ0eXAiOiJKV1QifQ.eyJuYW1lIjoiVmljdG9yIFZvaWNlIiwicGljdHVyZSI6Imh0dHBzOi8vbGgzLmdvb2dsZXVzZXJjb250ZW50LmNvbS9hL0FDZzhvY0t3MGFhWEtZU3F5LVhra242OXlkSUpGR25KQTM3UzEzWHZqTlk0ZDl4Q3pVektVdz1zOTYtYyIsImlzcyI6Imh0dHBzOi8vc2VjdXJldG9rZW4uZ29vZ2xlLmNvbS93bHQtdHJhaW5pbmctZ3NjIiwiYXVkIjoid2x0LXRyYWluaW5nLWdzYyIsImF1dGhfdGltZSI6MTc2NTMyNTM3NCwidXNlcl9pZCI6InNWZ0FRRHlIM0JmWU9CZkY2ZXBXVGpMSHlnWDIiLCJzdWIiOiJzVmdBUUR5SDNCZllPQmZGNmVwV1RqTEh5Z1gyIiwiaWF0IjoxNzY1MzI1Mzc0LCJleHAiOjE3NjUzMjg5NzQsImVtYWlsIjoidmljdG9ydm9pY2U4OUBnbWFpbC5jb20iLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiZmlyZWJhc2UiOnsiaWRlbnRpdGllcyI6eyJnb29nbGUuY29tIjpbIjExNjQ1OTMwMDE5ODYxOTg4ODgzNiJdLCJlbWFpbCI6WyJ2aWN0b3J2b2ljZTg5QGdtYWlsLmNvbSJdfSwic2lnbl9pbl9wcm92aWRlciI6Imdvb2dsZS5jb20ifX0.U_mp4iAw14poJz11UFKg3QVO6TSfE8Gps6VqLhg4GLLumjilgnuyD8mnKFznRFX0R-OyBf8mugVk59zfy4BugeZ0cXRkm1FWHqR9BVJZ9BQoEobXw4RqHkUvtgSe2qnx8a4fLUVp5zxNPpXfEjLAdcG4YnNwdZ7-TxyCDvO3U_WHkG3aAJup1q5KOqURDeYoQ7m7THeobyM3pnmDO03GIMdYgLV3Lnpvk6FTprtsV8SxWr8ZJ-Cy1g_I9wtKcB4B5bIFLjfV4r8W_-uq_g5ddbri-Yy28Ah97jxFIFOVChbPSbQpS-TRshW6M2cM5Y2EhGudpgVQBM-Tekco9fGSRw' \ - -H 'Origin: https://marble.worldlabs.ai' \ - -H 'Sec-GPC: 1' \ - -H 'Connection: keep-alive' \ - -H 'Sec-Fetch-Dest: empty' \ - -H 'Sec-Fetch-Mode: cors' \ - -H 'Sec-Fetch-Site: cross-site' \ - -H 'Priority: u=0' \ - -H 'Pragma: no-cache' \ - -H 'Cache-Control: no-cache' \ - -H 'TE: trailers' \ - --data-raw '{"metadata":{"version":"0.0.1","createdAt":1765325556528,"updatedAt":1765325556528,"useAdvancedEditing":false,"draftMode":false,"nodes":{}},"mime_type":"application/run+json"}' - */ - let mut request_builder = client.post(URL) .header(ACCEPT, ACCEPT_ALL) .header(ACCEPT_LANGUAGE, "en-US,en;q=0.5") @@ -70,7 +55,99 @@ pub async fn objects_create_initial(args: ObjectsCreateInitialArgs<'_>) -> Resul .header(CACHE_CONTROL, CACHE_CONTROL_NO_CACHE) .header(TE, TE_TRAILERS); + if let Some(timeout) = args.request_timeout { + request_builder = request_builder.timeout(timeout); + } + let request_payload = RawRequest::default(); + + let http_request = request_builder.json(&request_payload) + .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 : CreateMediaPostRawResponse = serde_json::from_str(&response_body) + .map_err(|err| GrokGenericApiError::SerdeResponseParseErrorWithBody(err, response_body.to_string()))?; + + Ok(GrokCreateMediaPostResponse { + post_id: PostId(response.post.id), + }) Ok(()) -} \ No newline at end of file +} + +#[derive(Serialize)] +struct RawRequest { + pub metadata: RawRequestMetadata, + pub mime_type: String, +} + +#[derive(Serialize)] +struct RawRequestMetadata { + pub version: String, + + #[serde(rename = "createdAt")] + pub created_at: u64, + + #[serde(rename = "updatedAt")] + pub updated_at: u64, + + #[serde(rename = "usesAdvancedEditing")] + pub uses_advanced_editing: bool, + + #[serde(rename = "draftMode")] + pub draft_mode: bool, + + pub nodes: RawRequestNodes, +} + +#[derive(Serialize)] +struct RawRequestNodes { +} + +impl Default for RawRequest { + fn default() -> Self { + let now = Utc::now(); + let now = now.timestamp().unsigned_abs(); + Self { + metadata: RawRequestMetadata { + version: "0.0.1".to_string(), + created_at: now, + updated_at: now, + uses_advanced_editing: false, + draft_mode: false, + nodes: RawRequestNodes {}, + }, + mime_type: "application/run+json".to_string(), + } + } +} + +#[derive(Serialize)] +pub struct RawResponse { +} +