mod private
{
use crate::
{
client ::Client,
environment ::{ OpenaiEnvironment, EnvironmentInterface },
error ::{ OpenAIError, Result, map_deserialization_error },
diagnostics ::{ DiagnosticsCollector, RequestMetrics, ResponseMetrics, ErrorMetrics },
};
use reqwest::Method;
use serde::{ de::DeserializeOwned, Serialize };
use std::{ sync::Arc, time::Instant };
impl< E > Client< E >
where
E : OpenaiEnvironment + EnvironmentInterface + Send + Sync + 'static,
{
#[ inline ]
pub fn get_diagnostics( &self ) -> Option< Arc< DiagnosticsCollector > >
{
self.diagnostics.clone()
}
#[ inline ]
pub fn list_registered_tools( &self ) -> Vec< &str >
{
Vec::new()
}
#[ inline ]
pub(in crate) async fn get_with_query< Q, O >( &self, path : &str, query : &Q ) -> Result< O >
where
Q : Serialize + ?Sized + Sync,
O : DeserializeOwned,
{
let url = self.environment.join_base_url( path )?;
let http_client = &self.http_client;
let response = self.execute_request_with_retry( || {
http_client.request( Method::GET, url.clone() ).query( query ).send()
}).await?;
let bytes = response.bytes().await?.to_vec(); let result = serde_json::from_slice( &bytes )
.map_err( | error | map_deserialization_error( &error ) )?;
Ok( result )
}
#[ inline ]
pub(in crate) async fn get< O >( &self, path : &str ) -> Result< O >
where
O : DeserializeOwned,
{
let url = self.environment.join_base_url( path )?;
let http_client = &self.http_client;
let response = self.execute_request_with_retry( || {
http_client.request( Method::GET, url.clone() ).send()
}).await?;
let bytes = response.bytes().await?.to_vec(); let result = serde_json::from_slice( &bytes )
.map_err( |e| { let body = String::from_utf8_lossy(&bytes); OpenAIError::Internal( format!( "Failed to parse JSON response : {e}. Response body : {body}" ) ) } )?;
Ok( result )
}
#[ inline ]
pub(in crate) async fn post< I, O >( &self, path : &str, body : &I ) -> Result< O >
where
I : Serialize + Sync,
O : DeserializeOwned,
{
let url = self.environment.join_base_url( path )?;
let http_client = &self.http_client;
let start_time = Instant::now();
if let Some( diagnostics ) = &self.diagnostics
{
let request_body_size = serde_json::to_vec( body ).map( |v| v.len() ).unwrap_or( 0 );
let request_metrics = RequestMetrics
{
timestamp : start_time,
method : "POST".to_string(),
endpoint : path.to_string(),
headers : if diagnostics.config.collection.request_headers
{
vec![ ( "Content-Type".to_string(), "application/json".to_string() ) ]
}
else
{
vec![]
},
body_size : request_body_size,
user_agent : "api_openai/0.2.0".to_string(),
};
diagnostics.record_request( &request_metrics );
}
let response = self.execute_request_with_retry( || {
http_client.request( Method::POST, url.clone() ).json( body ).send()
}).await;
match response
{
Ok( response ) =>
{
let status_code = response.status().as_u16();
let response_time = start_time.elapsed();
let bytes = response.bytes().await?.to_vec();
if let Some( diagnostics ) = &self.diagnostics
{
let response_metrics = ResponseMetrics
{
timestamp : Instant::now(),
status_code,
headers : if diagnostics.config.collection.response_headers
{
vec![ ( "Content-Type".to_string(), "application/json".to_string() ) ]
}
else
{
vec![]
},
body_size : bytes.len(),
response_time,
tokens_used : None, };
diagnostics.record_response( &response_metrics );
}
let result = serde_json::from_slice( &bytes )
.map_err( |e| { let body = String::from_utf8_lossy(&bytes); OpenAIError::Internal( format!( "Failed to parse JSON response : {e}. Response body : {body}" ) ) } )?;
Ok( result )
},
Err( error ) =>
{
if let Some( diagnostics ) = &self.diagnostics
{
let error_metrics = ErrorMetrics
{
timestamp : Instant::now(),
error_type : "RequestError".to_string(),
error_code : None,
error_message : error.to_string(),
retry_count : 0, final_failure : true,
};
diagnostics.record_error( &error_metrics );
}
Err( error )?
}
}
}
#[ inline ]
pub(in crate) async fn delete< O >( &self, path : &str ) -> Result< O >
where
O : DeserializeOwned,
{
let url = self.environment.join_base_url( path )?;
let http_client = &self.http_client;
let response = self.execute_request_with_retry( || {
http_client.request( Method::DELETE, url.clone() ).send()
}).await?;
let bytes = response.bytes().await?.to_vec(); let result = serde_json::from_slice( &bytes )
.map_err( |e| { let body = String::from_utf8_lossy(&bytes); OpenAIError::Internal( format!( "Failed to parse JSON response : {e}. Response body : {body}" ) ) } )?;
Ok( result )
}
#[ inline ]
pub(in crate) async fn patch< I, O >( &self, path : &str, body : &I ) -> Result< O >
where
I : Serialize + Sync,
O : DeserializeOwned,
{
let url = self.environment.join_base_url( path )?;
let http_client = &self.http_client;
let response = self.execute_request_with_retry( || {
http_client.request( Method::PATCH, url.clone() ).json( body ).send()
}).await?;
let bytes = response.bytes().await?.to_vec();
let result = serde_json::from_slice( &bytes )?;
Ok( result )
}
#[ inline ]
pub(in crate) async fn post_no_body< O >( &self, path : &str ) -> Result< O >
where
O : DeserializeOwned,
{
let url = self.environment.join_base_url( path )?;
let http_client = &self.http_client;
let response = self.execute_request_with_retry( || {
http_client.request( Method::POST, url.clone() ).send()
}).await?;
let bytes = response.bytes().await?.to_vec();
let result = serde_json::from_slice( &bytes )?;
Ok( result )
}
}
}