Skip to main content

openai_oxide/resources/
models.rs

1// Models resource — client.models().list() / retrieve() / delete()
2
3use crate::client::OpenAI;
4use crate::error::OpenAIError;
5use crate::types::model::{Model, ModelDeleted, ModelList};
6
7/// Access model endpoints.
8pub struct Models<'a> {
9    client: &'a OpenAI,
10}
11
12impl<'a> Models<'a> {
13    pub(crate) fn new(client: &'a OpenAI) -> Self {
14        Self { client }
15    }
16
17    /// List available models.
18    ///
19    /// `GET /models`
20    pub async fn list(&self) -> Result<ModelList, OpenAIError> {
21        self.client.get("/models").await
22    }
23
24    /// Retrieve a model by ID.
25    ///
26    /// `GET /models/{model}`
27    pub async fn retrieve(&self, model: &str) -> Result<Model, OpenAIError> {
28        self.client.get(&format!("/models/{model}")).await
29    }
30
31    /// Delete a fine-tuned model.
32    ///
33    /// `DELETE /models/{model}`
34    pub async fn delete(&self, model: &str) -> Result<ModelDeleted, OpenAIError> {
35        self.client.delete(&format!("/models/{model}")).await
36    }
37}
38
39#[cfg(test)]
40mod tests {
41    use crate::OpenAI;
42    use crate::config::ClientConfig;
43
44    #[tokio::test]
45    async fn test_models_list() {
46        let mut server = mockito::Server::new_async().await;
47        let mock = server
48            .mock("GET", "/models")
49            .match_header("authorization", "Bearer sk-test")
50            .with_status(200)
51            .with_header("content-type", "application/json")
52            .with_body(
53                r#"{
54                    "object": "list",
55                    "data": [
56                        {"id": "gpt-4o", "object": "model", "created": 1687882411, "owned_by": "openai"},
57                        {"id": "gpt-3.5-turbo", "object": "model", "created": 1677610602, "owned_by": "openai"}
58                    ]
59                }"#,
60            )
61            .create_async()
62            .await;
63
64        let client = OpenAI::with_config(ClientConfig::new("sk-test").base_url(server.url()));
65        let response = client.models().list().await.unwrap();
66        assert_eq!(response.data.len(), 2);
67        assert_eq!(response.data[0].id, "gpt-4o");
68        mock.assert_async().await;
69    }
70
71    #[tokio::test]
72    async fn test_models_retrieve() {
73        let mut server = mockito::Server::new_async().await;
74        let mock = server
75            .mock("GET", "/models/gpt-4o")
76            .with_status(200)
77            .with_header("content-type", "application/json")
78            .with_body(
79                r#"{"id": "gpt-4o", "object": "model", "created": 1687882411, "owned_by": "openai"}"#,
80            )
81            .create_async()
82            .await;
83
84        let client = OpenAI::with_config(ClientConfig::new("sk-test").base_url(server.url()));
85        let model = client.models().retrieve("gpt-4o").await.unwrap();
86        assert_eq!(model.id, "gpt-4o");
87        assert_eq!(model.owned_by, "openai");
88        mock.assert_async().await;
89    }
90
91    #[tokio::test]
92    async fn test_models_delete() {
93        let mut server = mockito::Server::new_async().await;
94        let mock = server
95            .mock("DELETE", "/models/ft:gpt-4o:org:custom:id")
96            .with_status(200)
97            .with_header("content-type", "application/json")
98            .with_body(r#"{"id": "ft:gpt-4o:org:custom:id", "object": "model", "deleted": true}"#)
99            .create_async()
100            .await;
101
102        let client = OpenAI::with_config(ClientConfig::new("sk-test").base_url(server.url()));
103        let resp = client
104            .models()
105            .delete("ft:gpt-4o:org:custom:id")
106            .await
107            .unwrap();
108        assert!(resp.deleted);
109        mock.assert_async().await;
110    }
111}