use axum::{
Json, Router,
extract::Request,
middleware,
response::Response,
routing::{get, post},
};
use crabllm_core::{Provider, Storage};
pub use auth::KeyName;
pub use state::AppState;
pub mod admin;
pub mod auth;
pub mod ext;
mod handlers;
mod state;
pub mod storage;
async fn track_active_connections(request: Request, next: middleware::Next) -> Response {
metrics::gauge!("crabllm_active_connections").increment(1.0);
let response = next.run(request).await;
metrics::gauge!("crabllm_active_connections").decrement(1.0);
response
}
pub fn router<S, P>(state: AppState<S, P>, admin_routes: Vec<Router>) -> Router
where
S: Storage + 'static,
P: Provider + 'static,
{
let mut app = Router::<AppState<S, P>>::new()
.route(
"/v1/chat/completions",
post(handlers::chat_completions::<S, P>),
)
.route("/v1/embeddings", post(handlers::embeddings::<S, P>))
.route(
"/v1/images/generations",
post(handlers::image_generations::<S, P>),
)
.route("/v1/audio/speech", post(handlers::audio_speech::<S, P>))
.route(
"/v1/audio/transcriptions",
post(handlers::audio_transcriptions::<S, P>),
)
.route("/v1/models", get(handlers::models::<S, P>))
.layer(middleware::from_fn_with_state(
state.clone(),
auth::auth::<S, P>,
))
.layer(middleware::from_fn(track_active_connections))
.with_state(state);
app = app.route(
"/health",
get(|| async { Json(serde_json::json!({"status": "ok"})) }),
);
for admin_router in admin_routes {
app = app.merge(admin_router);
}
app
}