use dotenvy::dotenv;
use openai4rs::*;
use std::time::Instant;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
dotenv().ok();
let api_key = std::env::var("OPENAI_API_KEY").unwrap();
let base_url = std::env::var("OPENAI_BASE_URL").unwrap();
let client = Config::builder()
.api_key(api_key)
.base_url(base_url)
.global_interceptor(LoggingInterceptor::new())
.global_interceptor(RequestModifierInterceptor)
.build_openai()?;
let model = "Qwen/Qwen3-235B-A22B-Instruct-2507";
let messages = vec![
system!("You are a helpful assistant."),
user!("What is the weather like today?"),
];
let request = chat_request(model, &messages);
println!("Sending request with interceptors...");
let start_time = Instant::now();
let response = client.chat().create(request).await?;
let duration = start_time.elapsed();
if let Some(content) = response.content() {
println!("\nResponse (took {:?}):\n{}", duration, content);
} else {
println!("\nNo content in response.");
}
Ok(())
}
#[derive(Debug)]
struct LoggingInterceptor {
start_time: std::sync::Mutex<Option<Instant>>,
}
impl LoggingInterceptor {
fn new() -> Self {
Self {
start_time: std::sync::Mutex::new(None),
}
}
}
#[async_trait::async_trait]
impl Interceptor for LoggingInterceptor {
fn priority(&self) -> InterceptorPriority {
InterceptorPriority::High }
async fn on_request(&self, request: Request) -> Result<Request, OpenAIError> {
println!(
"[LOG] LoggingInterceptor: Request starting to {}",
request.url()
);
*self.start_time.lock().unwrap() = Some(Instant::now());
Ok(request)
}
async fn on_response(
&self,
response: reqwest::Response,
) -> Result<reqwest::Response, OpenAIError> {
let duration = self
.start_time
.lock()
.unwrap()
.take()
.map(|start| start.elapsed());
println!(
"[LOG] LoggingInterceptor: Response received with status {}, took {:?}",
response.status(),
duration
);
Ok(response)
}
async fn on_error(&self, error: OpenAIError) -> Result<OpenAIError, OpenAIError> {
println!("[LOG] LoggingInterceptor: Error occurred: {:?}", error);
Ok(error)
}
}
#[derive(Debug)]
struct RequestModifierInterceptor;
#[async_trait]
impl Interceptor for RequestModifierInterceptor {
fn priority(&self) -> InterceptorPriority {
InterceptorPriority::Low }
async fn on_request(&self, request: Request) -> Result<Request, OpenAIError> {
println!("[MODIFY] RequestModifierInterceptor: Modifying request body");
Ok(request)
}
async fn on_response(
&self,
response: reqwest::Response,
) -> Result<reqwest::Response, OpenAIError> {
println!("[MODIFY] RequestModifierInterceptor: Processing response");
Ok(response)
}
}