http_middleware_retry/
http_middleware_retry.rs1use openai_ergonomic::{Client, Config, Response, Result};
15use reqwest_middleware::ClientBuilder;
16use reqwest_retry::{policies::ExponentialBackoff, RetryTransientMiddleware};
17
18#[tokio::main]
19async fn main() -> Result<()> {
20 println!("=== HTTP Middleware with Retry Example ===\n");
21
22 println!("1. Creating client with retry middleware");
24
25 let retry_policy = ExponentialBackoff::builder().build_with_max_retries(3);
28
29 let http_client = ClientBuilder::new(reqwest::Client::new())
31 .with(RetryTransientMiddleware::new_with_policy(retry_policy))
32 .build();
33
34 let config = Config::builder()
36 .api_key(
37 std::env::var("OPENAI_API_KEY")
38 .expect("OPENAI_API_KEY environment variable must be set"),
39 )
40 .http_client(http_client)
41 .build();
42
43 let client = Client::builder(config)?.build();
44
45 println!("Sending chat completion request (retries are automatic)...");
47
48 let builder = client.chat_simple("Hello! How are you today?");
49 match client.send_chat(builder).await {
50 Ok(response) => {
51 println!("\nSuccess! Response received:");
52 if let Some(content) = response.content() {
53 println!("{content}");
54 }
55 }
56 Err(e) => {
57 eprintln!("\nError after retries: {e}");
58 }
59 }
60
61 println!("\n2. Creating client with custom retry policy");
63
64 let custom_retry_policy = ExponentialBackoff::builder()
65 .retry_bounds(
66 std::time::Duration::from_millis(100), std::time::Duration::from_secs(30), )
69 .build_with_max_retries(5); let custom_http_client = ClientBuilder::new(
72 reqwest::Client::builder()
73 .timeout(std::time::Duration::from_secs(60))
74 .build()
75 .expect("Failed to build reqwest client"),
76 )
77 .with(RetryTransientMiddleware::new_with_policy(
78 custom_retry_policy,
79 ))
80 .build();
81
82 let custom_config = Config::builder()
83 .api_key(
84 std::env::var("OPENAI_API_KEY")
85 .expect("OPENAI_API_KEY environment variable must be set"),
86 )
87 .http_client(custom_http_client)
88 .build();
89
90 let custom_client = Client::builder(custom_config)?.build();
91
92 println!("Sending request with custom retry policy (up to 5 retries)...");
93
94 let builder = custom_client.chat_simple("Explain quantum computing in one sentence.");
95 match custom_client.send_chat(builder).await {
96 Ok(response) => {
97 println!("\nSuccess! Response received:");
98 if let Some(content) = response.content() {
99 println!("{content}");
100 }
101 }
102 Err(e) => {
103 eprintln!("\nError after all retries: {e}");
104 }
105 }
106
107 println!("\n3. Using builder pattern with retry middleware");
109
110 let builder = custom_client
111 .responses()
112 .user("What are the three laws of robotics?")
113 .max_completion_tokens(200)
114 .temperature(0.7);
115
116 let response = custom_client.send_responses(builder).await?;
117
118 println!("\nResponse received:");
119 if let Some(content) = response.content() {
120 println!("{content}");
121 }
122
123 println!("\nToken usage:");
124 if let Some(usage) = response.usage() {
125 let prompt = usage.prompt_tokens;
126 let completion = usage.completion_tokens;
127 let total = usage.total_tokens;
128 println!(" Prompt tokens: {prompt}");
129 println!(" Completion tokens: {completion}");
130 println!(" Total tokens: {total}");
131 }
132
133 println!("\n=== Example completed successfully! ===");
134 println!("\nKey benefits of using reqwest-middleware:");
135 println!(" - Automatic retry of transient failures");
136 println!(" - Exponential backoff to avoid overwhelming servers");
137 println!(" - Composable middleware for logging, metrics, etc.");
138 println!(" - Transparent to application code - works with any request");
139
140 Ok(())
141}