@@ -13,9 +13,7 @@ seamlessly with httpx clients. You can configure retry behavior for any provider
1313To use the retry transports, you need to install the ` tenacity ` dependency:
1414
1515``` bash
16- pip install tenacity
17- # or if using uv
18- uv add tenacity
16+ pip/uv-add ' pydantic-ai-slim[tenacity]'
1917```
2018
2119## Usage Example
@@ -32,7 +30,7 @@ from tenacity import (
3230)
3331from pydantic_ai import Agent
3432from pydantic_ai.models.openai import OpenAIModel
35- from pydantic_ai.tenacity import AsyncTenacityTransport, wait_retry_after
33+ from pydantic_ai.retries import AsyncTenacityTransport, wait_retry_after
3634from pydantic_ai.providers.openai import OpenAIProvider
3735
3836def create_retrying_client ():
@@ -74,7 +72,7 @@ agent = Agent(model)
7472The ` wait_retry_after ` function is a smart wait strategy that automatically respects HTTP ` Retry-After ` headers:
7573
7674``` python {title="wait_strategy_example.py"}
77- from pydantic_ai.tenacity import wait_retry_after
75+ from pydantic_ai.retries import wait_retry_after
7876from tenacity import wait_exponential
7977
8078# Basic usage - respects Retry-After headers, falls back to exponential backoff
@@ -102,7 +100,7 @@ For asynchronous HTTP clients (recommended for most use cases):
102100``` python {title="async_transport_example.py"}
103101from httpx import AsyncClient
104102from tenacity import AsyncRetrying, stop_after_attempt
105- from pydantic_ai.tenacity import AsyncTenacityTransport
103+ from pydantic_ai.retries import AsyncTenacityTransport
106104
107105# Create the basic components
108106async_retrying = AsyncRetrying(stop = stop_after_attempt(3 ), reraise = True )
@@ -128,7 +126,7 @@ For synchronous HTTP clients:
128126``` python {title="sync_transport_example.py"}
129127from httpx import Client
130128from tenacity import Retrying, stop_after_attempt
131- from pydantic_ai.tenacity import TenacityTransport
129+ from pydantic_ai.retries import TenacityTransport
132130
133131# Create the basic components
134132retrying = Retrying(stop = stop_after_attempt(3 ), reraise = True )
@@ -154,7 +152,7 @@ client = Client(transport=transport)
154152``` python {title="rate_limit_handling.py"}
155153from httpx import AsyncClient, HTTPStatusError
156154from tenacity import AsyncRetrying, stop_after_attempt, retry_if_exception_type, wait_exponential
157- from pydantic_ai.tenacity import AsyncTenacityTransport, wait_retry_after
155+ from pydantic_ai.retries import AsyncTenacityTransport, wait_retry_after
158156
159157def create_rate_limit_client ():
160158 """ Create a client that respects Retry-After headers from rate limiting responses."""
@@ -184,7 +182,7 @@ The `wait_retry_after` function automatically detects `Retry-After` headers in 4
184182``` python {title="network_error_handling.py"}
185183import httpx
186184from tenacity import AsyncRetrying, retry_if_exception_type, wait_exponential, stop_after_attempt
187- from pydantic_ai.tenacity import AsyncTenacityTransport
185+ from pydantic_ai.retries import AsyncTenacityTransport
188186
189187def create_network_resilient_client ():
190188 """ Create a client that handles network errors with retries."""
@@ -212,7 +210,7 @@ client = create_network_resilient_client()
212210``` python {title="custom_retry_logic.py"}
213211import httpx
214212from tenacity import AsyncRetrying, wait_exponential, stop_after_attempt
215- from pydantic_ai.tenacity import AsyncTenacityTransport, wait_retry_after
213+ from pydantic_ai.retries import AsyncTenacityTransport, wait_retry_after
216214
217215def create_custom_retry_client ():
218216 """ Create a client with custom retry logic."""
@@ -249,30 +247,12 @@ The retry transports work with any provider that accepts a custom HTTP client:
249247
250248### OpenAI
251249
252- ``` python {title="openai_with_retries.py"}
253- from httpx import AsyncClient, HTTPStatusError
254- from tenacity import AsyncRetrying, stop_after_attempt, retry_if_exception_type
250+ ``` python {title="openai_with_retries.py" requires="smart_retry_example.py"}
255251from pydantic_ai import Agent
256252from pydantic_ai.models.openai import OpenAIModel
257253from pydantic_ai.providers.openai import OpenAIProvider
258- from pydantic_ai.tenacity import AsyncTenacityTransport, wait_retry_after
259254
260- def create_retrying_client ():
261- """ Create a client with retry functionality."""
262- def should_retry_status (response ):
263- if response.status_code in (429 , 502 , 503 , 504 ):
264- response.raise_for_status()
265-
266- transport = AsyncTenacityTransport(
267- controller = AsyncRetrying(
268- retry = retry_if_exception_type(HTTPStatusError),
269- wait = wait_retry_after(max_wait = 300 ),
270- stop = stop_after_attempt(5 ),
271- reraise = True
272- ),
273- validate_response = should_retry_status
274- )
275- return AsyncClient(transport = transport)
255+ from smart_retry_example import create_retrying_client
276256
277257client = create_retrying_client()
278258model = OpenAIModel(' gpt-4o' , provider = OpenAIProvider(http_client = client))
@@ -281,30 +261,12 @@ agent = Agent(model)
281261
282262### Anthropic
283263
284- ``` python {title="anthropic_with_retries.py"}
285- from httpx import AsyncClient, HTTPStatusError
286- from tenacity import AsyncRetrying, stop_after_attempt, retry_if_exception_type
264+ ``` python {title="anthropic_with_retries.py" requires="smart_retry_example.py"}
287265from pydantic_ai import Agent
288266from pydantic_ai.models.anthropic import AnthropicModel
289267from pydantic_ai.providers.anthropic import AnthropicProvider
290- from pydantic_ai.tenacity import AsyncTenacityTransport, wait_retry_after
291268
292- def create_retrying_client ():
293- """ Create a client with retry functionality."""
294- def should_retry_status (response ):
295- if response.status_code in (429 , 502 , 503 , 504 ):
296- response.raise_for_status()
297-
298- transport = AsyncTenacityTransport(
299- controller = AsyncRetrying(
300- retry = retry_if_exception_type(HTTPStatusError),
301- wait = wait_retry_after(max_wait = 300 ),
302- stop = stop_after_attempt(5 ),
303- reraise = True
304- ),
305- validate_response = should_retry_status
306- )
307- return AsyncClient(transport = transport)
269+ from smart_retry_example import create_retrying_client
308270
309271client = create_retrying_client()
310272model = AnthropicModel(' claude-3-5-sonnet-20241022' , provider = AnthropicProvider(http_client = client))
@@ -313,30 +275,12 @@ agent = Agent(model)
313275
314276### Any OpenAI-Compatible Provider
315277
316- ``` python {title="openai_compatible_with_retries.py"}
317- from httpx import AsyncClient, HTTPStatusError
318- from tenacity import AsyncRetrying, stop_after_attempt, retry_if_exception_type
278+ ``` python {title="openai_compatible_with_retries.py" requires="smart_retry_example.py"}
319279from pydantic_ai import Agent
320280from pydantic_ai.models.openai import OpenAIModel
321281from pydantic_ai.providers.openai import OpenAIProvider
322- from pydantic_ai.tenacity import AsyncTenacityTransport, wait_retry_after
323282
324- def create_retrying_client ():
325- """ Create a client with retry functionality."""
326- def should_retry_status (response ):
327- if response.status_code in (429 , 502 , 503 , 504 ):
328- response.raise_for_status()
329-
330- transport = AsyncTenacityTransport(
331- controller = AsyncRetrying(
332- retry = retry_if_exception_type(HTTPStatusError),
333- wait = wait_retry_after(max_wait = 300 ),
334- stop = stop_after_attempt(5 ),
335- reraise = True
336- ),
337- validate_response = should_retry_status
338- )
339- return AsyncClient(transport = transport)
283+ from smart_retry_example import create_retrying_client
340284
341285client = create_retrying_client()
342286model = OpenAIModel(
@@ -368,30 +312,12 @@ agent = Agent(model)
368312
369313The retry transports will re-raise the last exception if all retry attempts fail. Make sure to handle these appropriately in your application:
370314
371- ``` python {title="error_handling_example.py"}
372- from httpx import AsyncClient, HTTPStatusError
373- from tenacity import AsyncRetrying, stop_after_attempt, retry_if_exception_type
315+ ``` python {title="error_handling_example.py" requires="smart_retry_example.py"}
374316from pydantic_ai import Agent
375317from pydantic_ai.models.openai import OpenAIModel
376318from pydantic_ai.providers.openai import OpenAIProvider
377- from pydantic_ai.tenacity import AsyncTenacityTransport, wait_retry_after
378319
379- def create_retrying_client ():
380- """ Create a client with retry functionality."""
381- def should_retry_status (response ):
382- if response.status_code in (429 , 502 , 503 , 504 ):
383- response.raise_for_status()
384-
385- transport = AsyncTenacityTransport(
386- controller = AsyncRetrying(
387- retry = retry_if_exception_type(HTTPStatusError),
388- wait = wait_retry_after(max_wait = 300 ),
389- stop = stop_after_attempt(3 ), # Low for demonstration
390- reraise = True
391- ),
392- validate_response = should_retry_status
393- )
394- return AsyncClient(transport = transport)
320+ from smart_retry_example import create_retrying_client
395321
396322client = create_retrying_client()
397323model = OpenAIModel(' gpt-4o' , provider = OpenAIProvider(http_client = client))
0 commit comments