or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-limiting.mdfactory-patterns.mdindex.mdrate-configuration.mdstorage-backends.mdtime-sources.md

index.mddocs/

0

# PyrateLimiter

1

2

A comprehensive Python rate-limiting library implementing the Leaky Bucket algorithm for controlling request rates in applications. PyrateLimiter supports unlimited rate limits with custom intervals, separately tracks limits for different services or resources, and manages limit breaches through configurable exception raising or delay mechanisms.

3

4

The library offers both synchronous and asynchronous workflows with multiple backend options including in-memory, Redis, SQLite, and PostgreSQL storage for persistent rate limiting across threads, processes, or application restarts. Key features include decorator support for easy function wrapping, multiprocessing compatibility, weight-based item consumption, and extensible architecture allowing custom bucket implementations.

5

6

## Package Information

7

8

- **Package Name**: pyrate-limiter

9

- **Language**: Python

10

- **Installation**: `pip install pyrate-limiter`

11

- **Version**: 3.9.0

12

- **License**: MIT

13

14

## Core Imports

15

16

```python

17

import pyrate_limiter

18

```

19

20

Common usage imports:

21

22

```python

23

from pyrate_limiter import Limiter, Rate, Duration, BucketFullException

24

from pyrate_limiter import InMemoryBucket, SQLiteBucket, RedisBucket

25

```

26

27

## Basic Usage

28

29

```python

30

from pyrate_limiter import Limiter, Rate, Duration

31

32

# Create a limiter: 5 requests per second

33

limiter = Limiter(Rate(5, Duration.SECOND))

34

35

# Try to acquire permission for a request

36

if limiter.try_acquire("user123"):

37

print("Request allowed")

38

else:

39

print("Rate limit exceeded")

40

41

# Using with context manager

42

with Limiter(Rate(10, Duration.MINUTE)) as limiter:

43

success = limiter.try_acquire("api_call", weight=2)

44

45

# Using as decorator

46

@limiter.as_decorator()

47

def rate_limited_function(user_id):

48

return (user_id, 1) # (name, weight) for rate limiting

49

50

@rate_limited_function

51

def api_call(user_id):

52

return f"Processing request for {user_id}"

53

```

54

55

## Architecture

56

57

PyrateLimiter uses a modular architecture based on three core abstractions:

58

59

- **Rate**: Defines rate limit rules (limit/interval pairs)

60

- **Bucket**: Storage backend for tracking rate limit state (in-memory, SQLite, Redis, PostgreSQL)

61

- **Clock**: Time source for rate calculations (system time, monotonic, remote database time)

62

- **Limiter**: Orchestrates rate limiting logic using buckets and clocks

63

64

This design enables flexible deployment scenarios from simple in-process rate limiting to distributed systems with shared state across multiple application instances.

65

66

## Capabilities

67

68

### Core Rate Limiting

69

70

The main Limiter class provides the primary rate limiting functionality with support for both synchronous and asynchronous operations, configurable delays, and exception handling.

71

72

```python { .api }

73

class Limiter:

74

def __init__(

75

self,

76

argument: Union[BucketFactory, AbstractBucket, Rate, List[Rate]],

77

clock: Optional[AbstractClock] = None,

78

raise_when_fail: bool = True,

79

max_delay: Optional[Union[int, Duration]] = None,

80

retry_until_max_delay: bool = False,

81

buffer_ms: int = 50

82

): ...

83

84

def try_acquire(self, name: str, weight: int = 1) -> Union[bool, Awaitable[bool]]: ...

85

86

async def try_acquire_async(self, name: str, weight: int = 1) -> bool: ...

87

88

def as_decorator(self) -> Callable[[ItemMapping], DecoratorWrapper]: ...

89

```

90

91

[Core Rate Limiting](./core-limiting.md)

92

93

### Storage Backends

94

95

Multiple storage backends for persisting rate limit state across application restarts, processes, and distributed deployments.

96

97

```python { .api }

98

class InMemoryBucket(AbstractBucket):

99

def __init__(self, rates: List[Rate]): ...

100

101

class SQLiteBucket(AbstractBucket):

102

def __init__(self, rates: List[Rate], conn: sqlite3.Connection, table: str, lock: Optional[RLock] = None): ...

103

104

@classmethod

105

def init_from_file(

106

cls, rates: List[Rate], db_path: str, table: str = "pyrate_limiter",

107

create_new_table: bool = False, use_file_lock: bool = False

108

) -> "SQLiteBucket": ...

109

110

class RedisBucket(AbstractBucket):

111

def __init__(self, rates: List[Rate], redis: Union[Redis, AsyncRedis], bucket_key: Optional[str] = None): ...

112

```

113

114

[Storage Backends](./storage-backends.md)

115

116

### Rate Configuration

117

118

Rate definition and duration utilities for configuring rate limits with flexible time intervals and validation.

119

120

```python { .api }

121

class Rate:

122

def __init__(self, limit: int, interval: Union[int, Duration]): ...

123

124

class Duration(Enum):

125

SECOND = 1000

126

MINUTE = 60000

127

HOUR = 3600000

128

DAY = 86400000

129

WEEK = 604800000

130

```

131

132

[Rate Configuration](./rate-configuration.md)

133

134

### Factory Patterns

135

136

Pre-configured factory functions and patterns for common use cases including multiprocessing support and simplified bucket creation.

137

138

```python { .api }

139

def create_limiter(

140

rate_per_duration: int = 3,

141

duration: Union[int, Duration] = Duration.SECOND,

142

clock: Optional[AbstractClock] = None,

143

**limiter_kwargs

144

) -> Limiter: ...

145

146

def create_sqlite_limiter(

147

rate_per_duration: int = 3,

148

duration: Union[int, Duration] = Duration.SECOND,

149

db_path: Optional[str] = None,

150

**kwargs

151

) -> Limiter: ...

152

```

153

154

[Factory Patterns](./factory-patterns.md)

155

156

### Time Sources

157

158

Different clock implementations for various deployment scenarios including local system time, monotonic time, and remote database-backed time sources.

159

160

```python { .api }

161

class TimeClock(AbstractClock):

162

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

163

164

class MonotonicClock(AbstractClock):

165

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

166

167

class SQLiteClock(AbstractClock):

168

def __init__(self, conn: Union[sqlite3.Connection, SQLiteBucket]): ...

169

```

170

171

[Time Sources](./time-sources.md)

172

173

## Exception Handling

174

175

```python { .api }

176

class BucketFullException(Exception):

177

def __init__(self, item: RateItem, rate: Rate): ...

178

item: RateItem

179

rate: Rate

180

meta_info: Dict[str, Union[str, float]]

181

182

class LimiterDelayException(Exception):

183

def __init__(self, item: RateItem, rate: Rate, actual_delay: int, max_delay: int): ...

184

item: RateItem

185

rate: Rate

186

actual_delay: int

187

max_delay: int

188

meta_info: Dict[str, Union[str, float]]

189

```

190

191

## Utility Functions

192

193

Utility functions for rate limiting operations and validation.

194

195

```python { .api }

196

def binary_search(items: List[RateItem], value: int) -> int:

197

"""

198

Find the index of item in list where left.timestamp < value <= right.timestamp.

199

200

Used internally to determine current size of time windows for rate calculations.

201

202

Parameters:

203

- items: List of RateItem objects sorted by timestamp

204

- value: Timestamp value to search for

205

206

Returns:

207

- int: Index position for the timestamp boundary

208

"""

209

210

def validate_rate_list(rates: List[Rate]) -> bool:

211

"""

212

Validate that rates are correctly ordered for rate limiting.

213

214

Parameters:

215

- rates: List of Rate objects to validate

216

217

Returns:

218

- bool: True if rates are valid, False otherwise

219

220

Validation rules:

221

- Rates must be ordered by increasing interval

222

- Rates must be ordered by increasing limit

223

- Rate density (limit/interval) must be decreasing

224

"""

225

226

def id_generator(size: int = 6, chars: str = ...) -> str:

227

"""

228

Generate random string identifier.

229

230

Parameters:

231

- size: Length of generated string (default: 6)

232

- chars: Character set to use (default: alphanumeric)

233

234

Returns:

235

- str: Random string identifier

236

"""

237

238

def dedicated_sqlite_clock_connection() -> sqlite3.Connection:

239

"""

240

Create dedicated SQLite connection for clock operations.

241

242

Returns:

243

- sqlite3.Connection: Configured SQLite connection for time queries

244

245

Features:

246

- Uses temporary database file

247

- Configured for EXCLUSIVE isolation

248

- Thread-safe with check_same_thread=False

249

"""

250

```

251

252

## Core Types

253

254

```python { .api }

255

class RateItem:

256

def __init__(self, name: str, timestamp: int, weight: int = 1): ...

257

name: str

258

weight: int

259

timestamp: int

260

261

ItemMapping = Callable[[Any], Tuple[str, int]]

262

DecoratorWrapper = Callable[[Callable[[Any], Any]], Callable[[Any], Any]]

263

```