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