Merge pull request #1 from andreban/add-delete-endpoint

Add delete model endpoint (DELETE /api/delete)
This commit is contained in:
2026-02-01 21:15:53 +00:00
committed by GitHub
4 changed files with 138 additions and 8 deletions

16
examples/delete.rs Normal file
View File

@@ -0,0 +1,16 @@
use std::{env, error::Error};
use ollama_rs::OllamaClient;
use ollama_rs::types::delete::DeleteRequest;
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
tracing_subscriber::fmt().init();
let _ = dotenvy::dotenv();
let server_address = env::var("OLLAMA_SERVER")?;
let model = env::args().nth(1).expect("usage: delete <model>");
let ollama_client = OllamaClient::new(server_address);
ollama_client.delete(DeleteRequest::new(&model)).await?;
println!("Model '{}' deleted successfully", model);
Ok(())
}

View File

@@ -93,6 +93,7 @@ use crate::{
error::{OllamaError, OllamaResult}, error::{OllamaError, OllamaResult},
types::{ types::{
chat::{ChatRequest, ChatResponse}, chat::{ChatRequest, ChatResponse},
delete::DeleteRequest,
generate::{GenerateRequest, GenerateResponse}, generate::{GenerateRequest, GenerateResponse},
ps::PsResponse, ps::PsResponse,
pull::{PullRequest, PullResponse}, pull::{PullRequest, PullResponse},
@@ -247,6 +248,40 @@ impl OllamaClient {
.await?) .await?)
} }
/// Deletes a model from the Ollama server.
///
/// Calls `DELETE /api/delete`.
///
/// # Errors
///
/// Returns [`OllamaError::NetworkError`] if the server is unreachable, the model
/// does not exist, or the server returns a non-success status code.
///
/// # Examples
///
/// ```no_run
/// # use ollama_rs::OllamaClient;
/// # use ollama_rs::types::delete::DeleteRequest;
/// # async fn run() -> ollama_rs::error::OllamaResult<()> {
/// let client = OllamaClient::default();
/// let request = DeleteRequest::new("gemma3");
/// client.delete(request).await?;
/// println!("Model deleted successfully");
/// # Ok(())
/// # }
/// ```
pub async fn delete(&self, request: DeleteRequest) -> OllamaResult<()> {
let request_address = format!("{}/api/delete", self.server_address);
info!("Delete model: {}", request.model);
self.client
.delete(request_address)
.json(&request)
.send()
.await?
.error_for_status()?;
Ok(())
}
fn stream_response<R: Serialize, T: DeserializeOwned>( fn stream_response<R: Serialize, T: DeserializeOwned>(
&self, &self,
endpoint: String, endpoint: String,

77
src/types/delete.rs Normal file
View File

@@ -0,0 +1,77 @@
//! Types for the model delete endpoint (`DELETE /api/delete`).
//!
//! Use [`DeleteRequest::new()`] to construct a request and pass it to
//! [`OllamaClient::delete()`](crate::OllamaClient::delete).
//!
//! # Examples
//!
//! ```no_run
//! # use ollama_rs::OllamaClient;
//! # use ollama_rs::types::delete::DeleteRequest;
//! # async fn run() -> ollama_rs::error::OllamaResult<()> {
//! let client = OllamaClient::default();
//! let request = DeleteRequest::new("gemma3");
//! client.delete(request).await?;
//! println!("Model deleted successfully");
//! # Ok(())
//! # }
//! ```
use serde::{Deserialize, Serialize};
/// A request to delete a model from the Ollama server (`DELETE /api/delete`).
///
/// # Examples
///
/// ```
/// use ollama_rs::types::delete::DeleteRequest;
///
/// let request = DeleteRequest::new("gemma3");
/// assert_eq!(request.model, "gemma3");
/// ```
#[derive(Debug, Serialize, Deserialize)]
pub struct DeleteRequest {
/// The name of the model to delete (e.g., `"gemma3"`, `"llama3:latest"`).
pub model: String,
}
impl DeleteRequest {
/// Creates a new [`DeleteRequest`] for the given model name.
pub fn new<M: Into<String>>(model: M) -> Self {
Self {
model: model.into(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use serde_json::json;
#[test]
fn new_creates_request() {
let request = DeleteRequest::new("gemma3");
assert_eq!(request.model, "gemma3");
}
#[test]
fn new_accepts_string() {
let request = DeleteRequest::new(String::from("llama3:latest"));
assert_eq!(request.model, "llama3:latest");
}
#[test]
fn request_serializes_correctly() {
let request = DeleteRequest::new("gemma3");
let json = serde_json::to_value(&request).unwrap();
assert_eq!(json, json!({"model": "gemma3"}));
}
#[test]
fn request_deserializes_correctly() {
let json = json!({"model": "gemma3"});
let request: DeleteRequest = serde_json::from_value(json).unwrap();
assert_eq!(request.model, "gemma3");
}
}

View File

@@ -3,8 +3,9 @@
//! Each submodule corresponds to an API endpoint: //! Each submodule corresponds to an API endpoint:
//! //!
//! | Module | Endpoint | Description | //! | Module | Endpoint | Description |
//! |--------------|-------------------|------------------------------------------| //! |--------------|-----------------------|------------------------------------------|
//! | [`chat`] | `POST /api/chat` | Multi-turn chat conversations | //! | [`chat`] | `POST /api/chat` | Multi-turn chat conversations |
//! | [`delete`] | `DELETE /api/delete` | Delete a model from the server |
//! | [`generate`] | `POST /api/generate` | Single-prompt text generation | //! | [`generate`] | `POST /api/generate` | Single-prompt text generation |
//! | [`pull`] | `POST /api/pull` | Download models from the registry | //! | [`pull`] | `POST /api/pull` | Download models from the registry |
//! | [`tags`] | `GET /api/tags` | List available models | //! | [`tags`] | `GET /api/tags` | List available models |
@@ -17,6 +18,7 @@
pub mod chat; pub mod chat;
pub mod common; pub mod common;
pub mod delete;
pub mod generate; pub mod generate;
pub mod ps; pub mod ps;
pub mod pull; pub mod pull;