Metadata-Version: 2.4
Name: drf-ratelimit-plus
Version: 1.0.0
Summary: Advanced rate limiting for Django REST Framework: token bucket, sliding window, tiers, and Redis Cluster support
Project-URL: Homepage, https://mahmoudgshake.github.io/MahmoudPackages/drf-ratelimit-plus/
Project-URL: Documentation, https://mahmoudgshake.github.io/MahmoudPackages/drf-ratelimit-plus/getting-started/
Project-URL: Repository, https://github.com/MahmoudGShake/MahmoudPackages/tree/master/drf-ratelimit-plus
Project-URL: Issues, https://github.com/MahmoudGShake/MahmoudPackages/issues
Project-URL: Changelog, https://github.com/MahmoudGShake/MahmoudPackages/blob/master/drf-ratelimit-plus/CHANGELOG.md
Author-email: Mahmoud Gamal <mahmoudgshaker2018@gmail.com>
Maintainer-email: Mahmoud Gamal <mahmoudgshaker2018@gmail.com>
License-Expression: MIT
License-File: LICENSE
Keywords: api,django,djangorestframework,drf,rate-limiting,redis,redis-cluster,sliding-window,throttling,token-bucket
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Web Environment
Classifier: Framework :: Django
Classifier: Framework :: Django :: 4.2
Classifier: Framework :: Django :: 5.0
Classifier: Framework :: Django :: 5.1
Classifier: Framework :: Django :: 5.2
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: django<5.3,>=4.2
Requires-Dist: djangorestframework>=3.14
Requires-Dist: redis>=5.0
Provides-Extra: dev
Requires-Dist: black>=24.10.0; extra == 'dev'
Requires-Dist: build>=1.2.0; extra == 'dev'
Requires-Dist: django-stubs[compatible-mypy]>=5.1.0; extra == 'dev'
Requires-Dist: djangorestframework-stubs[compatible-mypy]>=3.15.0; extra == 'dev'
Requires-Dist: fakeredis[lua]>=2.24.0; extra == 'dev'
Requires-Dist: hypothesis>=6.112.0; extra == 'dev'
Requires-Dist: mkdocs-material>=9.5.0; extra == 'dev'
Requires-Dist: mkdocs>=1.6.0; extra == 'dev'
Requires-Dist: mkdocstrings[python]>=0.26.0; extra == 'dev'
Requires-Dist: mypy>=1.13.0; extra == 'dev'
Requires-Dist: pre-commit>=3.8.0; extra == 'dev'
Requires-Dist: pytest-benchmark>=4.0.0; extra == 'dev'
Requires-Dist: pytest-cov>=5.0.0; extra == 'dev'
Requires-Dist: pytest-django>=4.9.0; extra == 'dev'
Requires-Dist: pytest-xdist>=3.6.0; extra == 'dev'
Requires-Dist: pytest>=8.3.0; extra == 'dev'
Requires-Dist: ruff>=0.6.9; extra == 'dev'
Requires-Dist: tox-gh-actions>=3.2.0; extra == 'dev'
Requires-Dist: tox>=4.21.0; extra == 'dev'
Requires-Dist: twine>=5.1.0; extra == 'dev'
Requires-Dist: types-redis; extra == 'dev'
Provides-Extra: docs
Requires-Dist: mkdocs-material>=9.5.0; extra == 'docs'
Requires-Dist: mkdocs>=1.6.0; extra == 'docs'
Requires-Dist: mkdocstrings[python]>=0.26.0; extra == 'docs'
Provides-Extra: test
Requires-Dist: fakeredis[lua]>=2.24.0; extra == 'test'
Requires-Dist: hypothesis>=6.112.0; extra == 'test'
Requires-Dist: pytest-benchmark>=4.0.0; extra == 'test'
Requires-Dist: pytest-cov>=5.0.0; extra == 'test'
Requires-Dist: pytest-django>=4.9.0; extra == 'test'
Requires-Dist: pytest-xdist>=3.6.0; extra == 'test'
Requires-Dist: pytest>=8.3.0; extra == 'test'
Description-Content-Type: text/markdown

# drf-ratelimit-plus

[![PyPI version](https://img.shields.io/pypi/v/drf-ratelimit-plus.svg)](https://pypi.org/project/drf-ratelimit-plus/)
[![Python versions](https://img.shields.io/pypi/pyversions/drf-ratelimit-plus.svg)](https://pypi.org/project/drf-ratelimit-plus/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)

Rate limiting for Django REST Framework that goes beyond DRF's built-in
`UserRateThrottle`/`AnonRateThrottle`: token bucket (with real burst
handling), sliding window, fixed window, weighted request costs, per-plan
rate tiers, and Redis Cluster support — built as real
`rest_framework.throttling.BaseThrottle` subclasses, so `Retry-After` and
the standard throttle lifecycle work exactly as DRF users already expect.

```python
from drf_ratelimit_plus import rate_limit


class ArticleViewSet(viewsets.ModelViewSet):
    throttle_classes = [rate_limit(rate="100/m", algorithm="token_bucket", burst=20, key="user")]
```

## Why

DRF's built-in throttles give you one fixed-window counter, one identity
dimension (user or IP), and no burst tolerance. Real APIs need more:
smooth burst handling that a fixed window can't provide, different limits
per subscription tier, weighted costs for expensive endpoints, and a
rate-limiting layer that scales horizontally against Redis Cluster
without hot-key problems.

## Features

- **Three algorithms**: token bucket (smooth bursts against a steady
  refill rate), sliding window (approximate, memory-efficient, avoids
  fixed-window boundary bursts), and fixed window (simplest, cheapest).
- **Weighted costs**: `@ratelimit(rate="1000/h", cost=5)` for an
  expensive endpoint sharing a budget with cheaper ones.
- **Plan tiers**: different limits per subscription tier, resolved
  per-request.
- **Redis Cluster ready**: every algorithm's Redis keys are designed for
  single-slot (or hash-tagged) atomic operations, so nothing requires
  cross-slot transactions.
- **Standard rate-limit headers**: `RateLimit-Limit`, `RateLimit-Remaining`,
  `RateLimit-Reset`, and `Retry-After` on `429` — via DRF's own
  `Throttled` exception, so existing error-handling code keeps working.
- **Composable key functions**: per IP, per user, per API key, per
  tenant, per endpoint, or any combination.
- **Dynamic configuration**: rates can be a string, or a callable
  re-evaluated per request (e.g. reading a database-configured limit).
- Fully typed, PEP 561 compatible, `mypy --strict` clean.

## Installation

```bash
pip install drf-ratelimit-plus
```

Requires a Redis server (standalone or Cluster) — see
[`docs/installation.md`](docs/installation.md).

## Quick Start

```python
from drf_ratelimit_plus import rate_limit


class ArticleViewSet(viewsets.ModelViewSet):
    throttle_classes = [
        rate_limit(rate="100/m", algorithm="sliding_window", key="ip"),
    ]
```

Or the decorator form, for function-based views:

```python
from rest_framework.decorators import api_view
from drf_ratelimit_plus import ratelimit


@api_view(["POST"])
@ratelimit(rate="10/m", key="user")
def expensive_action(request):
    ...
```

## Documentation

Full documentation: <https://mahmoudgshake.github.io/MahmoudPackages/drf-ratelimit-plus/>

- [Getting Started](https://mahmoudgshake.github.io/MahmoudPackages/drf-ratelimit-plus/getting-started)
- [Installation](https://mahmoudgshake.github.io/MahmoudPackages/drf-ratelimit-plus/installation)
- [Configuration](https://mahmoudgshake.github.io/MahmoudPackages/drf-ratelimit-plus/configuration) / [Settings](https://mahmoudgshake.github.io/MahmoudPackages/drf-ratelimit-plus/settings)
- [Quick Start](https://mahmoudgshake.github.io/MahmoudPackages/drf-ratelimit-plus/quickstart)
- [Advanced Usage](https://mahmoudgshake.github.io/MahmoudPackages/drf-ratelimit-plus/advanced-usage)
- [Architecture](https://mahmoudgshake.github.io/MahmoudPackages/drf-ratelimit-plus/architecture)
- [API Reference](https://mahmoudgshake.github.io/MahmoudPackages/drf-ratelimit-plus/api-reference)
- [Examples](https://mahmoudgshake.github.io/MahmoudPackages/drf-ratelimit-plus/examples)
- [Common Patterns](https://mahmoudgshake.github.io/MahmoudPackages/drf-ratelimit-plus/common-patterns)
- [Performance](https://mahmoudgshake.github.io/MahmoudPackages/drf-ratelimit-plus/performance)
- [Security](https://mahmoudgshake.github.io/MahmoudPackages/drf-ratelimit-plus/security)
- [Testing](https://mahmoudgshake.github.io/MahmoudPackages/drf-ratelimit-plus/testing)
- [Deployment](https://mahmoudgshake.github.io/MahmoudPackages/drf-ratelimit-plus/deployment)
- [FAQ](https://mahmoudgshake.github.io/MahmoudPackages/drf-ratelimit-plus/faq)
- [Troubleshooting](https://mahmoudgshake.github.io/MahmoudPackages/drf-ratelimit-plus/troubleshooting)

## Contributing

Contributions are welcome — see [CONTRIBUTING.md](https://github.com/MahmoudGShake/MahmoudPackages/blob/master/drf-ratelimit-plus/CONTRIBUTING.md).

## License

MIT — see [LICENSE](https://github.com/MahmoudGShake/MahmoudPackages/blob/master/drf-ratelimit-plus/LICENSE).
