openai_interface/files/
retrieve.rs1pub mod request {
2 use url::Url;
3
4 use crate::{
5 errors::OapiError,
6 rest::get::{Get, GetNoStream},
7 };
8
9 pub struct RetrieveRequest<'a> {
10 pub file_id: &'a str,
11 }
12
13 impl<'a> Get for RetrieveRequest<'a> {
14 fn build_url(&self, base_url: &str) -> Result<String, OapiError> {
16 let url = Url::parse(base_url)
17 .map_err(|e| OapiError::UrlError(e))?
18 .join("files/")
19 .unwrap()
20 .join(self.file_id)
21 .map_err(|e| OapiError::UrlError(e))?;
22
23 Ok(url.to_string())
24 }
25 }
26
27 impl<'a> GetNoStream for RetrieveRequest<'a> {
28 type Response = crate::files::FileObject;
29 }
30}
31
32#[cfg(test)]
33mod tests {
34 use std::sync::LazyLock;
35
36 use super::*;
37 use crate::{
38 files::{list::request::ListFilesRequest, retrieve::request::RetrieveRequest},
39 rest::get::{Get, GetNoStream},
40 };
41 use anyhow::bail;
42 use futures_util::future::{self};
43
44 const MODELSCOPE_BASE_URL: &str = "https://dashscope.aliyuncs.com/compatible-mode/v1/";
45 const MODELSCOPE_KEY: LazyLock<&str> =
46 LazyLock::new(|| include_str!("../../keys/modelstudio_domestic_key").trim());
47
48 #[test]
49 fn test_build_url() {
50 let request = request::RetrieveRequest { file_id: "file_id" };
51 let url = request.build_url("https://api.openai.com/v1/").unwrap();
52 assert_eq!(url, "https://api.openai.com/v1/files/file_id");
53 }
54
55 #[tokio::test]
56 async fn test_retrieve_file() -> Result<(), anyhow::Error> {
57 let list_request = ListFilesRequest {
59 limit: Some(5), ..Default::default()
61 };
62
63 let list_response = list_request
64 .get_response(MODELSCOPE_BASE_URL, &MODELSCOPE_KEY)
65 .await?;
66
67 let futures: Vec<_> = list_response
68 .data
69 .iter()
70 .map(|file_object| {
71 let file_id = file_object.id.clone();
72 let base_url = MODELSCOPE_BASE_URL.to_string();
73 let key = MODELSCOPE_KEY.to_string();
74 async move {
75 let retrieve_request = RetrieveRequest { file_id: &file_id };
76 retrieve_request.get_response(&base_url, &key).await
77 }
78 })
79 .collect();
80
81 let results = future::join_all(futures).await;
82
83 for (i, result) in results.iter().enumerate() {
84 match result {
85 Ok(file_object) => {
86 assert_eq!(&list_response.data[i].id, &file_object.id);
87 assert_eq!(&list_response.data[i].filename, &file_object.filename);
88 assert_eq!(&list_response.data[i].purpose, &file_object.purpose);
89 }
91 Err(e) => {
92 bail!(
93 "Failed to get response: {e:#}. The file is: index {i}, {:?}",
94 list_response.data[i]
95 )
96 }
97 }
98 }
99
100 Ok(())
101 }
102}