Merge pull request #172 from dongri/fix-batch-object

Fix batch object
This commit is contained in:
Dongri Jin
2025-07-10 16:11:48 +09:00
committed by GitHub
6 changed files with 77 additions and 70 deletions

View File

@ -44,7 +44,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
let result = client.retrieve_file_content(file_id).await?; let result = client.retrieve_file_content(file_id).await?;
let s = match str::from_utf8(&result) { let s = match str::from_utf8(&result) {
Ok(v) => v.to_string(), Ok(v) => v.to_string(),
Err(e) => panic!("Invalid UTF-8 sequence: {}", e), Err(e) => panic!("Invalid UTF-8 sequence: {e}"),
}; };
let json_value: Value = from_str(&s)?; let json_value: Value = from_str(&s)?;
let result_json = to_string_pretty(&json_value)?; let result_json = to_string_pretty(&json_value)?;

View File

@ -86,7 +86,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
let coin = c.coin; let coin = c.coin;
if name == "get_coin_price" { if name == "get_coin_price" {
let price = get_coin_price(&coin); let price = get_coin_price(&coin);
println!("{} price: {}", coin, price); println!("{coin} price: {price}");
} }
} }
} }

View File

@ -79,9 +79,9 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
let arguments = function_call.arguments.clone().unwrap(); let arguments = function_call.arguments.clone().unwrap();
let c: Currency = serde_json::from_str(&arguments)?; let c: Currency = serde_json::from_str(&arguments)?;
let coin = c.coin; let coin = c.coin;
println!("coin: {}", coin); println!("coin: {coin}");
let price = get_coin_price(&coin); let price = get_coin_price(&coin);
println!("price: {}", price); println!("price: {price}");
let req = ChatCompletionRequest::new( let req = ChatCompletionRequest::new(
GPT4_O.to_string(), GPT4_O.to_string(),
@ -99,7 +99,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
role: chat_completion::MessageRole::function, role: chat_completion::MessageRole::function,
content: chat_completion::Content::Text({ content: chat_completion::Content::Text({
let price = get_coin_price(&coin); let price = get_coin_price(&coin);
format!("{{\"price\": {}}}", price) format!("{{\"price\": {price}}}")
}), }),
name: Some(String::from("get_coin_price")), name: Some(String::from("get_coin_price")),
tool_calls: None, tool_calls: None,

View File

@ -163,7 +163,7 @@ impl OpenAIClient {
let mut request = client.request(method, url); let mut request = client.request(method, url);
if let Some(api_key) = &self.api_key { if let Some(api_key) = &self.api_key {
request = request.header("Authorization", format!("Bearer {}", api_key)); request = request.header("Authorization", format!("Bearer {api_key}"));
} }
if let Some(organization) = &self.organization { if let Some(organization) = &self.organization {
@ -244,7 +244,7 @@ impl OpenAIClient {
Ok(parsed) Ok(parsed)
} }
Err(e) => Err(APIError::CustomError { Err(e) => Err(APIError::CustomError {
message: format!("Failed to parse JSON: {} / response {}", e, text), message: format!("Failed to parse JSON: {e} / response {text}"),
}), }),
} }
} else { } else {
@ -253,7 +253,7 @@ impl OpenAIClient {
.await .await
.unwrap_or_else(|_| "Unknown error".to_string()); .unwrap_or_else(|_| "Unknown error".to_string());
Err(APIError::CustomError { Err(APIError::CustomError {
message: format!("{}: {}", status, error_message), message: format!("{status}: {error_message}"),
}) })
} }
} }
@ -320,11 +320,11 @@ impl OpenAIClient {
&mut self, &mut self,
file_id: String, file_id: String,
) -> Result<FileRetrieveResponse, APIError> { ) -> Result<FileRetrieveResponse, APIError> {
self.get(&format!("files/{}", file_id)).await self.get(&format!("files/{file_id}")).await
} }
pub async fn retrieve_file_content(&self, file_id: String) -> Result<Bytes, APIError> { pub async fn retrieve_file_content(&self, file_id: String) -> Result<Bytes, APIError> {
self.get_raw(&format!("files/{}/content", file_id)).await self.get_raw(&format!("files/{file_id}/content")).await
} }
pub async fn chat_completion( pub async fn chat_completion(
@ -495,7 +495,7 @@ impl OpenAIClient {
&mut self, &mut self,
assistant_id: String, assistant_id: String,
) -> Result<AssistantObject, APIError> { ) -> Result<AssistantObject, APIError> {
self.get(&format!("assistants/{}", assistant_id)).await self.get(&format!("assistants/{assistant_id}")).await
} }
pub async fn modify_assistant( pub async fn modify_assistant(
@ -503,15 +503,14 @@ impl OpenAIClient {
assistant_id: String, assistant_id: String,
req: AssistantRequest, req: AssistantRequest,
) -> Result<AssistantObject, APIError> { ) -> Result<AssistantObject, APIError> {
self.post(&format!("assistants/{}", assistant_id), &req) self.post(&format!("assistants/{assistant_id}"), &req).await
.await
} }
pub async fn delete_assistant( pub async fn delete_assistant(
&mut self, &mut self,
assistant_id: String, assistant_id: String,
) -> Result<common::DeletionStatus, APIError> { ) -> Result<common::DeletionStatus, APIError> {
self.delete(&format!("assistants/{}", assistant_id)).await self.delete(&format!("assistants/{assistant_id}")).await
} }
pub async fn list_assistant( pub async fn list_assistant(
@ -530,7 +529,7 @@ impl OpenAIClient {
assistant_id: String, assistant_id: String,
req: AssistantFileRequest, req: AssistantFileRequest,
) -> Result<AssistantFileObject, APIError> { ) -> Result<AssistantFileObject, APIError> {
self.post(&format!("assistants/{}/files", assistant_id), &req) self.post(&format!("assistants/{assistant_id}/files"), &req)
.await .await
} }
@ -539,7 +538,7 @@ impl OpenAIClient {
assistant_id: String, assistant_id: String,
file_id: String, file_id: String,
) -> Result<AssistantFileObject, APIError> { ) -> Result<AssistantFileObject, APIError> {
self.get(&format!("assistants/{}/files/{}", assistant_id, file_id)) self.get(&format!("assistants/{assistant_id}/files/{file_id}"))
.await .await
} }
@ -548,7 +547,7 @@ impl OpenAIClient {
assistant_id: String, assistant_id: String,
file_id: String, file_id: String,
) -> Result<common::DeletionStatus, APIError> { ) -> Result<common::DeletionStatus, APIError> {
self.delete(&format!("assistants/{}/files/{}", assistant_id, file_id)) self.delete(&format!("assistants/{assistant_id}/files/{file_id}"))
.await .await
} }
@ -565,7 +564,7 @@ impl OpenAIClient {
order, order,
after, after,
before, before,
format!("assistants/{}/files", assistant_id), format!("assistants/{assistant_id}/files"),
); );
self.get(&url).await self.get(&url).await
} }
@ -578,7 +577,7 @@ impl OpenAIClient {
} }
pub async fn retrieve_thread(&mut self, thread_id: String) -> Result<ThreadObject, APIError> { pub async fn retrieve_thread(&mut self, thread_id: String) -> Result<ThreadObject, APIError> {
self.get(&format!("threads/{}", thread_id)).await self.get(&format!("threads/{thread_id}")).await
} }
pub async fn modify_thread( pub async fn modify_thread(
@ -586,14 +585,14 @@ impl OpenAIClient {
thread_id: String, thread_id: String,
req: ModifyThreadRequest, req: ModifyThreadRequest,
) -> Result<ThreadObject, APIError> { ) -> Result<ThreadObject, APIError> {
self.post(&format!("threads/{}", thread_id), &req).await self.post(&format!("threads/{thread_id}"), &req).await
} }
pub async fn delete_thread( pub async fn delete_thread(
&mut self, &mut self,
thread_id: String, thread_id: String,
) -> Result<common::DeletionStatus, APIError> { ) -> Result<common::DeletionStatus, APIError> {
self.delete(&format!("threads/{}", thread_id)).await self.delete(&format!("threads/{thread_id}")).await
} }
pub async fn create_message( pub async fn create_message(
@ -601,7 +600,7 @@ impl OpenAIClient {
thread_id: String, thread_id: String,
req: CreateMessageRequest, req: CreateMessageRequest,
) -> Result<MessageObject, APIError> { ) -> Result<MessageObject, APIError> {
self.post(&format!("threads/{}/messages", thread_id), &req) self.post(&format!("threads/{thread_id}/messages"), &req)
.await .await
} }
@ -610,7 +609,7 @@ impl OpenAIClient {
thread_id: String, thread_id: String,
message_id: String, message_id: String,
) -> Result<MessageObject, APIError> { ) -> Result<MessageObject, APIError> {
self.get(&format!("threads/{}/messages/{}", thread_id, message_id)) self.get(&format!("threads/{thread_id}/messages/{message_id}"))
.await .await
} }
@ -620,15 +619,12 @@ impl OpenAIClient {
message_id: String, message_id: String,
req: ModifyMessageRequest, req: ModifyMessageRequest,
) -> Result<MessageObject, APIError> { ) -> Result<MessageObject, APIError> {
self.post( self.post(&format!("threads/{thread_id}/messages/{message_id}"), &req)
&format!("threads/{}/messages/{}", thread_id, message_id), .await
&req,
)
.await
} }
pub async fn list_messages(&mut self, thread_id: String) -> Result<ListMessage, APIError> { pub async fn list_messages(&mut self, thread_id: String) -> Result<ListMessage, APIError> {
self.get(&format!("threads/{}/messages", thread_id)).await self.get(&format!("threads/{thread_id}/messages")).await
} }
pub async fn retrieve_message_file( pub async fn retrieve_message_file(
@ -638,8 +634,7 @@ impl OpenAIClient {
file_id: String, file_id: String,
) -> Result<MessageFileObject, APIError> { ) -> Result<MessageFileObject, APIError> {
self.get(&format!( self.get(&format!(
"threads/{}/messages/{}/files/{}", "threads/{thread_id}/messages/{message_id}/files/{file_id}"
thread_id, message_id, file_id
)) ))
.await .await
} }
@ -658,7 +653,7 @@ impl OpenAIClient {
order, order,
after, after,
before, before,
format!("threads/{}/messages/{}/files", thread_id, message_id), format!("threads/{thread_id}/messages/{message_id}/files"),
); );
self.get(&url).await self.get(&url).await
} }
@ -668,8 +663,7 @@ impl OpenAIClient {
thread_id: String, thread_id: String,
req: CreateRunRequest, req: CreateRunRequest,
) -> Result<RunObject, APIError> { ) -> Result<RunObject, APIError> {
self.post(&format!("threads/{}/runs", thread_id), &req) self.post(&format!("threads/{thread_id}/runs"), &req).await
.await
} }
pub async fn retrieve_run( pub async fn retrieve_run(
@ -677,7 +671,7 @@ impl OpenAIClient {
thread_id: String, thread_id: String,
run_id: String, run_id: String,
) -> Result<RunObject, APIError> { ) -> Result<RunObject, APIError> {
self.get(&format!("threads/{}/runs/{}", thread_id, run_id)) self.get(&format!("threads/{thread_id}/runs/{run_id}"))
.await .await
} }
@ -687,7 +681,7 @@ impl OpenAIClient {
run_id: String, run_id: String,
req: ModifyRunRequest, req: ModifyRunRequest,
) -> Result<RunObject, APIError> { ) -> Result<RunObject, APIError> {
self.post(&format!("threads/{}/runs/{}", thread_id, run_id), &req) self.post(&format!("threads/{thread_id}/runs/{run_id}"), &req)
.await .await
} }
@ -704,7 +698,7 @@ impl OpenAIClient {
order, order,
after, after,
before, before,
format!("threads/{}/runs", thread_id), format!("threads/{thread_id}/runs"),
); );
self.get(&url).await self.get(&url).await
} }
@ -715,7 +709,7 @@ impl OpenAIClient {
run_id: String, run_id: String,
) -> Result<RunObject, APIError> { ) -> Result<RunObject, APIError> {
self.post( self.post(
&format!("threads/{}/runs/{}/cancel", thread_id, run_id), &format!("threads/{thread_id}/runs/{run_id}/cancel"),
&ModifyRunRequest::default(), &ModifyRunRequest::default(),
) )
.await .await
@ -735,8 +729,7 @@ impl OpenAIClient {
step_id: String, step_id: String,
) -> Result<RunStepObject, APIError> { ) -> Result<RunStepObject, APIError> {
self.get(&format!( self.get(&format!(
"threads/{}/runs/{}/steps/{}", "threads/{thread_id}/runs/{run_id}/steps/{step_id}"
thread_id, run_id, step_id
)) ))
.await .await
} }
@ -755,7 +748,7 @@ impl OpenAIClient {
order, order,
after, after,
before, before,
format!("threads/{}/runs/{}/steps", thread_id, run_id), format!("threads/{thread_id}/runs/{run_id}/steps"),
); );
self.get(&url).await self.get(&url).await
} }
@ -768,12 +761,12 @@ impl OpenAIClient {
} }
pub async fn retrieve_batch(&mut self, batch_id: String) -> Result<BatchResponse, APIError> { pub async fn retrieve_batch(&mut self, batch_id: String) -> Result<BatchResponse, APIError> {
self.get(&format!("batches/{}", batch_id)).await self.get(&format!("batches/{batch_id}")).await
} }
pub async fn cancel_batch(&mut self, batch_id: String) -> Result<BatchResponse, APIError> { pub async fn cancel_batch(&mut self, batch_id: String) -> Result<BatchResponse, APIError> {
self.post( self.post(
&format!("batches/{}/cancel", batch_id), &format!("batches/{batch_id}/cancel"),
&common::EmptyRequestBody {}, &common::EmptyRequestBody {},
) )
.await .await
@ -793,14 +786,14 @@ impl OpenAIClient {
} }
pub async fn retrieve_model(&mut self, model_id: String) -> Result<ModelResponse, APIError> { pub async fn retrieve_model(&mut self, model_id: String) -> Result<ModelResponse, APIError> {
self.get(&format!("models/{}", model_id)).await self.get(&format!("models/{model_id}")).await
} }
pub async fn delete_model( pub async fn delete_model(
&mut self, &mut self,
model_id: String, model_id: String,
) -> Result<common::DeletionStatus, APIError> { ) -> Result<common::DeletionStatus, APIError> {
self.delete(&format!("models/{}", model_id)).await self.delete(&format!("models/{model_id}")).await
} }
fn build_url_with_preserved_query(&self, path: &str) -> Result<String, url::ParseError> { fn build_url_with_preserved_query(&self, path: &str) -> Result<String, url::ParseError> {
@ -829,16 +822,16 @@ impl OpenAIClient {
) -> String { ) -> String {
let mut params = vec![]; let mut params = vec![];
if let Some(limit) = limit { if let Some(limit) = limit {
params.push(format!("limit={}", limit)); params.push(format!("limit={limit}"));
} }
if let Some(order) = order { if let Some(order) = order {
params.push(format!("order={}", order)); params.push(format!("order={order}"));
} }
if let Some(after) = after { if let Some(after) = after {
params.push(format!("after={}", after)); params.push(format!("after={after}"));
} }
if let Some(before) = before { if let Some(before) = before {
params.push(format!("before={}", before)); params.push(format!("before={before}"));
} }
if !params.is_empty() { if !params.is_empty() {
url = format!("{}?{}", url, params.join("&")); url = format!("{}?{}", url, params.join("&"));
@ -866,7 +859,7 @@ impl OpenAIClient {
map.get(file_field) map.get(file_field)
.and_then(|v| v.as_str()) .and_then(|v| v.as_str())
.ok_or(APIError::CustomError { .ok_or(APIError::CustomError {
message: format!("Field '{}' not found or not a string", file_field), message: format!("Field '{file_field}' not found or not a string"),
})? })?
} else { } else {
return Err(APIError::CustomError { return Err(APIError::CustomError {

View File

@ -23,27 +23,41 @@ pub struct RequestCounts {
} }
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
pub struct BatchResponse { pub struct BatchError {
pub id: String, pub code: String,
pub line: Option<u32>,
pub message: String,
pub param: Option<String>,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct BatchErrors {
pub object: String, pub object: String,
pub endpoint: String, pub data: Vec<BatchError>,
pub errors: Option<Vec<String>>, }
pub input_file_id: String,
pub completion_window: String, #[derive(Debug, Serialize, Deserialize)]
pub status: String, pub struct BatchResponse {
pub output_file_id: Option<String>,
pub error_file_id: Option<String>,
pub created_at: u64,
pub in_progress_at: Option<u64>,
pub expires_at: Option<u64>,
pub finalizing_at: Option<u64>,
pub completed_at: Option<u64>,
pub failed_at: Option<u64>,
pub expired_at: Option<u64>,
pub cancelling_at: Option<u64>,
pub cancelled_at: Option<u64>, pub cancelled_at: Option<u64>,
pub request_counts: RequestCounts, pub cancelling_at: Option<u64>,
pub completed_at: Option<u64>,
pub completion_window: String,
pub created_at: u64,
pub endpoint: String,
pub error_file_id: Option<String>,
pub errors: Option<BatchErrors>,
pub expired_at: Option<u64>,
pub expires_at: Option<u64>,
pub failed_at: Option<u64>,
pub finalizing_at: Option<u64>,
pub id: String,
pub in_progress_at: Option<u64>,
pub input_file_id: String,
pub metadata: Option<Metadata>, pub metadata: Option<Metadata>,
pub object: String,
pub output_file_id: Option<String>,
pub request_counts: RequestCounts,
pub status: String,
} }
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]

View File

@ -11,8 +11,8 @@ pub enum APIError {
impl fmt::Display for APIError { impl fmt::Display for APIError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self { match self {
APIError::ReqwestError(err) => write!(f, "ReqwestError: {}", err), APIError::ReqwestError(err) => write!(f, "ReqwestError: {err}"),
APIError::CustomError { message } => write!(f, "APIError: {}", message), APIError::CustomError { message } => write!(f, "APIError: {message}"),
} }
} }
} }