llm_edge_proxy/config/
mod.rs1use serde::{Deserialize, Serialize};
4use std::time::Duration;
5
6#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct Config {
9 pub server: ServerConfig,
10 pub rate_limit: RateLimitConfig,
11 pub auth: AuthConfig,
12 pub observability: ObservabilityConfig,
13}
14
15#[derive(Debug, Clone, Serialize, Deserialize)]
16pub struct ServerConfig {
17 pub address: String,
18 pub timeout_seconds: u64,
19 pub max_request_size: usize,
20 pub enable_tls: bool,
21 pub tls_cert_path: Option<String>,
22 pub tls_key_path: Option<String>,
23}
24
25#[derive(Debug, Clone, Serialize, Deserialize)]
26pub struct RateLimitConfig {
27 pub enabled: bool,
28 pub requests_per_minute: u32,
29 pub burst_size: u32,
30}
31
32#[derive(Debug, Clone, Serialize, Deserialize)]
33pub struct AuthConfig {
34 pub enabled: bool,
35 pub api_keys: Vec<String>,
36 pub require_auth_for_health: bool,
37}
38
39#[derive(Debug, Clone, Serialize, Deserialize)]
40pub struct ObservabilityConfig {
41 pub enable_tracing: bool,
42 pub enable_metrics: bool,
43 pub log_level: String,
44 pub otlp_endpoint: Option<String>,
45}
46
47impl Config {
48 pub fn from_env() -> anyhow::Result<Self> {
50 let server = ServerConfig {
51 address: std::env::var("SERVER_ADDRESS").unwrap_or_else(|_| "0.0.0.0:8080".to_string()),
52 timeout_seconds: std::env::var("SERVER_TIMEOUT_SECONDS")
53 .unwrap_or_else(|_| "30".to_string())
54 .parse()?,
55 max_request_size: std::env::var("MAX_REQUEST_SIZE")
56 .unwrap_or_else(|_| "10485760".to_string()) .parse()?,
58 enable_tls: std::env::var("ENABLE_TLS")
59 .unwrap_or_else(|_| "false".to_string())
60 .parse()?,
61 tls_cert_path: std::env::var("TLS_CERT_PATH").ok(),
62 tls_key_path: std::env::var("TLS_KEY_PATH").ok(),
63 };
64
65 let rate_limit = RateLimitConfig {
66 enabled: std::env::var("RATE_LIMIT_ENABLED")
67 .unwrap_or_else(|_| "true".to_string())
68 .parse()?,
69 requests_per_minute: std::env::var("RATE_LIMIT_RPM")
70 .unwrap_or_else(|_| "1000".to_string())
71 .parse()?,
72 burst_size: std::env::var("RATE_LIMIT_BURST")
73 .unwrap_or_else(|_| "100".to_string())
74 .parse()?,
75 };
76
77 let auth = AuthConfig {
78 enabled: std::env::var("AUTH_ENABLED")
79 .unwrap_or_else(|_| "true".to_string())
80 .parse()?,
81 api_keys: std::env::var("API_KEYS")
82 .unwrap_or_default()
83 .split(',')
84 .filter(|s| !s.is_empty())
85 .map(|s| s.to_string())
86 .collect(),
87 require_auth_for_health: std::env::var("AUTH_HEALTH_CHECK")
88 .unwrap_or_else(|_| "false".to_string())
89 .parse()?,
90 };
91
92 let observability = ObservabilityConfig {
93 enable_tracing: std::env::var("ENABLE_TRACING")
94 .unwrap_or_else(|_| "true".to_string())
95 .parse()?,
96 enable_metrics: std::env::var("ENABLE_METRICS")
97 .unwrap_or_else(|_| "true".to_string())
98 .parse()?,
99 log_level: std::env::var("LOG_LEVEL").unwrap_or_else(|_| "info".to_string()),
100 otlp_endpoint: std::env::var("OTLP_ENDPOINT").ok(),
101 };
102
103 Ok(Config {
104 server,
105 rate_limit,
106 auth,
107 observability,
108 })
109 }
110
111 pub fn timeout_duration(&self) -> Duration {
112 Duration::from_secs(self.server.timeout_seconds)
113 }
114}
115
116#[cfg(test)]
117mod tests {
118 use super::*;
119
120 #[test]
121 fn test_default_config() {
122 std::env::remove_var("SERVER_ADDRESS");
123 let config = Config::from_env().unwrap();
124 assert_eq!(config.server.address, "0.0.0.0:8080");
125 }
126}