or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

async.mdindex.mdrate-limit-items.mdstorage.mdstrategies.mdutilities.md

index.mddocs/

0

# Limits

1

2

A comprehensive Python library for implementing rate limiting functionality across various storage backends. Limits provides multiple rate limiting strategies including Fixed Window, Moving Window, and Sliding Window Counter algorithms, each with different memory efficiency and accuracy trade-offs.

3

4

## Package Information

5

6

- **Package Name**: limits

7

- **Language**: Python

8

- **Installation**: `pip install limits`

9

- **Repository**: https://github.com/alisaifee/limits

10

- **Documentation**: https://limits.readthedocs.io/

11

12

## Core Imports

13

14

```python

15

import limits

16

```

17

18

Common imports for rate limiting:

19

20

```python

21

from limits import RateLimitItem, parse

22

from limits.storage import storage_from_string

23

from limits.strategies import FixedWindowRateLimiter

24

```

25

26

For asynchronous usage:

27

28

```python

29

from limits.aio.strategies import FixedWindowRateLimiter as AsyncFixedWindowRateLimiter

30

from limits.storage import storage_from_string # Same function, use "async+" prefix

31

```

32

33

## Basic Usage

34

35

```python

36

from limits import RateLimitItemPerMinute, parse

37

from limits.storage import storage_from_string

38

from limits.strategies import FixedWindowRateLimiter

39

40

# Create rate limit items

41

rate_limit = RateLimitItemPerMinute(10) # 10 requests per minute

42

# Or parse from string

43

rate_limit = parse("10/minute")

44

45

# Set up storage backend

46

storage = storage_from_string("memory://")

47

# Or use Redis

48

# storage = storage_from_string("redis://localhost:6379")

49

50

# Create rate limiter with chosen strategy

51

limiter = FixedWindowRateLimiter(storage)

52

53

# Apply rate limiting

54

user_id = "user123"

55

if limiter.test(rate_limit, user_id):

56

# Request allowed

57

limiter.hit(rate_limit, user_id)

58

print("Request processed")

59

else:

60

print("Rate limit exceeded")

61

62

# Check remaining quota

63

stats = limiter.get_window_stats(rate_limit, user_id)

64

print(f"Remaining: {stats.remaining}, Reset at: {stats.reset_time}")

65

```

66

67

## Architecture

68

69

The limits library follows a modular architecture with three core components:

70

71

- **Rate Limit Items**: Define the rate limit parameters (amount, time window, granularity)

72

- **Storage Backends**: Handle persistence and distribution of rate limit counters across different storage systems

73

- **Rate Limiting Strategies**: Implement different algorithms for rate limit enforcement

74

75

This design enables flexible combinations of time windows, storage backends, and algorithmic strategies based on specific requirements for accuracy, memory efficiency, and distribution needs.

76

77

## Capabilities

78

79

### Rate Limit Items

80

81

Core classes for defining rate limits with different time granularities, supporting custom namespaces and time multipliers for flexible rate limiting configurations.

82

83

```python { .api }

84

class RateLimitItem:

85

def __init__(self, amount: int, multiples: int | None = 1, namespace: str = "LIMITER"): ...

86

def get_expiry(self) -> int: ...

87

def key_for(self, *identifiers: str | int | float | bytes) -> str: ...

88

89

class RateLimitItemPerSecond(RateLimitItem): ...

90

class RateLimitItemPerMinute(RateLimitItem): ...

91

class RateLimitItemPerHour(RateLimitItem): ...

92

class RateLimitItemPerDay(RateLimitItem): ...

93

class RateLimitItemPerMonth(RateLimitItem): ...

94

class RateLimitItemPerYear(RateLimitItem): ...

95

```

96

97

[Rate Limit Items](./rate-limit-items.md)

98

99

### Rate Limiting Strategies

100

101

Different algorithmic approaches for enforcing rate limits, each with distinct characteristics for accuracy, memory usage, and computational efficiency.

102

103

```python { .api }

104

class FixedWindowRateLimiter:

105

def __init__(self, storage: Storage): ...

106

def hit(self, item: RateLimitItem, *identifiers: str, cost: int = 1) -> bool: ...

107

def test(self, item: RateLimitItem, *identifiers: str, cost: int = 1) -> bool: ...

108

def get_window_stats(self, item: RateLimitItem, *identifiers: str) -> WindowStats: ...

109

110

class MovingWindowRateLimiter:

111

def __init__(self, storage: Storage): ...

112

def hit(self, item: RateLimitItem, *identifiers: str, cost: int = 1) -> bool: ...

113

def test(self, item: RateLimitItem, *identifiers: str, cost: int = 1) -> bool: ...

114

def get_window_stats(self, item: RateLimitItem, *identifiers: str) -> WindowStats: ...

115

116

class SlidingWindowCounterRateLimiter:

117

def __init__(self, storage: Storage): ...

118

def hit(self, item: RateLimitItem, *identifiers: str, cost: int = 1) -> bool: ...

119

def test(self, item: RateLimitItem, *identifiers: str, cost: int = 1) -> bool: ...

120

def get_window_stats(self, item: RateLimitItem, *identifiers: str) -> WindowStats: ...

121

```

122

123

[Rate Limiting Strategies](./strategies.md)

124

125

### Storage Backends

126

127

Multiple storage implementations supporting both local and distributed rate limiting with various backends including in-memory, Redis, Memcached, MongoDB, and etcd.

128

129

```python { .api }

130

def storage_from_string(storage_string: str, **options: float | str | bool) -> Storage: ...

131

132

class MemoryStorage(Storage): ...

133

class RedisStorage(Storage): ...

134

class RedisClusterStorage(Storage): ...

135

class RedisSentinelStorage(Storage): ...

136

class MemcachedStorage(Storage): ...

137

class MongoDBStorage(Storage): ...

138

class EtcdStorage(Storage): ...

139

```

140

141

[Storage Backends](./storage.md)

142

143

### Asynchronous Support

144

145

Complete async/await API providing the same functionality as the synchronous API but optimized for asynchronous applications and frameworks.

146

147

```python { .api }

148

# Async strategies mirror sync API but with async methods

149

class FixedWindowRateLimiter:

150

def __init__(self, storage: Storage): ...

151

async def hit(self, item: RateLimitItem, *identifiers: str, cost: int = 1) -> bool: ...

152

async def test(self, item: RateLimitItem, *identifiers: str, cost: int = 1) -> bool: ...

153

async def get_window_stats(self, item: RateLimitItem, *identifiers: str) -> WindowStats: ...

154

155

# Async storage backends with same interface as sync versions

156

class RedisStorage(Storage): ...

157

class MemoryStorage(Storage): ...

158

```

159

160

[Asynchronous API](./async.md)

161

162

### Utilities and Parsing

163

164

Helper functions for parsing rate limit strings, managing window statistics, and handling dependencies for different storage backends.

165

166

```python { .api }

167

def parse(limit_string: str) -> RateLimitItem: ...

168

def parse_many(limit_string: str) -> list[RateLimitItem]: ...

169

170

class WindowStats:

171

reset_time: float

172

remaining: int

173

```

174

175

[Utilities](./utilities.md)

176

177

## Types

178

179

Core type definitions used throughout the library:

180

181

```python { .api }

182

from typing import NamedTuple

183

184

class WindowStats(NamedTuple):

185

"""Statistics for a rate limit window"""

186

reset_time: float # Time when window resets (seconds since epoch)

187

remaining: int # Remaining quota in current window

188

189

class Granularity(NamedTuple):

190

"""Time granularity definition"""

191

seconds: int # Duration in seconds

192

name: str # Granularity name (second, minute, hour, etc.)

193

```

194

195

## Error Handling

196

197

The library defines several exception types for different error scenarios. These must be imported from `limits.errors`:

198

199

```python

200

from limits.errors import ConfigurationError, ConcurrentUpdateError, StorageError

201

```

202

203

```python { .api }

204

class ConfigurationError(Exception):

205

"""Raised when configuration problem is encountered"""

206

207

class ConcurrentUpdateError(Exception):

208

"""Raised when update fails due to concurrent updates"""

209

def __init__(self, key: str, attempts: int):

210

"""

211

Args:

212

key: The key that failed to update

213

attempts: Number of attempts made before giving up

214

"""

215

216

class StorageError(Exception):

217

"""Raised when error is encountered in storage backend"""

218

def __init__(self, storage_error: Exception):

219

"""

220

Args:

221

storage_error: The underlying storage exception that occurred

222

"""

223

storage_error: Exception # The original exception that was wrapped

224

```