#[cfg(feature = "server")]
use axum::{
Router,
response::{IntoResponse, Json},
routing::get,
};
#[cfg(feature = "server")]
use embellama::server::{
AppState, EngineConfig, ModelConfig, ServerConfig, create_router, inject_request_id,
limit_request_size,
};
#[cfg(feature = "server")]
use serde_json::json;
#[cfg(feature = "server")]
use std::env;
#[cfg(feature = "server")]
use tower::ServiceBuilder;
#[cfg(feature = "server")]
async fn custom_info_handler() -> impl IntoResponse {
Json(json!({
"name": "Embedded Embellama Server",
"description": "This is a custom endpoint added to the embedded server",
"version": env!("CARGO_PKG_VERSION"),
}))
}
#[cfg(feature = "server")]
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
embellama::init_with_env_filter("info,embellama=debug");
let model_path = env::args()
.nth(1)
.or_else(|| env::var("EMBELLAMA_MODEL_PATH").ok())
.expect("Please provide model path as first argument or set EMBELLAMA_MODEL_PATH");
println!("Starting embedded server example with model: {model_path}");
example_simple_server(&model_path).await?;
example_custom_router(&model_path).await?;
example_integrated_app(&model_path).await?;
Ok(())
}
#[cfg(feature = "server")]
async fn example_simple_server(model_path: &str) -> Result<(), Box<dyn std::error::Error>> {
println!("\n=== Example 1: Simple Server ===");
println!("This uses the convenient run_server function");
let engine_config = EngineConfig::builder()
.with_model_path(model_path)
.with_model_name("embedded-model")
.build()?;
let config = ServerConfig::builder()
.engine_config(engine_config)
.host("127.0.0.1")
.port(8081)
.worker_count(2)
.queue_size(50)
.build()?;
println!("Server would run with config: {config:?}");
Ok(())
}
#[cfg(feature = "server")]
async fn example_custom_router(model_path: &str) -> Result<(), Box<dyn std::error::Error>> {
println!("\n=== Example 2: Custom Router ===");
println!("This creates a custom router with additional routes");
let engine_config = EngineConfig::builder()
.with_model_path(model_path)
.with_model_name("custom-model")
.build()?;
let config = ServerConfig::builder()
.engine_config(engine_config)
.port(8082)
.build()?;
let state = AppState::new(config)?;
let mut app = create_router(state.clone());
app = app
.route("/custom/info", get(custom_info_handler))
.route(
"/custom/echo",
axum::routing::post(|body: String| async move {
Json(json!({
"echo": body,
"timestamp": chrono::Utc::now().to_rfc3339(),
}))
}),
)
.nest(
"/api",
Router::new()
.route("/status", get(|| async { "API is running" }))
.route("/version", get(|| async { env!("CARGO_PKG_VERSION") })),
);
app = app.layer(
ServiceBuilder::new()
.layer(axum::middleware::from_fn(inject_request_id))
.layer(axum::middleware::from_fn(limit_request_size)),
);
println!("Custom router created with additional routes:");
println!(" - /custom/info (GET)");
println!(" - /custom/echo (POST)");
println!(" - /api/status (GET)");
println!(" - /api/version (GET)");
println!(" Plus standard embedding routes at /v1/*");
Ok(())
}
#[cfg(feature = "server")]
async fn example_integrated_app(model_path: &str) -> Result<(), Box<dyn std::error::Error>> {
println!("\n=== Example 3: Integrated Application ===");
println!("This shows how to integrate embedding server into an existing app");
#[derive(Clone)]
struct MyAppState {
embedding_state: AppState,
custom_data: String,
}
let engine_config = EngineConfig::builder()
.with_model_path(model_path)
.with_model_name("integrated-model")
.build()?;
let config = ServerConfig::builder()
.engine_config(engine_config)
.build()?;
let embedding_state = AppState::new(config)?;
let app_state = MyAppState {
embedding_state: embedding_state.clone(),
custom_data: "Some application data".to_string(),
};
let _app = Router::new()
.route("/", get(|| async { "Welcome to my application!" }))
.route(
"/app/data",
get({
let state = app_state.clone();
move || async move { state.custom_data.clone() }
}),
)
.nest("/embeddings", create_router(embedding_state));
println!("Integrated application created with:");
println!(" - Main app routes at /");
println!(" - Embedding API at /embeddings/v1/*");
Ok(())
}
#[cfg(not(feature = "server"))]
fn main() {
eprintln!("This example requires the 'server' feature to be enabled.");
eprintln!("Run with: cargo run --example embedded_server --features server");
std::process::exit(1);
}