config + not implemented endpoints

master
prplV 2025-06-24 06:57:37 -04:00
parent 446512fdcb
commit 6805c7ac94
7 changed files with 187 additions and 17 deletions

View File

@ -7,14 +7,32 @@
# ------------------------------------------------------------------- # -------------------------------------------------------------------
ML_TARGET_URL="http://url.to/ml/api" ML_TARGET_URL="http://url.to/ml/api"
# `ML_API` log level selecetion (default - `INFO`) # `ML_MODEL_NAME`
# ----------------------------------------------- ML_MODEL_NAME="kis-test"
# Existing options:
# `ML_REQUEST_TIMEOUT` for setting ML response wait time
# ------------------------------------------------------
# - Measures in `secs`
# - Default value - 10
# ------------------------------------------------------
ML_REQUEST_TIMEOUT="10"
# `ML_API_LOG_LEVEL` log level selection
# --------------------------------------
# - Default value - `INFO`
# - Existing options:
# 1) TRACE - full log info # 1) TRACE - full log info
# 2) DEBUG # 2) DEBUG
# 3) INFO - common log info # 3) INFO - common log info
# 4) WARN # 4) WARN
# 5) ERROR # 5) ERROR
# 6) OFF - disabled logs # 6) OFF - disabled logs
# ----------------------------------------------- # --------------------------------------
ML_LOG_LEVEL="INFO" ML_API_LOG_LEVEL="INFO"
# `ML_API_PORT` for setting up virt port number usage
# ---------------------------------------------------
# - Deault value - 5143
# ---------------------------------------------------
ML_API_PORT="5134"

View File

@ -7,8 +7,9 @@ edition = "2024"
anyhow = "1.0.98" anyhow = "1.0.98"
axum = { version = "0.8.4", features = ["ws"] } axum = { version = "0.8.4", features = ["ws"] }
dotenv = "0.15.0" dotenv = "0.15.0"
futures = "0.3.31"
lazy_static = "1.5.0" lazy_static = "1.5.0"
reqwest = "0.12.20" reqwest = { version = "0.12.20", features = ["rustls-tls"] }
serde = { version = "1.0.219", features = ["derive"] } serde = { version = "1.0.219", features = ["derive"] }
serde_json = "1.0.140" serde_json = "1.0.140"
tokio = { version = "1.45.1", features = ["full"] } tokio = { version = "1.45.1", features = ["full"] }

View File

@ -1,5 +1,20 @@
pub mod openapi {} use axum::response::IntoResponse;
use axum::http::StatusCode;
pub mod ws {} pub mod openapi {
use super::{IntoResponse, StatusCode};
pub mod rest {} pub async fn swagger() -> impl IntoResponse { (StatusCode::NOT_IMPLEMENTED, "still in development ...") }
}
pub mod rest {
use super::{IntoResponse, StatusCode};
pub async fn model_rest_handler() -> impl IntoResponse { (StatusCode::NOT_IMPLEMENTED, "still in development ...") }
}
pub mod ws {
use super::{IntoResponse, StatusCode};
pub async fn model_ws_handler() -> impl IntoResponse { (StatusCode::NOT_IMPLEMENTED, "still in development ...") }
}

View File

@ -1,7 +1,43 @@
mod endpoints; mod endpoints;
mod schemas; mod schemas;
mod models;
mod setup;
use std::sync::Arc;
use tracing::info;
use dotenv::dotenv;
use endpoints::{
openapi::swagger,
rest::model_rest_handler,
ws::model_ws_handler,
};
use setup::setup_self_config;
use schemas::ApiSessionConfig;
use axum::{
routing::get,
Router};
#[tokio::main(flavor = "multi_thread")] #[tokio::main(flavor = "multi_thread")]
async fn main() { async fn main() -> anyhow::Result<()> {
println!("Hello, world!"); dotenv().ok();
let port = setup_self_config().await;
let app_state = Arc::new(ApiSessionConfig::from_env()?);
let base_url = format!("0.0.0.0:{}", port);
// routing
let api = Router::new()
.route("/rest", get(model_rest_handler))
.route("/ws", get(model_ws_handler));
let router = Router::new()
.nest("/api", api)
.route("/swagger", get(swagger))
.with_state(app_state.clone());
// running
info!("serving on {} ...", &base_url);
let listener = tokio::net::TcpListener::bind(&base_url).await?;
axum::serve(listener, router).await?;
Ok(())
} }

0
src/models.rs Normal file
View File

View File

@ -0,0 +1,55 @@
use tracing::{debug, instrument, warn, info};
use std::fmt;
///
#[derive(Debug)]
pub struct ApiSessionConfig {
// integration config
target_url : String,
model_name : String,
request_timeout : usize,
}
impl fmt::Display for ApiSessionConfig {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
let param_name_width = 25;
let param_name_val = (self.model_name.as_bytes().iter().count() + 4).max(self.target_url.as_bytes().iter().count() + 4);
let param_name_measure = 10;
// header
writeln!(f, "+{:-<param_name_width$}-+-{:-<param_name_val$}+{:-<param_name_measure$}-+",
"", "", "")?;
writeln!(f, "| {: <param_name_width$}| {: <param_name_val$}| {: <param_name_measure$}|",
"Param", "Value", "Measure")?;
writeln!(f, "+{:-<param_name_width$}-+-{:-<param_name_val$}+{:-<param_name_measure$}-+",
"", "", "")?;
// data
writeln!(f, "| {: <param_name_width$}| {: <param_name_val$}| {: <param_name_measure$}|",
"Target model url", self.target_url, "-")?;
writeln!(f, "| {: <param_name_width$}| {: <param_name_val$}| {: <param_name_measure$}|",
"Tagert model name", self.model_name, "-")?;
writeln!(f, "| {: <param_name_width$}| {: <param_name_val$}| {: <param_name_measure$}|",
"API response wait-time", self.request_timeout, "secs")?;
// footer
writeln!(f, "+{:-<param_name_width$}-+-{:-<param_name_val$}+{:-<param_name_measure$}-+",
"", "", "")?;
Ok(())
}
}
impl ApiSessionConfig {
#[instrument("app-config")]
pub fn from_env() -> anyhow::Result<Self> {
let config = Self {
target_url : std::env::var("ML_TARGET_URL")?,
model_name : std::env::var("ML_MODEL_NAME")?,
request_timeout : std::env::var("ML_REQUEST_TIMEOUT")?.parse().unwrap_or_else(|_| {
warn!("invalid port was given, setting up default one ...");
10
}),
};
debug!("{:?}", config);
info!("app is configurated. config :\n{}", config);
Ok(config)
}
}

45
src/setup.rs Normal file
View File

@ -0,0 +1,45 @@
use std::str::FromStr;
use tracing::{Level, trace, info, warn, instrument};
/// no docs
#[instrument(name = "configurating")]
pub async fn setup_self_config() -> u32 {
set_api_logger().await;
trace!("searching for port config ...");
get_api_port().await
}
/// no docs
#[instrument(name = "logger")]
async fn set_api_logger() {
let level = match std::env::var("ML_LOG_LEVEL") {
Ok(var) => Level::from_str(&var).unwrap_or_else(|_| Level::INFO),
Err(_) => Level::INFO,
};
tracing_subscriber::fmt()
.with_max_level(level)
.with_writer(std::io::stdout)
.with_span_events(tracing_subscriber::fmt::format::FmtSpan::NEW)
.with_line_number(false)
.with_target(false)
.with_file(false)
.compact()
.init();
info!("logger was configured");
}
/// no docs
#[instrument(name = "app-port")]
async fn get_api_port() -> u32 {
return match std::env::var("ML_API_PORT") {
Ok(var) => var.parse::<u32>().unwrap_or_else(|_| {
warn!("invalid port var ({} was given), setting up default ...", &var);
5134
}),
Err(er) => {
warn!("cannot find port config ({}), setting up default ...", er);
5134
},
};
}