Skip to main content

openai_compat/types/
batches.rs

1//! Batch types, mirroring `openai-python/src/openai/types/batch.py` and
2//! `batch_create_params.py` / `batch_list_params.py`.
3
4use std::collections::HashMap;
5
6use serde::{Deserialize, Serialize};
7
8use crate::pagination::HasId;
9
10/// The processing status of a [`Batch`].
11///
12/// Unrecognized values deserialize to [`BatchStatus::Unknown`] so newer
13/// server-side statuses do not break older clients.
14#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
15#[serde(rename_all = "snake_case")]
16pub enum BatchStatus {
17    Validating,
18    Failed,
19    InProgress,
20    Finalizing,
21    Completed,
22    Expired,
23    Cancelling,
24    Cancelled,
25    /// A status not recognized by this client version.
26    #[serde(other)]
27    Unknown,
28}
29
30/// A single error entry from a batch's `errors` list.
31#[derive(Debug, Clone, Deserialize)]
32#[non_exhaustive]
33pub struct BatchError {
34    #[serde(default)]
35    pub code: Option<String>,
36    #[serde(default)]
37    pub line: Option<i64>,
38    #[serde(default)]
39    pub message: Option<String>,
40    #[serde(default)]
41    pub param: Option<String>,
42}
43
44/// The `errors` object on a [`Batch`].
45#[derive(Debug, Clone, Deserialize)]
46#[non_exhaustive]
47pub struct BatchErrors {
48    #[serde(default)]
49    pub data: Vec<BatchError>,
50    #[serde(default)]
51    pub object: Option<String>,
52}
53
54/// Counts of the requests within a batch, split by outcome.
55#[derive(Debug, Clone, Deserialize)]
56#[non_exhaustive]
57pub struct BatchRequestCounts {
58    #[serde(default)]
59    pub completed: i64,
60    #[serde(default)]
61    pub failed: i64,
62    #[serde(default)]
63    pub total: i64,
64}
65
66/// A batch job over an uploaded input file.
67#[derive(Debug, Clone, Deserialize)]
68#[non_exhaustive]
69pub struct Batch {
70    pub id: String,
71    #[serde(default)]
72    pub completion_window: String,
73    #[serde(default)]
74    pub created_at: i64,
75    #[serde(default)]
76    pub endpoint: String,
77    #[serde(default)]
78    pub input_file_id: String,
79    #[serde(default)]
80    pub object: String,
81    pub status: BatchStatus,
82    #[serde(default)]
83    pub cancelled_at: Option<i64>,
84    #[serde(default)]
85    pub cancelling_at: Option<i64>,
86    #[serde(default)]
87    pub completed_at: Option<i64>,
88    #[serde(default)]
89    pub expired_at: Option<i64>,
90    #[serde(default)]
91    pub expires_at: Option<i64>,
92    #[serde(default)]
93    pub failed_at: Option<i64>,
94    #[serde(default)]
95    pub finalizing_at: Option<i64>,
96    #[serde(default)]
97    pub in_progress_at: Option<i64>,
98    #[serde(default)]
99    pub error_file_id: Option<String>,
100    #[serde(default)]
101    pub output_file_id: Option<String>,
102    #[serde(default)]
103    pub errors: Option<BatchErrors>,
104    #[serde(default)]
105    pub metadata: Option<HashMap<String, String>>,
106    #[serde(default)]
107    pub model: Option<String>,
108    #[serde(default)]
109    pub request_counts: Option<BatchRequestCounts>,
110    #[serde(default)]
111    pub usage: Option<serde_json::Value>,
112}
113
114impl HasId for Batch {
115    fn id(&self) -> Option<&str> {
116        Some(&self.id)
117    }
118}
119
120/// Parameters for `POST /batches`.
121#[derive(Debug, Clone, Serialize)]
122pub struct BatchCreateParams {
123    /// The time window for completion. Currently only `"24h"` is supported.
124    pub completion_window: String,
125    /// The endpoint the batched requests target, e.g. `/v1/chat/completions`.
126    pub endpoint: String,
127    /// The id of an uploaded file containing the batched requests (JSONL).
128    pub input_file_id: String,
129    #[serde(skip_serializing_if = "Option::is_none")]
130    pub metadata: Option<HashMap<String, String>>,
131    /// Expiration policy for the batch output/error files.
132    #[serde(skip_serializing_if = "Option::is_none")]
133    pub output_expires_after: Option<crate::types::common::ExpiresAfter>,
134}
135
136impl BatchCreateParams {
137    pub fn new(
138        input_file_id: impl Into<String>,
139        endpoint: impl Into<String>,
140        completion_window: impl Into<String>,
141    ) -> Self {
142        Self {
143            completion_window: completion_window.into(),
144            endpoint: endpoint.into(),
145            input_file_id: input_file_id.into(),
146            metadata: None,
147            output_expires_after: None,
148        }
149    }
150
151    pub fn metadata(mut self, metadata: HashMap<String, String>) -> Self {
152        self.metadata = Some(metadata);
153        self
154    }
155}
156
157/// Query parameters for `GET /batches`.
158#[derive(Debug, Clone, Default)]
159pub struct BatchListParams {
160    /// A cursor: return items after this batch id.
161    pub after: Option<String>,
162    /// Page size, 1-100 (server default 20).
163    pub limit: Option<u32>,
164}
165
166impl BatchListParams {
167    pub fn after(mut self, after: impl Into<String>) -> Self {
168        self.after = Some(after.into());
169        self
170    }
171
172    pub fn limit(mut self, limit: u32) -> Self {
173        self.limit = Some(limit);
174        self
175    }
176
177    /// Build the `(key, value)` query pairs for the list request.
178    pub(crate) fn to_query(&self) -> Vec<(String, String)> {
179        crate::pagination::cursor_query(self.after.as_deref(), None, self.limit, None)
180    }
181}