or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

async-support.mdcallbacks-hooks.mdcore-decorator.mdindex.mdretry-strategies.mdstop-conditions.mdutilities.mdwait-strategies.md

index.mddocs/

0

# Tenacity - Comprehensive Python Retry Library

1

2

Tenacity is a robust Python library that provides decorators and utilities for adding sophisticated retry behavior to functions and code blocks. It offers flexible retry strategies, exponential backoff, customizable stop conditions, and extensive callback mechanisms for both synchronous and asynchronous code.

3

4

## Package Information

5

6

```bash

7

pip install tenacity

8

```

9

10

```python { .api }

11

import tenacity

12

from tenacity import retry, stop_after_attempt, wait_exponential

13

```

14

15

## Basic Usage

16

17

The simplest way to add retry behavior is with the `@retry` decorator:

18

19

```python { .api }

20

from tenacity import retry, stop_after_attempt, wait_fixed

21

22

@retry(stop=stop_after_attempt(3), wait=wait_fixed(1))

23

def unreliable_function():

24

"""Function that might fail but will be retried up to 3 times with 1 second between attempts."""

25

# Your code here

26

pass

27

```

28

29

## Architecture

30

31

Tenacity is built around a modular architecture with four core components:

32

33

### 1. Retry Controllers

34

- **`BaseRetrying`** - Abstract base class for all retry controllers

35

- **`Retrying`** - Standard synchronous retry controller

36

- **`AsyncRetrying`** - Asynchronous retry controller for coroutines

37

- **`TornadoRetrying`** - Tornado web framework integration

38

39

### 2. Retry Strategies

40

Determine when to retry based on exceptions or return values:

41

- Exception-based conditions (`retry_if_exception_type`, `retry_if_exception_message`)

42

- Result-based conditions (`retry_if_result`, `retry_if_not_result`)

43

- Logical combinations (`retry_any`, `retry_all`)

44

- Chain-of-causation support (`retry_if_exception_cause_type`)

45

46

### 3. Stop Conditions

47

Control when to stop retrying:

48

- Attempt-based (`stop_after_attempt`)

49

- Time-based (`stop_after_delay`, `stop_before_delay`)

50

- Event-based (`stop_when_event_set`)

51

- Logical combinations (`stop_any`, `stop_all`)

52

53

### 4. Wait Strategies

54

Define delays between retry attempts:

55

- Fixed delays (`wait_fixed`)

56

- Exponential backoff (`wait_exponential`, `wait_random_exponential`)

57

- Random delays (`wait_random`)

58

- Incremental delays (`wait_incrementing`)

59

- Strategy combinations (`wait_combine`, `wait_chain`)

60

61

## Core Type Definitions

62

63

```python { .api }

64

from typing import Any, Callable, Union, TypeVar, Optional

65

from datetime import timedelta

66

import threading

67

68

# Type aliases for time units

69

time_unit_type = Union[int, float, timedelta]

70

71

# Type variables for wrapped functions

72

WrappedFn = TypeVar('WrappedFn', bound=Callable[..., Any])

73

WrappedFnReturnT = TypeVar('WrappedFnReturnT')

74

75

# Base type aliases for strategy composition

76

RetryBaseT = Union['retry_base', Callable[['RetryCallState'], bool]]

77

StopBaseT = Union['stop_base', Callable[['RetryCallState'], bool]]

78

WaitBaseT = Union['wait_base', Callable[['RetryCallState'], Union[float, int]]]

79

80

# Core state management

81

class RetryCallState:

82

"""Tracks state of a retry session."""

83

start_time: float

84

retry_object: 'BaseRetrying'

85

fn: Callable[..., Any]

86

args: tuple

87

kwargs: dict

88

attempt_number: int

89

outcome: 'Future'

90

outcome_timestamp: Optional[float]

91

idle_for: float

92

next_action: Optional['BaseAction']

93

upcoming_sleep: float

94

seconds_since_start: float

95

96

class Future:

97

"""Container for attempt results."""

98

attempt_number: int

99

failed: bool

100

101

@classmethod

102

def construct(cls, attempt_number: int, value: Any, has_exception: bool) -> 'Future'

103

104

# Exception classes

105

class TryAgain(Exception):

106

"""Raise to force immediate retry regardless of retry condition."""

107

pass

108

109

class RetryError(Exception):

110

"""Raised when all retry attempts are exhausted."""

111

last_attempt: Future

112

113

def reraise(self) -> None:

114

"""Reraise the original exception from the last attempt."""

115

```

116

117

## Main Decorator

118

119

```python { .api }

120

def retry(

121

sleep: Callable[[float], None] = sleep,

122

stop: StopBaseT = stop_never,

123

wait: WaitBaseT = wait_none(),

124

retry: RetryBaseT = retry_if_exception_type(),

125

before: Callable[[RetryCallState], None] = before_nothing,

126

after: Callable[[RetryCallState], None] = after_nothing,

127

before_sleep: Optional[Callable[[RetryCallState], None]] = None,

128

reraise: bool = False,

129

retry_error_cls: type = RetryError,

130

retry_error_callback: Optional[Callable[[RetryCallState], Any]] = None

131

) -> Callable[[WrappedFn], WrappedFn]:

132

"""

133

Main decorator to add retry behavior to functions.

134

135

Auto-detects async/tornado functions and applies appropriate retry controller.

136

137

Parameters:

138

- sleep: Function to use for sleeping between retries

139

- stop: Strategy determining when to stop retrying

140

- wait: Strategy determining how long to wait between retries

141

- retry: Strategy determining whether to retry after a failure

142

- before: Callback executed before each attempt

143

- after: Callback executed after each attempt

144

- before_sleep: Callback executed before sleeping between retries

145

- reraise: If True, reraise original exception instead of RetryError

146

- retry_error_cls: Exception class to raise when retries are exhausted

147

- retry_error_callback: Callback executed when retries are exhausted

148

"""

149

```

150

151

## Core Capability Areas

152

153

### [Core Decorator & Classes](./core-decorator.md)

154

Complete coverage of the `@retry` decorator, `Retrying`, `AsyncRetrying`, `TornadoRetrying` classes, and state management components like `RetryCallState` and `Future`.

155

156

### [Retry Strategies](./retry-strategies.md)

157

All 14+ retry conditions including exception-based (`retry_if_exception_type`), result-based (`retry_if_result`), message-based (`retry_if_exception_message`), and logical combinations (`retry_any`, `retry_all`).

158

159

### [Stop Conditions](./stop-conditions.md)

160

Complete coverage of 7+ stop strategies including attempt limits (`stop_after_attempt`), time limits (`stop_after_delay`, `stop_before_delay`), event-based stopping, and logical combinations.

161

162

### [Wait Strategies](./wait-strategies.md)

163

All 9+ wait/backoff strategies including fixed delays, exponential backoff with jitter, random delays, incremental delays, and strategy composition methods.

164

165

### [Async Support](./async-support.md)

166

Comprehensive async/await support with `AsyncRetrying`, async retry strategies, and integration with asyncio, trio, and other async frameworks.

167

168

### [Callbacks & Hooks](./callbacks-hooks.md)

169

Complete callback system including before/after attempt hooks, before sleep callbacks, logging utilities, and custom callback creation.

170

171

### [Utilities & Helpers](./utilities.md)

172

Utility functions, sleep strategies, time conversion helpers, and other supporting functionality for advanced retry scenarios.

173

174

## Key Features

175

176

- **Flexible Retry Logic**: 14+ retry strategies based on exceptions, return values, or custom conditions

177

- **Sophisticated Timing**: 9+ wait strategies with exponential backoff, jitter, and custom timing

178

- **Async/Await Support**: Native support for coroutines with `AsyncRetrying`

179

- **Framework Integration**: Tornado web framework support via `TornadoRetrying`

180

- **Comprehensive Callbacks**: Before/after/sleep hooks for logging and custom actions

181

- **Logical Composition**: Combine strategies with AND/OR logic

182

- **Type Safety**: Full type annotations and generic support

183

- **Thread Safety**: Built-in threading support with event-based coordination

184

- **Extensive Configuration**: 20+ parameters for fine-tuned retry behavior

185

186

## Common Patterns

187

188

```python { .api }

189

# Exponential backoff with jitter for API calls

190

@retry(

191

stop=stop_after_attempt(5),

192

wait=wait_random_exponential(min=1, max=60),

193

retry=retry_if_exception_type((ConnectionError, TimeoutError))

194

)

195

def call_external_api():

196

pass

197

198

# Database connection with custom retry logic

199

@retry(

200

stop=stop_after_delay(30),

201

wait=wait_exponential(multiplier=1, min=4, max=10),

202

retry=retry_if_exception_type(ConnectionError),

203

before_sleep=before_sleep_log(logger, logging.WARNING)

204

)

205

def connect_to_database():

206

pass

207

208

# Async function with comprehensive retry

209

@retry(

210

stop=stop_any(stop_after_attempt(5), stop_after_delay(60)),

211

wait=wait_combine(wait_fixed(3), wait_random(0, 2)),

212

retry=retry_if_not_result(lambda x: x is not None)

213

)

214

async def fetch_data():

215

pass

216

```

217

218

This documentation provides complete coverage of tenacity's 95+ public API elements, enabling robust retry behavior for any Python application.