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 automatic fallback.

✨ Features

  • 🚀 High Performance: Atomic operations using Redis Lua scripts and optimized algorithms
  • 🔧 Flexible Configuration: Both decorator and middleware support with custom key functions
  • 🪟 Multiple Algorithms: Fixed window and sliding window rate limiting
  • 🔌 Multiple Backends: Redis, Database, Memory, and Multi-Backend with automatic fallback
  • 📊 Rich Headers: Standard rate limiting headers (X-RateLimit-*)
  • 🛡️ Production Ready: Comprehensive testing, error handling, and monitoring
  • 🔄 Auto-Fallback: Seamless failover between backends when one goes down
  • 📈 Health Monitoring: Built-in health checks and status reporting

🚀 Quick Setup

1. Installation

# Basic installation
pip install django-smart-ratelimit

# With optional dependencies for specific backends/features
pip install django-smart-ratelimit[redis]      # Redis backend (recommended)
pip install django-smart-ratelimit[mongodb]    # MongoDB backend
pip install django-smart-ratelimit[jwt]        # JWT-based rate limiting
pip install django-smart-ratelimit[all]        # All optional dependencies

2. Add to Django Settings

# settings.py
INSTALLED_APPS = [
    # ... your apps
    'django_smart_ratelimit',
]

# Basic Redis configuration (recommended for production)
RATELIMIT_BACKEND = 'redis'
RATELIMIT_REDIS = {
    'host': 'localhost',
    'port': 6379,
    'db': 0,
}

3. Choose Your Style

Option A: Decorator Style (View-Level)

from django_smart_ratelimit import rate_limit
from django.http import JsonResponse

@rate_limit(key='ip', rate='10/m')
def api_endpoint(request):
    return JsonResponse({'message': 'Hello World'})

@rate_limit(key='user', rate='100/h', block=True)
def user_api(request):
    return JsonResponse({'data': 'user-specific data'})

# With algorithm and skip_if parameters
@rate_limit(key='ip', rate='50/h', algorithm='sliding_window', skip_if=lambda req: req.user.is_staff)
def advanced_api(request):
    return JsonResponse({'advanced': 'data'})

Option B: Middleware Style (Application-Level)

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

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

4. Test It Works

# Check backend health
python manage.py ratelimit_health

# Test with curl
curl -I http://localhost:8000/api/endpoint/
# Look for X-RateLimit-* headers

That's it! You now have rate limiting protection. 🎉

📖 Documentation

Core Documentation

Examples & Advanced Usage

🏗️ Basic Examples

Decorator Examples

from django_smart_ratelimit import rate_limit

# Basic IP-based limiting
@rate_limit(key='ip', rate='10/m')
def public_api(request):
    return JsonResponse({'message': 'Hello World'})

# User-based limiting (automatically falls back to IP for anonymous users)
@rate_limit(key='user', rate='100/h')
def user_dashboard(request):
    return JsonResponse({'user_data': '...'})

# Custom key function for more control
@rate_limit(key=lambda req: f"user:{req.user.id}" if req.user.is_authenticated else f"ip:{req.META.get('REMOTE_ADDR')}", rate='50/h')
def flexible_api(request):
    return JsonResponse({'data': '...'})

# Block when limit exceeded (default is to continue)
@rate_limit(key='ip', rate='5/m', block=True)
def strict_api(request):
    return JsonResponse({'sensitive': 'data'})

# Skip rate limiting for staff users
@rate_limit(key='ip', rate='10/m', skip_if=lambda req: req.user.is_staff)
def staff_friendly_api(request):
    return JsonResponse({'data': 'staff can access unlimited'})

# Use sliding window algorithm
@rate_limit(key='user', rate='100/h', algorithm='sliding_window')
def smooth_api(request):
    return JsonResponse({'algorithm': 'sliding_window'})

# Use fixed window algorithm
@rate_limit(key='ip', rate='20/m', algorithm='fixed_window')
def burst_api(request):
    return JsonResponse({'algorithm': 'fixed_window'})

Middleware Configuration

# settings.py
RATELIMIT_MIDDLEWARE = {
    # Default rate for all paths
    'DEFAULT_RATE': '100/m',

    # Path-specific rates
    'RATE_LIMITS': {
        '/api/auth/': '10/m',      # Authentication endpoints
        '/api/upload/': '5/h',     # File uploads
        '/api/search/': '50/m',    # Search endpoints
        '/api/': '200/h',          # General API
    },

    # Paths to skip (no rate limiting)
    'SKIP_PATHS': [
        '/admin/',
        '/health/',
        '/static/',
    ],

    # Custom key function
    'KEY_FUNCTION': 'myapp.utils.get_api_key_or_ip',

    # Block requests when limit exceeded
    'BLOCK': True,
}

🔧 Backend Options

Redis (Recommended for Production)

RATELIMIT_BACKEND = 'redis'
RATELIMIT_REDIS = {
    'host': 'localhost',
    'port': 6379,
    'db': 0,
    'password': 'your-password',  # if needed
    'socket_timeout': 0.1,
}

Database (Good for Small Scale)

RATELIMIT_BACKEND = 'database'
# No additional configuration needed
# Uses your default Django database

Memory (Development Only)

RATELIMIT_BACKEND = 'memory'
RATELIMIT_MEMORY_MAX_KEYS = 10000

Multi-Backend (High Availability)

RATELIMIT_BACKENDS = [
    {
        'name': 'primary_redis',
        'backend': 'redis',
        'config': {'host': 'redis-primary.example.com'}
    },
    {
        'name': 'fallback_redis',
        'backend': 'redis',
        'config': {'host': 'redis-fallback.example.com'}
    },
    {
        'name': 'emergency_db',
        'backend': 'database',
        'config': {}
    }
]
RATELIMIT_MULTI_BACKEND_STRATEGY = 'first_healthy'

🔍 Monitoring

Health Checks

# Basic health check
python manage.py ratelimit_health

# Detailed status
python manage.py ratelimit_health --verbose

# JSON output for monitoring
python manage.py ratelimit_health --json

Cleanup (Database Backend)

# Clean expired entries
python manage.py cleanup_ratelimit

# Preview what would be deleted
python manage.py cleanup_ratelimit --dry-run

# Clean entries older than 24 hours
python manage.py cleanup_ratelimit --older-than 24

🆚 Comparison

Feature django-smart-ratelimit django-ratelimit django-rest-framework
Multiple Backends ✅ Redis, DB, Memory, Multi ❌ Cache only ❌ Cache only
Sliding Window
Auto-Fallback
Health Monitoring
Standard Headers ⚠️ Limited
Atomic Operations ⚠️ Race conditions ⚠️ Race conditions
Production Ready ⚠️ ⚠️

📚 Comprehensive Examples

The examples/ directory contains detailed examples for every use case:

See the Examples README for detailed usage instructions.

🤝 Contributing

We welcome contributions! See our Contributing Guide for details on:

  • Setting up the development environment
  • Running tests and code quality checks
  • Submitting pull requests
  • Code style guidelines

💖 Support the Project

If you find this project helpful and want to support its development, you can make a donation:

  • USDT (Ethereum): 0x202943b3a6CC168F92871d9e295537E6cbc53Ff4

Your support helps maintain and improve this open-source project for the Django community! 🙏

📜 License

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

🙏 Acknowledgments

  • Inspired by various rate limiting implementations in the Django ecosystem
  • Built with performance and reliability in mind for production use
  • Community feedback and contributions help make this better

DocumentationExamplesContributingIssues

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.4.0.tar.gz (58.0 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.4.0-py3-none-any.whl (36.7 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: django_smart_ratelimit-0.4.0.tar.gz
  • Upload date:
  • Size: 58.0 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.4.0.tar.gz
Algorithm Hash digest
SHA256 974fb6a88d109c0bbdba506d6712de309f4b32a25240c6375598488b9ce8cb98
MD5 5382171a1ca4f3aeacd1bd21827f63e8
BLAKE2b-256 11c9c3f98f8f4de766e29448aceff440023a4705472d644ede2417a32099e1ac

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for django_smart_ratelimit-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 328a6eb323049cef7421aec7ab9a9d951c2adf7ff8e8f85555389f6a17ddb0c8
MD5 39e4921c9706ceb96750749d3057a7a7
BLAKE2b-256 aacfe376c9be9203a08664d2ade3fb4121d87b8205b802a538248bb1e4a6a8cd

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