or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.mdretry-strategies.md

index.mddocs/

0

# aiohttp-retry

1

2

A simple retry client for aiohttp that enables automatic retry functionality with various backoff strategies for HTTP requests. It offers configurable retry options including exponential backoff, random retry intervals, Fibonacci sequences, and custom timeout logic, with support for retrying on specific HTTP status codes, exceptions, or custom response evaluation callbacks.

3

4

## Package Information

5

6

- **Package Name**: aiohttp-retry

7

- **Package Type**: pypi

8

- **Language**: Python

9

- **Installation**: `pip install aiohttp-retry`

10

11

## Core Imports

12

13

```python

14

from aiohttp_retry import RetryClient, ExponentialRetry

15

```

16

17

Common imports for different retry strategies:

18

19

```python

20

from aiohttp_retry import (

21

RetryClient,

22

ExponentialRetry,

23

RandomRetry,

24

ListRetry,

25

FibonacciRetry,

26

JitterRetry,

27

RequestParams

28

)

29

```

30

31

Type imports:

32

33

```python

34

from aiohttp_retry.types import ClientType

35

```

36

37

## Basic Usage

38

39

```python

40

from aiohttp_retry import RetryClient, ExponentialRetry

41

42

async def main():

43

# Basic usage with default exponential retry

44

retry_client = RetryClient()

45

async with retry_client.get('https://httpbin.org/status/503') as response:

46

print(f"Status: {response.status}")

47

48

await retry_client.close()

49

50

# Using custom retry options

51

retry_options = ExponentialRetry(

52

attempts=5,

53

start_timeout=0.5,

54

max_timeout=10.0,

55

factor=2.0

56

)

57

58

async with RetryClient(retry_options=retry_options) as client:

59

async with client.get('https://httpbin.org/status/500') as response:

60

print(f"Status: {response.status}")

61

62

# Using with existing aiohttp ClientSession

63

from aiohttp import ClientSession

64

65

session = ClientSession()

66

retry_client = RetryClient(client_session=session)

67

68

response = await retry_client.get('https://httpbin.org/get')

69

print(f"Status: {response.status}")

70

71

await session.close()

72

```

73

74

## Architecture

75

76

aiohttp-retry is built around two core concepts:

77

78

- **RetryClient**: A wrapper around aiohttp's ClientSession that adds retry functionality

79

- **Retry Strategies**: Pluggable strategies that determine timeout intervals between retry attempts

80

81

The library maintains full compatibility with aiohttp's async/await patterns and provides comprehensive tracing capabilities for monitoring retry attempts and debugging network communication issues.

82

83

## Capabilities

84

85

### HTTP Client Operations

86

87

The main RetryClient class provides all standard HTTP methods with automatic retry functionality. It supports all HTTP verbs and maintains compatibility with aiohttp's ClientSession interface.

88

89

```python { .api }

90

class RetryClient:

91

def __init__(

92

self,

93

client_session: ClientSession | None = None,

94

logger: _LoggerType | None = None,

95

retry_options: RetryOptionsBase | None = None,

96

raise_for_status: bool = False,

97

*args: Any,

98

**kwargs: Any

99

): ...

100

101

def get(

102

self,

103

url: _URL_TYPE,

104

retry_options: RetryOptionsBase | None = None,

105

raise_for_status: bool | None = None,

106

**kwargs: Any

107

) -> _RequestContext: ...

108

109

def post(

110

self,

111

url: _URL_TYPE,

112

retry_options: RetryOptionsBase | None = None,

113

raise_for_status: bool | None = None,

114

**kwargs: Any

115

) -> _RequestContext: ...

116

117

def put(

118

self,

119

url: _URL_TYPE,

120

retry_options: RetryOptionsBase | None = None,

121

raise_for_status: bool | None = None,

122

**kwargs: Any

123

) -> _RequestContext: ...

124

125

def patch(

126

self,

127

url: _URL_TYPE,

128

retry_options: RetryOptionsBase | None = None,

129

raise_for_status: bool | None = None,

130

**kwargs: Any

131

) -> _RequestContext: ...

132

133

def delete(

134

self,

135

url: _URL_TYPE,

136

retry_options: RetryOptionsBase | None = None,

137

raise_for_status: bool | None = None,

138

**kwargs: Any

139

) -> _RequestContext: ...

140

141

def head(

142

self,

143

url: _URL_TYPE,

144

retry_options: RetryOptionsBase | None = None,

145

raise_for_status: bool | None = None,

146

**kwargs: Any

147

) -> _RequestContext: ...

148

149

def options(

150

self,

151

url: _URL_TYPE,

152

retry_options: RetryOptionsBase | None = None,

153

raise_for_status: bool | None = None,

154

**kwargs: Any

155

) -> _RequestContext: ...

156

157

def request(

158

self,

159

method: str,

160

url: StrOrURL,

161

retry_options: RetryOptionsBase | None = None,

162

raise_for_status: bool | None = None,

163

**kwargs: Any

164

) -> _RequestContext: ...

165

166

def requests(

167

self,

168

params_list: list[RequestParams],

169

retry_options: RetryOptionsBase | None = None,

170

raise_for_status: bool | None = None

171

) -> _RequestContext: ...

172

173

async def close(self) -> None: ...

174

175

async def __aenter__(self) -> RetryClient: ...

176

async def __aexit__(self, exc_type, exc_val, exc_tb) -> None: ...

177

178

@property

179

def retry_options(self) -> RetryOptionsBase: ...

180

```

181

182

### Multi-Request Configuration

183

184

Advanced request configuration that allows different parameters for each retry attempt, enabling dynamic URL switching, header modification, and parameter adjustment between attempts.

185

186

```python { .api }

187

from dataclasses import dataclass

188

189

@dataclass

190

class RequestParams:

191

method: str

192

url: _RAW_URL_TYPE

193

headers: dict[str, Any] | None = None

194

trace_request_ctx: dict[str, Any] | None = None

195

kwargs: dict[str, Any] | None = None

196

```

197

198

### Base Retry Strategy

199

200

Abstract base class that defines the interface for all retry strategies. Custom retry strategies can be implemented by inheriting from this class.

201

202

```python { .api }

203

class RetryOptionsBase:

204

def __init__(

205

self,

206

attempts: int = 3,

207

statuses: Iterable[int] | None = None,

208

exceptions: Iterable[type[Exception]] | None = None,

209

methods: Iterable[str] | None = None,

210

retry_all_server_errors: bool = True,

211

evaluate_response_callback: Callable[[ClientResponse], Awaitable[bool]] | None = None

212

): ...

213

214

def get_timeout(self, attempt: int, response: ClientResponse | None = None) -> float: ...

215

```

216

217

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

218

219

### Type Definitions

220

221

```python { .api }

222

from typing import Union, List, Tuple, Callable, Awaitable, Any, Iterable, Generator, Protocol

223

import logging

224

from aiohttp import ClientSession, ClientResponse

225

from aiohttp.typedefs import StrOrURL

226

from yarl import URL as YARL_URL

227

228

# Main client type alias

229

ClientType = Union[ClientSession, RetryClient]

230

231

# URL type definitions

232

_RAW_URL_TYPE = Union[StrOrURL, YARL_URL]

233

_URL_TYPE = Union[_RAW_URL_TYPE, List[_RAW_URL_TYPE], Tuple[_RAW_URL_TYPE, ...]]

234

235

# Logger protocol and type definition

236

class _Logger(Protocol):

237

"""Logger protocol defining required methods."""

238

def debug(self, msg: str, *args: Any, **kwargs: Any) -> None: ...

239

def warning(self, msg: str, *args: Any, **kwargs: Any) -> None: ...

240

def exception(self, msg: str, *args: Any, **kwargs: Any) -> None: ...

241

242

_LoggerType = Union[_Logger, logging.Logger]

243

244

# Callback type definitions

245

EvaluateResponseCallbackType = Callable[[ClientResponse], Awaitable[bool]]

246

RequestFunc = Callable[..., Awaitable[ClientResponse]]

247

248

# Internal request context type (returned by HTTP methods)

249

class _RequestContext:

250

"""

251

Internal request context that supports async context manager protocol.

252

Returned by all HTTP methods on RetryClient.

253

"""

254

def __await__(self) -> Generator[Any, None, ClientResponse]: ...

255

async def __aenter__(self) -> ClientResponse: ...

256

async def __aexit__(self, exc_type, exc_val, exc_tb) -> None: ...

257

```