Добавить в корзинуПозвонить
Найти в Дзене
Один Rust не п...Rust

HTTP API c ML и без БД на Rust

Cargo.toml: [dependencies] warp = "0.3" tokio = { version = "1", features = ["full"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" uuid = { version = "1.3", features = ["v4"] } chrono = { version = "0.4", features = ["serde"] } smartcore = "0.5" use std::sync::{Arc, Mutex}; use warp::Filter; use serde::{Deserialize, Serialize}; use chrono::{DateTime, Utc}; use uuid::Uuid; use smartcore::text::bag_of_words::BagOfWords; use smartcore::naive_bayes::MultinomialNB; use smartcore::linalg::basic::matrix::DenseMatrix; #[derive(Deserialize)] struct NewTask { description: String, } #[derive(Serialize, Clone)] struct Task { id: String, description: String, created_at: DateTime<Utc>, category: String, } type TaskDB = Arc<Mutex<Vec<Task>>>; fn train_model() -> (BagOfWords, MultinomialNB<f64>) { let training_data = vec![ ("work on project", "Work"), ("meeting with team", "Work"), ("buy groceries", "Personal"), ("call mom", "Personal"), ("urgent deadline", "Urgent"), ("impo
GitHub - nicktretyakov/REST_ML_NoDB
ML на RUST без заморочек
Один Rust не п...Rust

  • HTTP API: Warp framework.
  • In-Memory Storage: Arc<Mutex<Vec<Task>>>.
  • ML Integration: smartcore library.
  • Task Structure: UUID.
  • No Database.

Cargo.toml:

[dependencies]

warp = "0.3"

tokio = { version = "1", features = ["full"] }

serde = { version = "1.0", features = ["derive"] }

serde_json = "1.0"

uuid = { version = "1.3", features = ["v4"] }

chrono = { version = "0.4", features = ["serde"] }

smartcore = "0.5"

  • GET /tasks: List all tasks.
  • GET /tasks/{id}: Retrieve a specific task.
  • PUT /tasks/{id}: Update a task.
  • DELETE /tasks/{id}: Delete a task.

use std::sync::{Arc, Mutex};

use warp::Filter;

use serde::{Deserialize, Serialize};

use chrono::{DateTime, Utc};

use uuid::Uuid;

use smartcore::text::bag_of_words::BagOfWords;

use smartcore::naive_bayes::MultinomialNB;

use smartcore::linalg::basic::matrix::DenseMatrix;

#[derive(Deserialize)]

struct NewTask {

description: String,

}

#[derive(Serialize, Clone)]

struct Task {

id: String,

description: String,

created_at: DateTime<Utc>,

category: String,

}

type TaskDB = Arc<Mutex<Vec<Task>>>;

fn train_model() -> (BagOfWords, MultinomialNB<f64>) {

let training_data = vec![

("work on project", "Work"),

("meeting with team", "Work"),

("buy groceries", "Personal"),

("call mom", "Personal"),

("urgent deadline", "Urgent"),

("important email", "Urgent"),

("schedule appointment", "Other"),

];

let descriptions: Vec<&str> = training_data.iter().map(|(d, _)| *d).collect();

let labels: Vec<&str> = training_data.iter().map(|(_, l)| *l).collect();

let vectorizer = BagOfWords::fit(&descriptions, None);

let features = vectorizer.transform(&descriptions);

let category_to_id = |cat: &str| match cat {

"Work" => 0,

"Personal" => 1,

"Urgent" => 2,

"Other" => 3,

_ => 4,

};

let labels_num: Vec<usize> = labels.iter().map(|&l| category_to_id(l)).collect();

let nb = MultinomialNB::fit(&features, &labels_num, Default::default()).unwrap();

(vectorizer, nb)

}

#[tokio::main]

async fn main() {

let (vectorizer, nb) = train_model();

let vectorizer = Arc::new(vectorizer);

let nb = Arc::new(nb);

let db: TaskDB = Arc::new(Mutex::new(Vec::new()));

let create_task = warp::post()

.and(warp::path("tasks"))

.and(warp::body::json())

.map(move |new_task: NewTask| {

let desc = new_task.description;

let features = vectorizer.transform(&[desc.as_str()]);

let prediction = nb.predict(&features).unwrap();

let category_id = prediction[0];

let category = match category_id {

0 => "Work",

1 => "Personal",

2 => "Urgent",

3 => "Other",

_ => "Unknown",

};

let id = Uuid::new_v4().to_string();

let now = Utc::now();

let task = Task {

id,

description: desc,

created_at: now,

category: category.to_string(),

};

let mut tasks = db.lock().unwrap();

tasks.push(task.clone());

warp::reply::json(&task)

});

warp::serve(create_task).run(([127, 0, 0, 1], 3030)).await;

}