Skip to content

mohosy/flowguard

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Flowguard

python tests license

Token bucket and sliding window rate limiters built with clean, testable primitives. Flowguard shows how to design thread-safe throttling with pluggable time sources, a decorator middleware layer, and a deterministic simulation harness.

Why this impresses FAANG recruiters

  • Demonstrates systems thinking with two canonical algorithms implemented from scratch (no dependencies).
  • Thread-safe design and deterministic time abstraction for reproducible tests.
  • Professional project hygiene: typed API, CI workflow, unit tests, and CLI demo.
  • Clean architecture: core strategies, middleware decorator, utility time providers, and a separate simulation surface.

Project layout

  • flowguard/limits/: reusable limiter primitives (TokenBucket, SlidingWindow, Decision).
  • flowguard/utils/time_provider.py: injectable clocks (MonotonicTime, ManualTime) for determinism.
  • flowguard/middleware/decorators.py: rate_limited decorator for protecting callables.
  • cli/simulate.py: deterministic simulator comparing strategies on the same traffic pattern.
  • tests/: Pytest coverage for refill math, window pruning, and wait-time reporting.

Quickstart

# From repo root
python3 -m venv .venv && source .venv/bin/activate
python3 -m pip install --upgrade pip
python3 -m pip install -e '.[dev]'   # or: python3 -m pip install pytest

# Run the deterministic simulator
PYTHONPATH=. python3 cli/simulate.py

# Run tests
PYTHONPATH=. python3 -m pytest

CLI demo (deterministic)

  t(s)  req        token bucket    tokens    next      sliding window    next
-----------------------------------------------------------------------------
  0.40    1               ALLOW      9.00    0.00               ALLOW    0.00
  0.43    2               ALLOW      8.15    0.00               ALLOW    0.00
  0.46    3               ALLOW      7.30    0.00               ALLOW    0.00
  0.86    4               ALLOW      8.30    0.00               ALLOW    0.00
  0.94    5               ALLOW      7.70    0.00               ALLOW    0.00
  0.99    6               ALLOW      6.95    0.00               ALLOW    0.00
  1.04    7               ALLOW      6.20    0.00               ALLOW    0.00
  1.09    8               ALLOW      5.45    0.00               ALLOW    0.00
  1.09    9               ALLOW      4.45    0.00               ALLOW    0.00
  1.12   10               ALLOW      3.60    0.00               ALLOW    0.00
  1.52   11               ALLOW      4.60    0.00               ALLOW    0.00
  1.92   12               ALLOW      5.60    0.00               ALLOW    0.00
  2.17   13               ALLOW      5.85    0.00               BLOCK    0.73
  2.20   14               ALLOW      5.00    0.00               BLOCK    0.70
  2.45   15               ALLOW      5.25    0.00               BLOCK    0.45
  2.57   16               ALLOW      4.85    0.00               BLOCK    0.33
  2.60   17               ALLOW      4.00    0.00               BLOCK    0.30
  2.60   18               ALLOW      3.00    0.00               BLOCK    0.30
  2.63   19               ALLOW      2.15    0.00               BLOCK    0.27
  2.68   20               ALLOW      1.40    0.00               BLOCK    0.22
  2.73   21               ALLOW      0.65    0.00               BLOCK    0.17
  2.98   22               ALLOW      0.90    0.00               ALLOW    0.00
  3.23   23               ALLOW      1.15    0.00               ALLOW    0.00
  3.26   24               ALLOW      0.30    0.00               ALLOW    0.00
  3.51   25               ALLOW      0.55    0.00               ALLOW    0.00
  3.56   26               BLOCK      0.80    0.04               ALLOW    0.00
  3.56   27               BLOCK      0.80    0.04               ALLOW    0.00
  3.96   28               ALLOW      1.80    0.00               ALLOW    0.00
  4.36   29               ALLOW      2.80    0.00               ALLOW    0.00
  4.61   30               ALLOW      3.05    0.00               ALLOW    0.00

Summary
-------
Token bucket: 28/30 allowed
Sliding window: 21/30 allowed

Using Flowguard in code

from flowguard import TokenBucket, rate_limited

# Allow bursts of 10 requests with steady 5 rps refill
limiter = TokenBucket(capacity=10, refill_rate=5)

@rate_limited(limiter)
def handle_request(payload):
    return f"processed {payload}"

for i in range(15):
    try:
        print(handle_request(i))
    except Exception as exc:
        print(f"dropped {i}: {exc}")

Architecture notes

  • Deterministic time: all limiters consume a TimeProvider, making simulations and tests reproducible without real waits.
  • Thread safety: critical sections guarded with locks for correctness under concurrency.
  • Extensible decisions: the Decision object surfaces tokens remaining and time until next availability for better UX/logging.
  • Middleware layer: decorator lets you protect any callable; swap strategies without touching business logic.

Built by Mo Shirmohammadi (USC CS) — github.com/mohosy

About

Token bucket and sliding window rate limiter implementations. Python.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages