or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

tessl/pypi-ratelimit

API rate limit decorator for preventing function calls from exceeding specified frequency limits

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
pypipkg:pypi/ratelimit@2.2.x

To install, run

npx @tessl/cli install tessl/pypi-ratelimit@2.2.0

0

# Ratelimit

1

2

A Python decorator library for implementing API rate limiting functionality that prevents functions from being called more frequently than specified limits. It provides a clean, decorator-based approach to enforce rate limits on function calls, helping developers avoid hitting API rate limits that could result in service bans.

3

4

## Package Information

5

6

- **Package Name**: ratelimit

7

- **Package Type**: pypi

8

- **Language**: Python

9

- **Version**: 2.2.1

10

- **Installation**: `pip install ratelimit`

11

12

## Core Imports

13

14

```python

15

from ratelimit import limits, RateLimitException, sleep_and_retry

16

```

17

18

Alternative imports:

19

20

```python

21

# Using backwards-compatible alias

22

from ratelimit import rate_limited, RateLimitException, sleep_and_retry

23

24

# Package-level import

25

import ratelimit

26

# Access via: ratelimit.limits, ratelimit.RateLimitException, etc.

27

```

28

29

## Basic Usage

30

31

```python

32

from ratelimit import limits, RateLimitException, sleep_and_retry

33

import requests

34

35

# Basic rate limiting

36

FIFTEEN_MINUTES = 900

37

38

@limits(calls=15, period=FIFTEEN_MINUTES)

39

def call_api(url):

40

response = requests.get(url)

41

if response.status_code != 200:

42

raise Exception('API response: {}'.format(response.status_code))

43

return response

44

45

# With exception handling

46

try:

47

result = call_api('https://api.example.com/data')

48

except RateLimitException as e:

49

print(f"Rate limit exceeded. Wait {e.period_remaining} seconds")

50

51

# Automatic retry on rate limit

52

@sleep_and_retry

53

@limits(calls=15, period=FIFTEEN_MINUTES)

54

def call_api_with_retry(url):

55

response = requests.get(url)

56

if response.status_code != 200:

57

raise Exception('API response: {}'.format(response.status_code))

58

return response

59

```

60

61

## Capabilities

62

63

### Rate Limiting Decorator

64

65

Prevents functions from being called more frequently than specified limits. The main decorator that enforces rate limits on function calls.

66

67

```python { .api }

68

class RateLimitDecorator(object):

69

def __init__(self, calls=15, period=900, clock=now, raise_on_limit=True):

70

"""

71

Rate limit decorator class. Available as 'limits' and 'rate_limited' aliases.

72

73

Parameters:

74

- calls (int): Maximum function invocations allowed within time period. Must be >= 1. Default: 15

75

- period (float): Time period in seconds before rate limit resets. Must be > 0. Default: 900 (15 minutes)

76

- clock (callable): Function returning current time as float. Default: time.monotonic or time.time

77

- raise_on_limit (bool): Whether to raise RateLimitException when limit exceeded. Default: True

78

"""

79

80

# Main alias (recommended)

81

limits = RateLimitDecorator

82

83

# Backwards compatibility alias

84

rate_limited = RateLimitDecorator

85

```

86

87

### Automatic Retry Decorator

88

89

Wraps rate-limited functions to automatically sleep and retry when rate limits are exceeded, ensuring every function call eventually succeeds.

90

91

```python { .api }

92

def sleep_and_retry(func):

93

"""

94

Decorator that rescues rate limit exceptions by sleeping until the rate limit resets.

95

96

Parameters:

97

- func (callable): The function to decorate

98

99

Returns:

100

- callable: Decorated function that automatically retries on rate limit

101

"""

102

```

103

104

### Rate Limit Exception

105

106

Custom exception raised when the number of function invocations exceeds the imposed rate limit. Contains information about the remaining time until the rate limit resets.

107

108

```python { .api }

109

class RateLimitException(Exception):

110

def __init__(self, message, period_remaining):

111

"""

112

Exception raised when rate limits are exceeded.

113

114

Parameters:

115

- message (str): Exception message

116

- period_remaining (float): Time remaining until rate limit resets

117

118

Attributes:

119

- period_remaining (float): Time in seconds until rate limit resets

120

"""

121

```

122

123

### Package Version

124

125

Package version constant.

126

127

```python { .api }

128

__version__ = "2.2.1"

129

```

130

131

## Implementation Details

132

133

```python { .api }

134

# Internal clock function used by the library (not exported)

135

# Uses monotonic time if available, otherwise falls back to system clock

136

now = time.monotonic if hasattr(time, 'monotonic') else time.time

137

```

138

139

## Usage Examples

140

141

### Custom Clock for Testing

142

143

```python

144

from ratelimit import limits

145

import time

146

147

class TestClock:

148

def __init__(self):

149

self.time = 0

150

151

def __call__(self):

152

return self.time

153

154

def advance(self, seconds):

155

self.time += seconds

156

157

clock = TestClock()

158

159

@limits(calls=2, period=10, clock=clock)

160

def test_function():

161

return "success"

162

163

# Function can be called twice

164

test_function() # Success

165

test_function() # Success

166

167

# Third call raises exception

168

try:

169

test_function() # RateLimitException

170

except RateLimitException:

171

print("Rate limit exceeded")

172

173

# Advance clock and try again

174

clock.advance(10)

175

test_function() # Success again

176

```

177

178

### Non-Exception Mode

179

180

```python

181

from ratelimit import limits

182

183

@limits(calls=1, period=60, raise_on_limit=False)

184

def api_call():

185

print("API called")

186

return "data"

187

188

# First call succeeds

189

result = api_call() # Prints "API called", returns "data"

190

191

# Second call silently skips execution

192

result = api_call() # Returns None, no print statement

193

```

194

195

### Integration with Exponential Backoff

196

197

```python

198

from ratelimit import limits, RateLimitException, sleep_and_retry

199

from backoff import on_exception, expo

200

201

@on_exception(expo, RateLimitException, max_tries=8)

202

@limits(calls=15, period=900)

203

def api_call_with_backoff(url):

204

# Your API call implementation

205

pass

206

207

# Alternative using sleep_and_retry (simpler but less flexible)

208

@sleep_and_retry

209

@limits(calls=15, period=900)

210

def api_call_simple_retry(url):

211

# Your API call implementation

212

pass

213

```

214

215

## Thread Safety

216

217

All decorators are thread-safe using `threading.RLock()`. Each decorated function maintains its own independent rate limit state, allowing multiple rate-limited functions to operate concurrently without interference.

218

219

## Error Handling

220

221

The package raises `RateLimitException` when rate limits are exceeded (unless `raise_on_limit=False`). This exception contains:

222

223

- Standard exception message

224

- `period_remaining` attribute: float indicating seconds until rate limit resets

225

226

Common error handling patterns:

227

228

```python

229

import time

230

from ratelimit import limits, RateLimitException

231

232

@limits(calls=1, period=60)

233

def rate_limited_function():

234

return "success"

235

236

# Manual retry with exponential backoff

237

max_retries = 3

238

for attempt in range(max_retries):

239

try:

240

result = rate_limited_function()

241

break

242

except RateLimitException as e:

243

if attempt == max_retries - 1:

244

raise

245

wait_time = min(e.period_remaining * (2 ** attempt), 300) # Cap at 5 minutes

246

time.sleep(wait_time)

247

```