use std::net::{IpAddr, SocketAddr};
use crate::{
ExtractionConfig, Result, core::ServerConfig, extractors, plugins::startup_validation::validate_plugins_at_startup,
};
use super::{config::load_server_config, router::create_router_with_limits_and_server_config, types::ApiSizeLimits};
pub async fn serve(host: impl AsRef<str>, port: u16) -> Result<()> {
let extraction_config = match ExtractionConfig::discover()? {
Some(config) => {
tracing::info!("Loaded extraction config from discovered file");
config
}
None => {
tracing::info!("No config file found, using default configuration");
ExtractionConfig::default()
}
};
let server_config = load_server_config(None)?;
let limits = ApiSizeLimits::new(
server_config.max_request_body_bytes,
server_config.max_multipart_field_bytes,
);
extractors::ensure_initialized()?;
validate_plugins_at_startup()?;
serve_with_config_and_limits(host, port, extraction_config, limits).await
}
pub async fn serve_with_config(host: impl AsRef<str>, port: u16, config: ExtractionConfig) -> Result<()> {
let limits = ApiSizeLimits::default();
tracing::info!(
"Upload size limit: 100 MB (default, {} bytes)",
limits.max_request_body_bytes
);
extractors::ensure_initialized()?;
validate_plugins_at_startup()?;
serve_with_config_and_limits(host, port, config, limits).await
}
pub async fn serve_with_config_and_limits(
host: impl AsRef<str>,
port: u16,
config: ExtractionConfig,
limits: ApiSizeLimits,
) -> Result<()> {
let ip: IpAddr = host
.as_ref()
.parse()
.map_err(|e| crate::error::KreuzbergError::validation(format!("Invalid host address: {}", e)))?;
let server_config = ServerConfig {
host: host.as_ref().to_string(),
port,
max_request_body_bytes: limits.max_request_body_bytes,
max_multipart_field_bytes: limits.max_multipart_field_bytes,
..Default::default()
};
let addr = SocketAddr::new(ip, port);
let app = create_router_with_limits_and_server_config(config, limits, server_config);
extractors::ensure_initialized()?;
validate_plugins_at_startup()?;
tracing::info!("Starting Kreuzberg API server on http://{}:{}", ip, port);
let listener = tokio::net::TcpListener::bind(addr)
.await
.map_err(crate::error::KreuzbergError::Io)?;
axum::serve(listener, app)
.await
.map_err(|e| crate::error::KreuzbergError::Other(e.to_string()))?;
Ok(())
}
pub async fn serve_with_server_config(extraction_config: ExtractionConfig, server_config: ServerConfig) -> Result<()> {
let ip: IpAddr = server_config
.host
.parse()
.map_err(|e| crate::error::KreuzbergError::validation(format!("Invalid host address: {}", e)))?;
let limits = ApiSizeLimits::new(
server_config.max_request_body_bytes,
server_config.max_multipart_field_bytes,
);
let addr = SocketAddr::new(ip, server_config.port);
let app = create_router_with_limits_and_server_config(extraction_config, limits, server_config.clone());
extractors::ensure_initialized()?;
validate_plugins_at_startup()?;
tracing::info!(
"Starting Kreuzberg API server on http://{}:{} (request_body_limit={} MB, multipart_field_limit={} MB)",
ip,
server_config.port,
server_config.max_request_body_mb(),
server_config.max_multipart_field_mb()
);
let listener = tokio::net::TcpListener::bind(addr)
.await
.map_err(crate::error::KreuzbergError::Io)?;
axum::serve(listener, app)
.await
.map_err(|e| crate::error::KreuzbergError::Other(e.to_string()))?;
Ok(())
}
pub async fn serve_default() -> Result<()> {
serve("127.0.0.1", 8000).await
}