Metadata-Version: 2.4
Name: ratelimit-lite
Version: 0.1.0
Summary: Lightweight client-side rate limiting for outbound API calls, with pluggable memory/Redis backends.
Author: Athul
License: MIT
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Provides-Extra: redis
Requires-Dist: redis>=4.0; extra == "redis"
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"

# ratelimit-lite

A lightweight, client-side rate limiter for outbound API calls — no database required. Works entirely in memory by default, with optional Redis support for coordinating limits across multiple processes or pods.

## Install

```bash
pip install ratelimit-lite
```

For Redis support:

```bash
pip install ratelimit-lite[redis]
```

## Quickstart

```python
from ratelimit_lite.limiter import Limiter
from ratelimit_lite.decorator import rate_limited

limiter = Limiter(algorithm="sliding_window", backend="memory", limit=50, window_size=60)

@rate_limited(limiter, key="weather_api")
def call_weather_api():
    ...
```

Or use it as a context manager:

```python
with limiter.acquire("weather_api"):
    call_weather_api()
```

By default, a blocked call raises `RateLimitExceeded`. Pass `wait=True` to block and retry automatically instead:

```python
@rate_limited(limiter, key="weather_api", wait=True)
def call_weather_api():
    ...
```

## Algorithms

- `"fixed_window"` — simple counter that resets every `window_size` seconds. Fast and predictable, but allows brief bursts near window boundaries.
- `"sliding_window"` — weighted counter that blends the previous and current window, avoiding boundary bursts. Recommended default for most use cases.

## Backends

- `"memory"` — in-process, no dependencies. State resets on restart and does not coordinate across multiple processes.
- `"redis"` — coordinates limits across multiple processes or pods, using Lua scripts for atomicity. Requires a running Redis server.

```python
from ratelimit_lite.limiter import Limiter

# uses localhost:6379 by default
limiter = Limiter(algorithm="sliding_window", backend="redis", limit=50, window_size=60)
```

To use a custom Redis connection, pass a configured client directly:

```python
import redis
from ratelimit_lite.stores.redis_store import RedisStore

custom_client = redis.Redis(host="my-redis-host", port=6379)
store = RedisStore(redis_client=custom_client)
```
