use actix_web::middleware::Logger;
use actix_web::{web, App, HttpServer};
use apistos::app::{BuildConfig, OpenApiWrapper};
use apistos::web::{get, post, resource, scope};
use apistos::{info::Info, server::Server, spec::Spec};
use apistos::{RapidocConfig, RedocConfig, ScalarConfig, SwaggerUIConfig};
use dotenv::dotenv;
use embedcache::{
embed_text, initialize_chunkers, initialize_db_pool, initialize_models,
list_supported_features, process_url, AppState, LLMConfig, ServerConfig,
};
#[actix_web::main]
async fn main() -> std::io::Result<()> {
dotenv().ok();
let config = ServerConfig::from_env().expect("Failed to load configuration");
let db_pool = initialize_db_pool(&config)
.await
.expect("Failed to initialize database pool");
let models = initialize_models(&config).expect("Failed to initialize models");
let llm_config = LLMConfig::from_server_config(&config);
let chunkers = initialize_chunkers(llm_config.as_ref());
let app_state = web::Data::new(AppState {
db_pool,
models,
chunkers,
});
let server_addr = format!("{}:{}", config.host, config.port);
println!("Starting server at {}", server_addr);
HttpServer::new(move || {
let spec = Spec {
info: Info {
title: "Embedcache API".to_string(),
description: Some(
"High-performance text embedding API with caching capabilities".to_string(),
),
..Default::default()
},
servers: vec![Server {
url: "/".to_string(),
..Default::default()
}],
..Default::default()
};
App::new()
.document(spec)
.wrap(Logger::default())
.app_data(app_state.clone())
.service(
scope("/v1")
.service(resource("/embed").route(post().to(embed_text)))
.service(resource("/process").route(post().to(process_url)))
.service(resource("/params").route(get().to(list_supported_features))),
)
.build_with(
"/openapi.json",
BuildConfig::default()
.with(RapidocConfig::new(&"/rapidoc"))
.with(RedocConfig::new(&"/redoc"))
.with(ScalarConfig::new(&"/scalar"))
.with(SwaggerUIConfig::new(&"/swagger")),
)
})
.bind(server_addr)?
.run()
.await
}