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 GitHub Discussions

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.

๐Ÿค Community & Support

We have an active community ready to help you get the most out of django-smart-ratelimit!

๐Ÿ’ฌ GitHub Discussions

Join our community discussions for questions, ideas, and sharing experiences:

๐Ÿ› Issues & Bug Reports

For bug reports and specific issues, please use GitHub Issues.

๐Ÿค 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

๐Ÿ“š Documentation โ€ข ๐Ÿ’ก Examples โ€ข ๐Ÿค Contributing โ€ข ๐Ÿ’ฌ Discussions โ€ข ๐Ÿ› Issues

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.2.tar.gz (58.9 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.2-py3-none-any.whl (37.2 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: django_smart_ratelimit-0.4.2.tar.gz
  • Upload date:
  • Size: 58.9 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.2.tar.gz
Algorithm Hash digest
SHA256 906f0c05ae43edd6c507090fcd70e7451983536388436ac55ffa06716c54f524
MD5 b933d2e18c14acc7f0180e7c70f09ebe
BLAKE2b-256 7c09e5064bed67c7134dd6f2640eb108224892fd18f21e8844b4ceb8ecd49dcb

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for django_smart_ratelimit-0.4.2-py3-none-any.whl
Algorithm Hash digest
SHA256 99fa9e8d6d1112e40b1c6571dad80202c4fcaba6e6371095c6a299350c27560e
MD5 b60b40640814cda2f6b16b8ea7130bc0
BLAKE2b-256 89064df8631cea1e097ef429cfd322c55aa9d57d879eb4efd4bd6afd6fbfb154

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