Skip to main content

openai_interface/models/
delete.rs

1//! Module for deleting a fine-tuned model.
2//!
3//! You must have the Owner role in your organization to delete a model.
4//!
5//! > ![warn] This module is untested!
6//! > OpenAI-compatible providers are not known to implement this endpoint.
7//! > If you encounter any issues, please report them on the repository.
8
9pub mod request {
10    use url::Url;
11
12    use crate::{
13        errors::OapiError,
14        rest::delete::{Delete, DeleteNoStream},
15    };
16
17    /// Delete a fine-tuned model by its identifier.
18    #[derive(Debug, Clone)]
19    pub struct DeleteModelRequest<'a> {
20        /// The ID of the model to delete.
21        pub model: &'a str,
22    }
23
24    impl Delete for DeleteModelRequest<'_> {
25        /// base_url should look like <https://api.openai.com/v1>
26        fn build_url(&self, base_url: &str) -> Result<String, OapiError> {
27            let mut url =
28                Url::parse(base_url.trim_end_matches('/')).map_err(OapiError::UrlError)?;
29            url.path_segments_mut()
30                .map_err(|_| OapiError::UrlCannotBeBase(base_url.to_string()))?
31                .push("models")
32                .push(self.model);
33
34            Ok(url.to_string())
35        }
36    }
37
38    impl DeleteNoStream for DeleteModelRequest<'_> {
39        type Response = super::response::ModelDeleted;
40    }
41}
42
43pub mod response {
44    use serde::Deserialize;
45
46    /// The response of a model deletion.
47    #[derive(Debug, Deserialize, Clone)]
48    pub struct ModelDeleted {
49        /// The ID of the model that was deleted.
50        pub id: String,
51        /// Whether the model was deleted.
52        pub deleted: bool,
53        /// The object type, which is always `model`.
54        pub object: String,
55    }
56
57    crate::impl_from_str!(ModelDeleted);
58}
59
60#[cfg(test)]
61mod tests {
62    use super::request::DeleteModelRequest;
63    use crate::rest::delete::Delete;
64
65    #[test]
66    fn test_build_url() {
67        let request = DeleteModelRequest {
68            model: "ft:gpt-4o:my-org:custom-suffix:7p8f9k",
69        };
70        let url = request.build_url("https://api.openai.com/v1").unwrap();
71        assert_eq!(
72            url,
73            "https://api.openai.com/v1/models/ft:gpt-4o:my-org:custom-suffix:7p8f9k"
74        );
75    }
76
77    /// Deserializes a model deletion response.
78    ///
79    /// No accessible provider implements this endpoint, so this fixture is
80    /// NOT captured from a live response. The structure (`id` / `deleted` /
81    /// `object`) follows the schema of openai-python `types/model_deleted.py`;
82    /// the values are constructed for the test.
83    #[test]
84    fn test_parse_delete_response() {
85        let content =
86            r#"{"id":"ft:gpt-4o:my-org:custom-suffix:7p8f9k","deleted":true,"object":"model"}"#;
87
88        let response: super::response::ModelDeleted = content.parse().unwrap();
89        assert_eq!(response.id, "ft:gpt-4o:my-org:custom-suffix:7p8f9k");
90        assert!(response.deleted);
91        assert_eq!(response.object, "model");
92    }
93}