HTTP API WIP

This commit is contained in:
Sebastian Hugentobler 2025-07-01 14:02:18 +02:00
parent 0bd97d0ed3
commit 552fce432b
Signed by: shu
SSH key fingerprint: SHA256:ppcx6MlixdNZd5EUM1nkHOKoyQYoJwzuQKXM6J/t66M
14 changed files with 740 additions and 35 deletions

75
src/api.rs Normal file
View file

@ -0,0 +1,75 @@
use std::{
io,
net::{AddrParseError, SocketAddr},
str::FromStr,
};
use snafu::{ResultExt, Snafu};
use state::AppState;
use tokio::net::TcpListener;
use utoipa::OpenApi;
use utoipa_axum::router::OpenApiRouter;
use utoipa_swagger_ui::SwaggerUi;
use crate::{storage::Postgres, text_encoder::TextEncoder, tokenize::Tokenizer};
pub mod error;
pub mod query;
pub mod routes;
pub mod state;
const TAG: &str = "little-librarian";
#[derive(OpenApi)]
#[openapi(
tags(
(name = TAG, description = "Calibre Semantic Search API")
)
)]
struct ApiDoc;
#[derive(Debug, Snafu)]
pub enum ServeError {
#[snafu(display("Failed to parse address into <ip>:<port>."))]
AddressParse { source: AddrParseError },
#[snafu(display("Failed to bind to {address}."))]
Bind {
source: io::Error,
address: SocketAddr,
},
#[snafu(display("Failed to run http server."))]
Serve { source: io::Error },
}
pub async fn serve(
address: &str,
db: Postgres,
tokenizer: Tokenizer,
embedder: TextEncoder,
reranker: TextEncoder,
chunk_size: usize,
) -> Result<(), ServeError> {
let state = AppState {
db,
tokenizer,
embedder,
reranker,
chunk_size,
};
let (router, api) = OpenApiRouter::with_openapi(ApiDoc::openapi())
.nest("/api/v1/", routes::router(state))
.split_for_parts();
let router =
router.merge(SwaggerUi::new("/swagger-ui").url("/api-docs/openapi.json", api.clone()));
let address = SocketAddr::from_str(address).context(AddressParseSnafu)?;
let listener = TcpListener::bind(&address)
.await
.context(BindSnafu { address })?;
axum::serve(listener, router.into_make_service())
.await
.context(ServeSnafu)
}