# limits Documentation

limits provides utilities to implement rate limiting using various strategies and storage backends such as redis & memcached.

# Quickstart

Initialize the storage backend:

    from limits import storage
    memory_storage = storage.MemoryStorage()

Initialize a rate limiter with the Moving Window strategy:

    from limits import strategies
    moving_window = strategies.MovingWindowRateLimiter(memory_storage)

Initialize a rate limit using the Rate limit string notation:

    from limits import parse
    one_per_minute = parse("1/minute")

Initialize a rate limit explicitly using a subclass of `RateLimitItem`:

    from limits import RateLimitItemPerSecond
    one_per_second = RateLimitItemPerSecond(1, 1)

Test the limits:

    assert True == moving_window.hit(one_per_minute, "test_namespace", "foo")
    assert False == moving_window.hit(one_per_minute, "test_namespace", "foo")
    assert True == moving_window.hit(one_per_minute, "test_namespace", "bar")

    assert True == moving_window.hit(one_per_second, "test_namespace", "foo")
    assert False == moving_window.hit(one_per_second, "test_namespace", "foo")
    time.sleep(1)
    assert True == moving_window.hit(one_per_second, "test_namespace", "foo")

Check specific limits without hitting them:

    assert True == moving_window.hit(one_per_second, "test_namespace", "foo")
    while not moving_window.test(one_per_second, "test_namespace", "foo"):
        time.sleep(0.01)
    assert True == moving_window.hit(one_per_second, "test_namespace", "foo")

# Projects using limits

- Flask-Limiter : Rate limiting extension for Flask applications.
- djlimiter: Rate limiting middleware for Django applications.

# References

- Redis rate limiting pattern #2
- DomainTools redis rate limiter

## Contributions

- Timothee Groleau
- Zehua Liu
- David Czarnecki