Skip to main content

A flexible and efficient rate limiting library for Django applications

Project description

Django Smart Ratelimit

CI PyPI version PyPI status Python versions Django versions Downloads License

A flexible and efficient rate limiting library for Django applications with support for multiple backends and sliding window algorithms.

Features

  • 🚀 High Performance: Atomic operations using Redis Lua scripts
  • 🔧 Flexible Configuration: Both decorator and middleware support
  • 🪟 Multiple Algorithms: Fixed window and sliding window rate limiting
  • 🔌 Multiple Backends: Redis backend with extensible architecture
  • 📊 Rich Headers: Standard rate limiting headers
  • 🛡️ Production Ready: Comprehensive testing and error handling

Quick Start

Installation

pip install django-smart-ratelimit

Basic Usage

Decorator Style

from django_smart_ratelimit import rate_limit

@rate_limit(key='ip', rate='10/m')
def my_view(request):
    return HttpResponse('Hello World')

@rate_limit(key='user:{user.id}', rate='100/h', block=True)
def api_endpoint(request):
    return JsonResponse({'data': 'some data'})

Middleware Style

# settings.py
MIDDLEWARE = [
    'django_smart_ratelimit.middleware.RateLimitMiddleware',
    # ... other middleware
]

RATELIMIT_MIDDLEWARE = {
    'DEFAULT_RATE': '100/m',
    'BACKEND': 'redis',
    'SKIP_PATHS': ['/admin/', '/health/'],
    'RATE_LIMITS': {
        '/api/': '1000/h',
        '/auth/login/': '5/m',
    }
}

Configuration

Redis Backend

# settings.py
RATELIMIT_BACKEND = 'redis'
RATELIMIT_REDIS = {
    'host': 'localhost',
    'port': 6379,
    'db': 0,
    'password': None,
}

# Algorithm selection
RATELIMIT_USE_SLIDING_WINDOW = True  # or False for fixed window

Memory Backend

# settings.py
RATELIMIT_BACKEND = 'memory'

# Memory backend configuration
RATELIMIT_MEMORY_MAX_KEYS = 10000  # Maximum number of keys to store
RATELIMIT_MEMORY_CLEANUP_INTERVAL = 300  # Cleanup interval in seconds

# Algorithm selection
RATELIMIT_USE_SLIDING_WINDOW = True  # or False for fixed window

Usage Examples

Decorator Examples

Basic Rate Limiting

from django_smart_ratelimit import rate_limit

# Limit by IP address
@rate_limit(key='ip', rate='10/m')
def public_api(request):
    return JsonResponse({'message': 'Hello World'})

# Limit by user
@rate_limit(key='user', rate='100/h')
def user_api(request):
    return JsonResponse({'user_data': '...'})

Custom Key Functions

def custom_key(request):
    if request.user.is_authenticated:
        return f"user:{request.user.id}"
    return f"ip:{request.META.get('REMOTE_ADDR')}"

@rate_limit(key=custom_key, rate='50/m')
def smart_api(request):
    return JsonResponse({'data': '...'})

Non-blocking Rate Limiting

@rate_limit(key='ip', rate='10/m', block=False)
def api_with_headers(request):
    # This will add headers but not block requests
    return JsonResponse({'data': '...'})

Middleware Examples

Path-based Rate Limiting

RATELIMIT_MIDDLEWARE = {
    'DEFAULT_RATE': '100/m',
    'RATE_LIMITS': {
        '/api/public/': '1000/h',
        '/api/private/': '100/h',
        '/auth/': '5/m',
        '/upload/': '10/h',
    }
}

Custom Key Functions

# utils.py
def user_key_function(request):
    if request.user.is_authenticated:
        return f"user:{request.user.id}"
    return f"ip:{request.META.get('REMOTE_ADDR')}"

def api_key_function(request):
    api_key = request.META.get('HTTP_X_API_KEY')
    if api_key:
        return f"api_key:{api_key}"
    return f"ip:{request.META.get('REMOTE_ADDR')}"

# settings.py
RATELIMIT_MIDDLEWARE = {
    'KEY_FUNCTION': 'myapp.utils.user_key_function',
    'RATE_LIMITS': {
        '/api/': '1000/h',
    }
}

Rate Formats

The library supports several rate formats:

  • 10/s - 10 requests per second
  • 100/m - 100 requests per minute
  • 1000/h - 1000 requests per hour
  • 10000/d - 10000 requests per day

Response Headers

When rate limiting is applied, the following headers are added:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 75
X-RateLimit-Reset: 1640995200

Algorithms

Fixed Window

Simple and memory-efficient algorithm that resets the counter at fixed intervals.

Pros:

  • Low memory usage
  • Simple implementation
  • Predictable reset times

Cons:

  • Potential for burst traffic
  • Less accurate limiting

Sliding Window

More accurate algorithm that maintains a sliding window of requests.

Pros:

  • Accurate rate limiting
  • No burst traffic issues
  • Smooth rate limiting

Cons:

  • Higher memory usage
  • More complex implementation

Configuration Reference

Decorator Parameters

Parameter Type Default Description
key str or callable Required Rate limit key or key function
rate str Required Rate limit (e.g., '10/m')
block bool True Block requests when limit exceeded
backend str None Backend to use (uses default if None)

Middleware Settings

Setting Type Default Description
DEFAULT_RATE str '100/m' Default rate limit
BACKEND str 'redis' Backend to use
KEY_FUNCTION str None Import path to key function
BLOCK bool True Block requests when limit exceeded
SKIP_PATHS list [] Paths to skip rate limiting
RATE_LIMITS dict {} Path-specific rate limits

Backend Settings

Setting Type Default Description
RATELIMIT_BACKEND str 'redis' Backend to use ('redis', 'memory')
RATELIMIT_REDIS dict {} Redis configuration
RATELIMIT_MEMORY_MAX_KEYS int 10000 Maximum keys for memory backend
RATELIMIT_MEMORY_CLEANUP_INTERVAL int 300 Cleanup interval (seconds)
RATELIMIT_USE_SLIDING_WINDOW bool True Use sliding window algorithm
RATELIMIT_KEY_PREFIX str 'ratelimit:' Redis key prefix

Development

Running Tests

# Install development dependencies
pip install -e .[dev]

# Run tests
pytest

# Run tests with coverage
pytest --cov=django_smart_ratelimit --cov-report=html

# Run specific test file
pytest tests/test_decorator.py

Code Quality

# Format code
black django_smart_ratelimit tests

# Check linting
flake8 django_smart_ratelimit tests

# Type checking
mypy django_smart_ratelimit

Pre-commit Hooks

# Install pre-commit hooks
pre-commit install

# Run hooks manually
pre-commit run --all-files

Contributing

We welcome contributions! Please follow these steps:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Make your changes
  4. Add tests for your changes
  5. Run the test suite (pytest)
  6. Commit your changes (git commit -m 'Add amazing feature')
  7. Push to the branch (git push origin feature/amazing-feature)
  8. Open a Pull Request

Contribution Guidelines

  • Write tests for new features
  • Follow the existing code style
  • Add docstrings to new functions and classes
  • Update documentation as needed
  • Add type hints where appropriate

License

This project is licensed under the MIT License - see the LICENSE file for details.

Changelog

v0.1.0 (Initial Release)

  • Basic decorator and middleware support
  • Redis backend with sliding window algorithm
  • Comprehensive test suite
  • Documentation and examples

Support

💖 Support the Project

If this library has saved you time and effort, consider supporting its development:

Cryptocurrency Donations

  • USDT (Ethereum): 0x202943b3a6CC168F92871d9e295537E6cbc53Ff4

Alternative Support Methods

  • Star this repository on GitHub
  • 🐛 Report bugs and suggest features
  • 🔀 Contribute code improvements
  • 📢 Share with your team and community

Your support helps maintain and improve this open-source project! 🙏

Acknowledgments

  • Created by Yasser Shkeir
  • Inspired by existing Django rate limiting libraries
  • Thanks to the Django and Redis communities
  • Special thanks to all contributors

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_smart_ratelimit-0.2.0.tar.gz (23.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_smart_ratelimit-0.2.0-py3-none-any.whl (16.3 kB view details)

Uploaded Python 3

File details

Details for the file django_smart_ratelimit-0.2.0.tar.gz.

File metadata

  • Download URL: django_smart_ratelimit-0.2.0.tar.gz
  • Upload date:
  • Size: 23.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for django_smart_ratelimit-0.2.0.tar.gz
Algorithm Hash digest
SHA256 73c98a471357eaf12fb181c81f38b84af4e10657e7a0e50d79dc2957ba9a303c
MD5 5b6e4403e22f7ffb0eeff2c4fcdb15aa
BLAKE2b-256 812f108aad43644302047d96ae0098d14bae53f597233bda796abfa1ca6742ab

See more details on using hashes here.

File details

Details for the file django_smart_ratelimit-0.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for django_smart_ratelimit-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 31307ac757dad3fd7d6e16eeba304a71910336c254a5836b9102448f30e6cf6c
MD5 3e51042c5862feb330c2ae0b459c9fe2
BLAKE2b-256 6a37ff833a1c24de8889aa8c419f2a50a3ca79189b11d2393e40dfc4d8998318

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page