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.1.tar.gz (58.3 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.1-py3-none-any.whl (36.9 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: django_smart_ratelimit-0.4.1.tar.gz
  • Upload date:
  • Size: 58.3 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.1.tar.gz
Algorithm Hash digest
SHA256 36d1772b104952d38e44a2b99c54447d889acc1d267427f13ee9a98a4c649d25
MD5 bd76ebddb140b81bd7177d70df1e1620
BLAKE2b-256 229ec6beadf6c0b9187efc2dd73b0eef3a40bfeb90a8ea5cd976052c32b95acd

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for django_smart_ratelimit-0.4.1-py3-none-any.whl
Algorithm Hash digest
SHA256 b28ecdbedac68aae5c95478354c71d1ad53c1ed1a04e12981b3133a614773906
MD5 dacbe8df5d6da911ef3008e167486c2a
BLAKE2b-256 f178f7fa68d9436fdde366c23174c756bdfb0787521e652762886f43138f9c82

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