ollarust 0.1.2

Ollama API client for Rust
Documentation
pub mod structs;

use thiserror::Error as TError;

#[derive(TError, Debug)]
pub enum OError {
}

pub type OllamaResult<T> = Result<T, OError>;


use reqwest::{Client, Error};
use serde::{Serialize, Deserialize};
use serde_json::Value;
use crate::structs::*;

fn url(base_url: &str, endpoint: &str) -> String {
    format!( "{}{}", base_url, endpoint )
}

#[derive(Debug)]
pub struct Ollama {
    client: Client,
    base_url: String,
    pub version: String
}

impl Ollama {
    async fn send_request<T, R>(
        &self,
        method: &str,
        url: &str,
        payload: Option<T>,
    ) -> Result<R, reqwest::Error>
    where
        T: Serialize,
        R: for<'de> Deserialize<'de>,
    {
        let request = match method.to_uppercase().as_str() {
            "POST" => {
                let body = payload
                    .map(|p| serde_json::to_value(p).unwrap())
                    .unwrap_or(Value::Null);
                println!("{:?}", body);

                self.client.post(url).json(&body)
            }
            _ => self.client.get(url),
        };

        let response = request
            .send()
            .await?
            .json::<R>()
            .await?;

        Ok(response)
    }

    pub async fn new(port: Option<String>) -> Result<Self, Error> {
        let port = port.unwrap_or("11434".to_string());
        let base_url = format!("http://localhost:{}/api", port);

        let client = Client::new();

        let get_version: Ver = client
            .get( &url(&base_url, "/version") )
            .send()
            .await?
            .json()
            .await?;

        Ok( Self {
            client: client,
            base_url: base_url,
            version: get_version.version
        } )
    }

    pub async fn generate(&self, payload: GeneratePayload) -> Result<GenerateResponse, Error> {
        self.send_request("POST", &url(&self.base_url, "/generate"), Some(payload)).await
    }

    pub async fn chat(&self, payload: ChatPayload) -> Result<ChatResponse, Error> {
        self.send_request("POST", &url(&self.base_url, "/chat"), Some(payload)).await
    }

    pub async fn embed(&self, payload: EmbedPayload) -> Result<EmbeddingResponse, Error> {
        self.send_request("POST", &url(&self.base_url, "/embed"), Some(payload)).await
    }

    pub async fn list_models(&self) -> Result< ListModels, Error> {
        self.send_request("GET", &url(&self.base_url, "/tags"), None::<()>).await
    }

    pub async fn ps(&self) -> Result< ListModels, Error > {
        self.send_request("GET", &url(&self.base_url, "/ps"), None::<()>).await
    }

    pub async fn show(&self, payload: ShowPayload) -> Result<ShowResponse, Error> {
        self.send_request("POST", &url(&self.base_url, "/show"), Some(payload)).await
    }

    pub async fn create(&self, payload: CreateModelPayload) -> Result<CreateModelResponse, Error> {
        self.send_request("POST", &url(&self.base_url, "/create"), Some(payload) ).await
    }

    pub async fn copy(&self, payload: CopyModel) {
        let _: Result< Value, Error> = self.send_request( "POST", &url(&self.base_url, "/copy"), Some(payload) ).await;
    }

    pub async fn pull(&self, payload: ShowPayload) -> Result<CreateModelResponse, Error> {
        self.send_request("POST", &url(&self.base_url, "/pull"), Some(payload) ).await
    }

    pub async fn push(&self, payload: ShowPayload) -> Result<CreateModelResponse, Error> {
        self.send_request("POST", &url(&self.base_url, "/pull"), Some(payload) ).await
    }

    pub async fn delete(&self) {
        todo!("i will do that in 1.0.0")
    }
}