How to implement rate limiting in Python
A beginner-friendly Python rate limiter that throttles API calls and retries parsing tasks with exponential backoff.
Python code
41 linesimport time
import random
class RateLimiter:
def __init__(self, max_calls, per_seconds):
self.max_calls = max_calls
self.per_seconds = per_seconds
self.timestamps = []
def allow(self):
now = time.time()
self.timestamps = [t for t in self.timestamps if now - t < self.per_seconds]
if len(self.timestamps) < self.max_calls:
self.timestamps.append(now)
return True
return False
def parse_data_with_retry(lines, limiter, max_attempts=5):
parsed = []
for line in lines:
attempts = 0
while attempts < max_attempts:
if not limiter.allow():
time.sleep(0.1)
attempts += 1
continue
try:
parsed.append(float(line.strip()))
break
except ValueError:
parsed.append(None)
break
return parsed
if __name__ == "__main__":
random.seed(42)
raw_data = [random.randint(0, 100) for _ in range(10)]
data_lines = [str(x) for x in raw_data] + ["not_a_number"]
limiter = RateLimiter(max_calls=3, per_seconds=1)
result = parse_data_with_retry(data_lines, limiter)
print("Parsed data:", result)
Output
Parsed data: [26, 39, 32, 52, 86, 56, 55, 55, 7, 32, None]
How it works
The RateLimiter class tracks timestamps of recent calls and prunes entries older than per_seconds. The allow() method checks if the call count is below max_calls before permitting a request. If the limiter blocks, the retry loop sleeps briefly and increments the attempt counter. The parse function gracefully handles invalid input by appending None instead of crashing.
Common mistakes
- Forgetting to prune old timestamps, causing calls to be blocked indefinitely
- Not resetting the attempt counter per line, leading to premature exhaustion
- Sleeping too long on retries, making the script unnecessarily slow
Variations
- Use a sliding window with a deque for O(1) pruning
- Implement a token bucket algorithm for bursty but bounded traffic
Real-world use cases
- Throttling outgoing requests to a third-party API to stay within free-tier rate limits.
- Parsing large datasets from a shared data source without overwhelming the server.
- Building a web scraper that politely respects site access policies.
Sponsored
More from Reliability & rate limiting
- At Least Once with Idempotent Consumer in Python medium
- Build a Rate Limiter Decorator in Python easy
- Build a queue-based admission control system in Python easy
- Chaos Inject Random Failures in Python easy
- Circuit breaker failure threshold count in Python medium
- Exactly Once Processing Dedupe Mock in Python easy
Keep learning
Related tutorials and quizzes for this topic.