openai-interface 0.13.0

A low-level Rust interface for the OpenAI API
Documentation
//! File upload functionality for OpenAI-compatible APIs
//!
//! This module provides functionality for uploading files to OpenAI-compatible APIs.
//! Files can be uploaded for various purposes such as fine-tuning, batch processing,
//! assistants, and more.
//!
//! # Overview
//!
//! The `create` module contains:
//! - [`request`]: File upload request types and functionality
//! - Support for multipart/form-data file uploads
//! - Comprehensive error handling for file operations
//!
//! The response object is in [`super`]
//!
//! # Examples
//!
//! ## Basic File Upload
//!
//! This example demonstrates how to upload a file for batch processing:
//!
//! ```rust,no_run
//! use std::path::PathBuf;
//! use openai_interface::files::create::request::{CreateFileRequest, FilePurpose};
//! use openai_interface::files::FileObject;
//! use openai_interface::rest::{default_client, post::PostNoStream, RequestOptions};
//!
//! const MODELSCOPE_URL: &str = "https://dashscope.aliyuncs.com/compatible-mode/v1";
//!
//! #[tokio::main]
//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
//!     // Needs the `ferritls` cargo feature; drop this line if you install
//!     // your own rustls crypto provider (see `openai_interface::rest`).
//!     # #[cfg(feature = "ferritls")]
//!     openai_interface::rest::install_crypto_provider().ok();
//!
//!     let file_path = PathBuf::from("src/files/create/file-test.txt");
//!     let create_file_request = CreateFileRequest {
//!         file: file_path,
//!         purpose: FilePurpose::Batch,
//!         ..Default::default()
//!     };
//!
//!     let response: FileObject = create_file_request
//!         .get_response(&default_client(), MODELSCOPE_URL, &RequestOptions::bearer("YOUR_API_KEY"))
//!         .await?;
//!
//!     println!("Uploaded file ID: {}", response.id);
//!     println!("File size: {} bytes", response.bytes);
//!     println!("Filename: {}", response.filename);
//!     Ok(())
//! }
//! ```
//!
//! ## File Upload with Custom Purpose
//!
//! This example shows how to upload a file with a custom purpose:
//!
//! ```rust,no_run
//! use std::path::PathBuf;
//! use openai_interface::files::create::request::{CreateFileRequest, FilePurpose};
//! use openai_interface::files::FileObject;
//! use openai_interface::rest::{default_client, post::PostNoStream, RequestOptions};
//!
//! const MODELSCOPE_URL: &str = "https://dashscope.aliyuncs.com/compatible-mode/v1";
//!
//! #[tokio::main]
//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
//!     // Needs the `ferritls` cargo feature; drop this line if you install
//!     // your own rustls crypto provider (see `openai_interface::rest`).
//!     # #[cfg(feature = "ferritls")]
//!     openai_interface::rest::install_crypto_provider().ok();
//!
//!     let file_path = PathBuf::from("src/files/create/file-test.txt");
//!     let create_file_request = CreateFileRequest {
//!         file: file_path,
//!         purpose: FilePurpose::Other("file-extract".to_string()),
//!         ..Default::default()
//!     };
//!
//!     let response: FileObject = create_file_request
//!         .get_response(&default_client(), MODELSCOPE_URL, &RequestOptions::bearer("YOUR_API_KEY"))
//!         .await?;
//!
//!     println!("Uploaded file with custom purpose: {}", response.id);
//!     Ok(())
//! }
//! ```

pub mod request;

#[cfg(test)]
mod tests {
    use std::path::PathBuf;

    use crate::rest::{RequestOptions, default_client, post::PostNoStream};

    use super::*;

    const TEST_FILE_PATH: &str = "src/files/create/file-test.txt";
    const MODELSCOPE_URL: &str = "https://dashscope.aliyuncs.com/compatible-mode/v1";

    fn modelstudio_key() -> Option<String> {
        std::env::var("QWEN_API_KEY")
            .ok()
            .map(|key| key.trim().to_string())
            .filter(|key| !key.is_empty())
    }

    #[tokio::test]
    async fn test_file_create() -> Result<(), anyhow::Error> {
        let Some(api_key) = modelstudio_key() else {
            println!("Skipping: set QWEN_API_KEY to run this test");
            return Ok(());
        };

        let file_path = PathBuf::from(TEST_FILE_PATH);
        let create_file_request = request::CreateFileRequest {
            file: file_path,
            purpose: request::FilePurpose::Other("file-extract".to_string()),
            ..Default::default()
        };

        let response = create_file_request
            .get_response(
                &default_client(),
                MODELSCOPE_URL,
                &RequestOptions::bearer(&api_key),
            )
            .await?;

        println!("Uploaded file ID: {}", response.id);
        println!("File size: {} bytes", response.bytes);
        println!("Filename: {}", response.filename);

        Ok(())
    }
}