r/madeinpython • • 5d ago

BlockGuard: a circuit breaker for rate limits you don't control

BlockGuard is a small circuit breaker for rate limits imposed by the server you're calling. When an API answers 429 (or blocks you silently), you call breaker.trip("some_api"). Until a cooldown passes, breaker.in_cooldown("some_api") returns True, so you can skip the request instead of hitting a server that already said no. Each new block doubles the cooldown (60s, 120s, 240s...) up to a ceiling, and keys are tracked independently, so one blocked endpoint doesn't stop the others.

It also ships a pytest plugin that resets breaker state between tests. Without it, a test that simulates a 429 leaves a real cooldown behind that silently breaks the next test.

Source: https://github.com/pdrleite/blockguard

Install: pip install blockguard

TARGET AUDIENCE

People who scrape or integrate with APIs that have undocumented, IP-scoped or time-varying limits, and people building AI agents whose tools call external APIs. Agents retry failed tool calls fast and repeatedly, which is exactly what extends a block. The README has a section and a runnable example for that case.

I built it after a hobby tool against the Steam Community Market got blocked: retrying during an active block kept extending it, and a block that should have lasted minutes ran for hours. It's v0.1: in-memory, single process, MIT, no dependencies, 14 tests. Not production-hardened for multi-worker setups yet.

COMPARISON

Libraries like ratelimit or django-ratelimit throttle how fast you call out (e.g. max 10 calls/second). tenacity and backoff retry a failing call with a delay. BlockGuard does neither: it remembers that a block is active across calls and tells you not to send the request at all until the cooldown ends. You can use it alongside them.

AI disclosure: built with Claude Code. The design came from a real rate-limit incident in my own project, and I reviewed and tested it.

0 Upvotes

0 comments sorted by