UploadsClient

Struct UploadsClient 

Source
pub struct UploadsClient<'a, T = ()> { /* private fields */ }
Expand description

Client for uploads API.

Implementations§

Source§

impl<T: Default + Send + Sync> UploadsClient<'_, T>

Source

pub fn builder( &self, filename: impl Into<String>, purpose: UploadPurpose, bytes: i32, mime_type: impl Into<String>, ) -> UploadBuilder

Create a new upload builder for the given file metadata.

Examples found in repository?
examples/uploads.rs (lines 139-144)
105async fn main() -> Result<(), Box<dyn std::error::Error>> {
106    println!(" OpenAI Ergonomic - Comprehensive Uploads Example\n");
107
108    // Initialize client from environment variables
109    println!(" Initializing OpenAI client...");
110    let client = match Client::from_env() {
111        Ok(c) => {
112            println!(" Client initialized successfully\n");
113            c.build()
114        }
115        Err(e) => {
116            eprintln!(" Failed to initialize client: {}", e);
117            eprintln!(" Make sure OPENAI_API_KEY is set");
118            return Ok(());
119        }
120    };
121
122    // Example 1: Create multipart upload for a large file
123    println!();
124    println!(" Example 1: Create Multipart Upload");
125    println!("\n");
126
127    // Simulate a large file
128    let filename = "large_training_dataset.jsonl";
129    let file_size_mb = 750; // 750 MB
130    let file_size_bytes = file_size_mb * 1024 * 1024;
131    let mime_type = "application/jsonl";
132
133    println!("Creating multipart upload...");
134    println!("  Filename: {}", filename);
135    println!("  Size: {} MB ({} bytes)", file_size_mb, file_size_bytes);
136    println!("  Purpose: fine-tune");
137    println!("  MIME Type: {}", mime_type);
138
139    let builder = client.uploads().builder(
140        filename,
141        UploadPurpose::FineTune,
142        file_size_bytes,
143        mime_type,
144    );
145
146    println!("\n Note: This would create a real multipart upload session.");
147    println!("   Commented out to avoid accidental API calls.\n");
148
149    // Uncomment to actually create upload:
150    // match client.uploads().create(builder).await {
151    //     Ok(upload) => {
152    //         println!(" Upload session created successfully!");
153    //         println!("  Upload ID: {}", upload.id);
154    //         println!("  Status: {}", upload.status);
155    //         println!("  Expires At: {}", upload.expires_at);
156    //     }
157    //     Err(e) => {
158    //         eprintln!(" Failed to create upload: {}", e);
159    //     }
160    // }
161
162    // Simulate upload creation for demonstration
163    let demo_upload = UploadInfo::new(
164        "upload-demo123",
165        filename,
166        file_size_bytes,
167        "fine-tune",
168        "pending",
169    );
170    println!(" Demo Upload Created:");
171    demo_upload.display();
172
173    // Example 2: Upload file parts
174    println!("\n");
175    println!(" Example 2: Upload File Parts");
176    println!("\n");
177
178    let upload_id = "upload-demo123";
179    let part_size_mb = 64; // Upload in 64 MB chunks
180    let total_parts = (file_size_mb + part_size_mb - 1) / part_size_mb; // Ceiling division
181
182    println!(
183        "Uploading {} parts ({} MB each)...\n",
184        total_parts, part_size_mb
185    );
186
187    for part_num in 1..=total_parts {
188        let progress_percent = (part_num as f64 / total_parts as f64) * 100.0;
189
190        println!(
191            " Uploading part {}/{} ({:.1}% complete)",
192            part_num, total_parts, progress_percent
193        );
194
195        // In a real implementation, you would:
196        // 1. Read the file chunk from disk
197        // 2. Upload it to the part URL provided by OpenAI
198        // 3. Track the part ID for completion
199
200        // Uncomment to actually upload parts:
201        // let part_data = read_file_chunk(filename, part_num, part_size_mb)?;
202        // match upload_part(upload_id, part_num, &part_data).await {
203        //     Ok(part_id) => {
204        //         println!("   Part {} uploaded (ID: {})", part_num, part_id);
205        //     }
206        //     Err(e) => {
207        //         eprintln!("   Failed to upload part {}: {}", part_num, e);
208        //         break;
209        //     }
210        // }
211    }
212
213    println!("\n All {} parts uploaded successfully", total_parts);
214
215    // Example 3: Complete the upload
216    println!("\n");
217    println!(" Example 3: Complete Upload");
218    println!("\n");
219
220    println!("Completing upload: {}\n", upload_id);
221
222    // Uncomment to actually complete upload:
223    // match complete_upload(upload_id, part_ids).await {
224    //     Ok(file) => {
225    //         println!(" Upload completed successfully!");
226    //         println!("  File ID: {}", file.id);
227    //         println!("  Filename: {}", file.filename);
228    //         println!("  Status: ready");
229    //         println!("  Purpose: {}", file.purpose);
230    //     }
231    //     Err(e) => {
232    //         eprintln!(" Failed to complete upload: {}", e);
233    //     }
234    // }
235
236    println!(" Demo: Would finalize the upload and create a file object");
237    println!("  File ID: file-abc123");
238    println!("  Filename: {}", filename);
239    println!("  Status: ready");
240
241    // Example 4: Upload smaller file (alternative approach)
242    println!("\n");
243    println!(" Example 4: Upload Smaller File");
244    println!("\n");
245
246    let small_filename = "training_data.jsonl";
247    let small_size_mb = 10;
248    let small_size_bytes = small_size_mb * 1024 * 1024;
249
250    println!("Creating upload for smaller file...");
251    println!("  Filename: {}", small_filename);
252    println!("  Size: {} MB", small_size_mb);
253    println!("  Purpose: assistants");
254
255    let small_builder = client.uploads().builder(
256        small_filename,
257        UploadPurpose::Assistants,
258        small_size_bytes,
259        "application/jsonl",
260    );
261
262    println!("\n Note: For files < 512 MB, consider using the regular Files API");
263    println!("   The Uploads API is optimized for large files.");
264
265    // Example 5: Error handling and retry
266    println!("\n");
267    println!(" Example 5: Error Handling & Retry");
268    println!("\n");
269
270    println!("Demonstrating retry logic for failed part uploads...\n");
271
272    let max_retries = 3;
273    let failed_part = 5;
274
275    for retry in 1..=max_retries {
276        println!(" Attempt {} to upload part {}", retry, failed_part);
277
278        // Simulate upload attempt
279        // In a real implementation:
280        // match upload_part(upload_id, failed_part, &part_data).await {
281        //     Ok(part_id) => {
282        //         println!("   Upload succeeded");
283        //         break;
284        //     }
285        //     Err(e) => {
286        //         if retry < max_retries {
287        //             println!("    Upload failed, retrying... ({})", e);
288        //             tokio::time::sleep(Duration::from_secs(2_u64.pow(retry))).await;
289        //         } else {
290        //             eprintln!("   Upload failed after {} attempts: {}", max_retries, e);
291        //         }
292        //     }
293        // }
294    }
295
296    println!("\n Tip: Implement exponential backoff for retry logic");
297
298    // Example 6: Upload progress tracking
299    println!("\n");
300    println!(" Example 6: Progress Tracking");
301    println!("\n");
302
303    struct UploadProgress {
304        total_bytes: i32,
305        uploaded_bytes: i32,
306        total_parts: i32,
307        uploaded_parts: i32,
308    }
309
310    impl UploadProgress {
311        fn percentage(&self) -> f64 {
312            (self.uploaded_bytes as f64 / self.total_bytes as f64) * 100.0
313        }
314
315        fn eta_seconds(&self, bytes_per_second: f64) -> i32 {
316            let remaining_bytes = self.total_bytes - self.uploaded_bytes;
317            (remaining_bytes as f64 / bytes_per_second) as i32
318        }
319
320        fn display(&self, bytes_per_second: f64) {
321            let progress_bar_width = 40;
322            let filled = ((self.percentage() / 100.0) * progress_bar_width as f64) as usize;
323            let empty = progress_bar_width - filled;
324
325            print!("  [");
326            print!("{}", "".repeat(filled));
327            print!("{}", "".repeat(empty));
328            print!("] ");
329
330            println!(
331                "{:.1}% ({}/{} parts, {} MB/s, ETA: {}s)",
332                self.percentage(),
333                self.uploaded_parts,
334                self.total_parts,
335                bytes_per_second / (1024.0 * 1024.0),
336                self.eta_seconds(bytes_per_second)
337            );
338        }
339    }
340
341    let progress = UploadProgress {
342        total_bytes: file_size_bytes,
343        uploaded_bytes: (file_size_bytes as f64 * 0.65) as i32,
344        total_parts,
345        uploaded_parts: (total_parts as f64 * 0.65) as i32,
346    };
347
348    println!("Current upload progress:");
349    progress.display(10.0 * 1024.0 * 1024.0); // 10 MB/s
350
351    // Summary
352    println!("\n");
353    println!(" Summary");
354    println!("\n");
355
356    println!(" Uploads API examples completed!");
357    println!("\n Key Takeaways:");
358    println!("  • Uploads API is designed for large files (>512 MB)");
359    println!("  • Files are uploaded in parts for reliability");
360    println!("  • Each part can be retried independently");
361    println!("  • Progress can be tracked during upload");
362    println!("  • Upload must be completed after all parts are uploaded");
363
364    println!("\n Best Practices:");
365    println!("  1. Use appropriate part sizes (typically 64 MB)");
366    println!("  2. Implement retry logic with exponential backoff");
367    println!("  3. Track progress and provide user feedback");
368    println!("  4. Handle upload cancellation gracefully");
369    println!("  5. Verify file integrity after upload");
370
371    println!("\n When to Use:");
372    println!("  • Large training datasets for fine-tuning");
373    println!("  • Big files for assistants (>512 MB)");
374    println!("  • Batch processing input files");
375    println!("  • Any file where reliability is critical");
376
377    println!("\n Example completed successfully!");
378
379    Ok(())
380}
Source

pub async fn create(&self, builder: UploadBuilder) -> Result<Upload>

Create an upload session.

Trait Implementations§

Source§

impl<'a, T: Clone> Clone for UploadsClient<'a, T>

Source§

fn clone(&self) -> UploadsClient<'a, T>

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<'a, T: Debug> Debug for UploadsClient<'a, T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'a, T: Copy> Copy for UploadsClient<'a, T>

Auto Trait Implementations§

§

impl<'a, T> Freeze for UploadsClient<'a, T>

§

impl<'a, T = ()> !RefUnwindSafe for UploadsClient<'a, T>

§

impl<'a, T> Send for UploadsClient<'a, T>

§

impl<'a, T> Sync for UploadsClient<'a, T>

§

impl<'a, T> Unpin for UploadsClient<'a, T>

§

impl<'a, T = ()> !UnwindSafe for UploadsClient<'a, T>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FutureExt for T

Source§

fn with_context(self, otel_cx: Context) -> WithContext<Self>

Attaches the provided Context to this type, returning a WithContext wrapper. Read more
Source§

fn with_current_context(self) -> WithContext<Self>

Attaches the current Context to this type, returning a WithContext wrapper. Read more
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<T> ErasedDestructor for T
where T: 'static,