Skip to main content

openai_interface/files/list/
mod.rs

1//! This module provides functionality for listing files from OpenAI-compatible APIs.
2//!
3//! # Examples
4//!
5//! ```rust,no_run
6//!
7//! use openai_interface::files::list::request::ListFilesRequest;
8//! use openai_interface::rest::{default_client, get::{Get, GetNoStream}};
9//!
10//! const QWEN_BASE_URL: &'static str = "https://dashscope.aliyuncs.com/compatible-mode/v1/";
11//!
12//! #[tokio::main]
13//! async fn main() -> Result<(), anyhow::Error> {
14//!    // Needs the `ferritls` cargo feature; drop this line if you install
15//!    // your own rustls crypto provider (see `openai_interface::rest`).
16//!    # #[cfg(feature = "ferritls")]
17//!    openai_interface::rest::install_crypto_provider().ok();
18//!
19//!    let request = ListFilesRequest {
20//!        purpose: Some("batch".to_string()),
21//!        limit: Some(1),
22//!        // after: Some("file_123".to_string()),
23//!        ..Default::default()
24//!    };
25//!    let response = request
26//!        .get_response(&default_client(), QWEN_BASE_URL, "YOUR_API_KEY")
27//!        .await?;
28//!
29//!    println!("Response: {:?}", response);
30//!
31//!    Ok(())
32//! }
33//! ```
34
35pub mod request;
36pub mod response;
37
38#[cfg(test)]
39mod tests {
40    use super::request::*;
41    use crate::rest::{
42        default_client,
43        get::{Get, GetNoStream},
44    };
45
46    const QWEN_BASE_URL: &str = "https://dashscope.aliyuncs.com/compatible-mode/v1/";
47
48    fn qwen_api_key() -> Option<String> {
49        std::env::var("QWEN_API_KEY")
50            .ok()
51            .map(|key| key.trim().to_string())
52            .filter(|key| !key.is_empty())
53    }
54
55    #[test]
56    fn test_build_url_no_params() {
57        let request = ListFilesRequest::default();
58        let base_url = "https://api.openai.com/v1/";
59        let url = request.build_url(base_url).expect("Failed to build url");
60        assert_eq!(url, "https://api.openai.com/v1/files");
61    }
62
63    #[test]
64    fn test_build_url_with_purpose() {
65        let request = ListFilesRequest {
66            purpose: Some("fine-tune".to_string()),
67            ..Default::default()
68        };
69        let base_url = "https://api.openai.com/v1/";
70        let url = request.build_url(base_url).expect("Failed to build url");
71        assert_eq!(url, "https://api.openai.com/v1/files?purpose=fine-tune");
72    }
73
74    #[test]
75    fn test_build_url_with_limit() {
76        let request = ListFilesRequest {
77            limit: Some(100),
78            ..Default::default()
79        };
80        let base_url = "https://api.openai.com/v1/";
81        let url = request.build_url(base_url).expect("Failed to build url");
82        assert_eq!(url, "https://api.openai.com/v1/files?limit=100");
83    }
84
85    #[test]
86    fn test_build_url_with_after() {
87        let request = ListFilesRequest {
88            after: Some("file_123".to_string()),
89            ..Default::default()
90        };
91        let base_url = "https://api.openai.com/v1/";
92        let url = request.build_url(base_url).expect("Failed to build url");
93        assert_eq!(url, "https://api.openai.com/v1/files?after=file_123");
94    }
95
96    #[test]
97    fn test_build_url_with_all_params() {
98        let request = ListFilesRequest {
99            purpose: Some("assistants".to_string()),
100            limit: Some(50),
101            after: Some("file_abc".to_string()),
102            order: Some(ListOrder::Asc),
103        };
104        let base_url = "https://api.openai.com/v1/";
105        let url = request.build_url(base_url).expect("Failed to build url");
106        // Note: URL parameters are ordered alphabetically by the url crate
107        assert!(url.contains("after=file_abc"));
108        assert!(url.contains("limit=50"));
109        assert!(url.contains("order=asc"));
110        assert!(url.contains("purpose=assistants"));
111        assert!(url.starts_with("https://api.openai.com/v1/files?"));
112    }
113
114    #[test]
115    fn test_build_url_encoding() {
116        let request = ListFilesRequest {
117            purpose: Some("fine tune".to_string()), // Space should be encoded
118            ..Default::default()
119        };
120        let base_url = "https://api.openai.com/v1/";
121        let url = request.build_url(base_url).expect("Failed to build url");
122        assert_eq!(url, "https://api.openai.com/v1/files?purpose=fine+tune");
123    }
124
125    #[tokio::test]
126    async fn test_query_qwen_no_params() -> Result<(), anyhow::Error> {
127        let Some(api_key) = qwen_api_key() else {
128            println!("Skipping: set QWEN_API_KEY to run this test");
129            return Ok(());
130        };
131
132        let request = ListFilesRequest::default();
133        let response = request
134            .get_response(&default_client(), QWEN_BASE_URL, &api_key)
135            .await?;
136
137        println!("Response: {:?}", response);
138
139        Ok(())
140    }
141
142    #[tokio::test]
143    async fn test_query_qwen_with_params() -> Result<(), anyhow::Error> {
144        let Some(api_key) = qwen_api_key() else {
145            println!("Skipping: set QWEN_API_KEY to run this test");
146            return Ok(());
147        };
148
149        let request = ListFilesRequest {
150            purpose: Some("batch".to_string()),
151            limit: Some(1),
152            // after: Some("file_123".to_string()),
153            ..Default::default()
154        };
155        let response = request
156            .get_response(&default_client(), QWEN_BASE_URL, &api_key)
157            .await?;
158
159        println!("Response: {:?}", response);
160
161        Ok(())
162    }
163}