# Django Smart Ratelimit
[](https://github.com/YasserShkeir/django-smart-ratelimit/actions)
[](https://pypi.org/project/django-smart-ratelimit/)
[](https://pypi.org/project/django-smart-ratelimit/)
[](https://pypi.org/project/django-smart-ratelimit/)
[](https://pypi.org/project/django-smart-ratelimit/)
[](https://pypi.org/project/django-smart-ratelimit/)
[](https://github.com/YasserShkeir/django-smart-ratelimit/blob/main/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
```bash
# 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
```python
# 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)
```python
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)
```python
# 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
```bash
# 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
- **[Backend Configuration](docs/backends.md)** - Redis, Database, Memory, and Multi-Backend setup
- **[Architecture & Design](docs/design.md)** - Core architecture, algorithms, and design decisions
- **[Management Commands](docs/management_commands.md)** - Health checks and cleanup commands
### Examples & Advanced Usage
- **[Basic Examples](examples/)** - Working examples for different use cases
- **[Complex Key Functions](examples/custom_key_functions.py)** - Custom key patterns and JWT tokens
- **[Multi-Backend Setup](examples/backend_configuration.py)** - High availability configurations
## 🏗️ Basic Examples
### Decorator Examples
```python
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
```python
# 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)
```python
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)
```python
RATELIMIT_BACKEND = 'database'
# No additional configuration needed
# Uses your default Django database
```
### Memory (Development Only)
```python
RATELIMIT_BACKEND = 'memory'
RATELIMIT_MEMORY_MAX_KEYS = 10000
```
### Multi-Backend (High Availability)
```python
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
```bash
# 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)
```bash
# 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:
- **[basic_rate_limiting.py](examples/basic_rate_limiting.py)** - IP, user, and session-based limiting
- **[advanced_rate_limiting.py](examples/advanced_rate_limiting.py)** - Complex scenarios with custom logic
- **[custom_key_functions.py](examples/custom_key_functions.py)** - Geographic, device, and business logic keys
- **[jwt_rate_limiting.py](examples/jwt_rate_limiting.py)** - JWT token and role-based limiting
- **[tenant_rate_limiting.py](examples/tenant_rate_limiting.py)** - Multi-tenant applications
- **[backend_configuration.py](examples/backend_configuration.py)** - All backend configurations
- **[monitoring_examples.py](examples/monitoring_examples.py)** - Health checks and metrics
- **[django_integration.py](examples/django_integration.py)** - Complete Django project setup
See the **[Examples README](examples/README.md)** for detailed usage instructions.
## 🤝 Contributing
We welcome contributions! See our [Contributing Guide](CONTRIBUTING.md) 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](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](docs/)** • **[Examples](examples/)** • **[Contributing](CONTRIBUTING.md)** • **[Issues](https://github.com/YasserShkeir/django-smart-ratelimit/issues)**
Raw data
{
"_id": null,
"home_page": null,
"name": "django-smart-ratelimit",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.9",
"maintainer_email": null,
"keywords": "decorator, django, middleware, rate-limiting, redis",
"author": null,
"author_email": "Yasser Shkeir <shkeiryasser@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/22/9e/c6beadf6c0b9187efc2dd73b0eef3a40bfeb90a8ea5cd976052c32b95acd/django_smart_ratelimit-0.4.1.tar.gz",
"platform": null,
"description": "# Django Smart Ratelimit\n\n[](https://github.com/YasserShkeir/django-smart-ratelimit/actions)\n[](https://pypi.org/project/django-smart-ratelimit/)\n[](https://pypi.org/project/django-smart-ratelimit/)\n[](https://pypi.org/project/django-smart-ratelimit/)\n[](https://pypi.org/project/django-smart-ratelimit/)\n[](https://pypi.org/project/django-smart-ratelimit/)\n[](https://github.com/YasserShkeir/django-smart-ratelimit/blob/main/LICENSE)\n\nA flexible and efficient rate limiting library for Django applications with support for multiple backends and automatic fallback.\n\n## \u2728 Features\n\n- \ud83d\ude80 **High Performance**: Atomic operations using Redis Lua scripts and optimized algorithms\n- \ud83d\udd27 **Flexible Configuration**: Both decorator and middleware support with custom key functions\n- \ud83e\ude9f **Multiple Algorithms**: Fixed window and sliding window rate limiting\n- \ud83d\udd0c **Multiple Backends**: Redis, Database, Memory, and Multi-Backend with automatic fallback\n- \ud83d\udcca **Rich Headers**: Standard rate limiting headers (X-RateLimit-\\*)\n- \ud83d\udee1\ufe0f **Production Ready**: Comprehensive testing, error handling, and monitoring\n- \ud83d\udd04 **Auto-Fallback**: Seamless failover between backends when one goes down\n- \ud83d\udcc8 **Health Monitoring**: Built-in health checks and status reporting\n\n## \ud83d\ude80 Quick Setup\n\n### 1. Installation\n\n```bash\n# Basic installation\npip install django-smart-ratelimit\n\n# With optional dependencies for specific backends/features\npip install django-smart-ratelimit[redis] # Redis backend (recommended)\npip install django-smart-ratelimit[mongodb] # MongoDB backend\npip install django-smart-ratelimit[jwt] # JWT-based rate limiting\npip install django-smart-ratelimit[all] # All optional dependencies\n```\n\n### 2. Add to Django Settings\n\n```python\n# settings.py\nINSTALLED_APPS = [\n # ... your apps\n 'django_smart_ratelimit',\n]\n\n# Basic Redis configuration (recommended for production)\nRATELIMIT_BACKEND = 'redis'\nRATELIMIT_REDIS = {\n 'host': 'localhost',\n 'port': 6379,\n 'db': 0,\n}\n```\n\n### 3. Choose Your Style\n\n#### Option A: Decorator Style (View-Level)\n\n```python\nfrom django_smart_ratelimit import rate_limit\nfrom django.http import JsonResponse\n\n@rate_limit(key='ip', rate='10/m')\ndef api_endpoint(request):\n return JsonResponse({'message': 'Hello World'})\n\n@rate_limit(key='user', rate='100/h', block=True)\ndef user_api(request):\n return JsonResponse({'data': 'user-specific data'})\n\n# With algorithm and skip_if parameters\n@rate_limit(key='ip', rate='50/h', algorithm='sliding_window', skip_if=lambda req: req.user.is_staff)\ndef advanced_api(request):\n return JsonResponse({'advanced': 'data'})\n```\n\n#### Option B: Middleware Style (Application-Level)\n\n```python\n# settings.py\nMIDDLEWARE = [\n 'django_smart_ratelimit.middleware.RateLimitMiddleware',\n # ... other middleware\n]\n\nRATELIMIT_MIDDLEWARE = {\n 'DEFAULT_RATE': '100/m',\n 'RATE_LIMITS': {\n '/api/': '1000/h',\n '/auth/login/': '5/m',\n },\n 'SKIP_PATHS': ['/admin/', '/health/'],\n}\n```\n\n### 4. Test It Works\n\n```bash\n# Check backend health\npython manage.py ratelimit_health\n\n# Test with curl\ncurl -I http://localhost:8000/api/endpoint/\n# Look for X-RateLimit-* headers\n```\n\nThat's it! You now have rate limiting protection. \ud83c\udf89\n\n## \ud83d\udcd6 Documentation\n\n### Core Documentation\n\n- **[Backend Configuration](docs/backends.md)** - Redis, Database, Memory, and Multi-Backend setup\n- **[Architecture & Design](docs/design.md)** - Core architecture, algorithms, and design decisions\n- **[Management Commands](docs/management_commands.md)** - Health checks and cleanup commands\n\n### Examples & Advanced Usage\n\n- **[Basic Examples](examples/)** - Working examples for different use cases\n- **[Complex Key Functions](examples/custom_key_functions.py)** - Custom key patterns and JWT tokens\n- **[Multi-Backend Setup](examples/backend_configuration.py)** - High availability configurations\n\n## \ud83c\udfd7\ufe0f Basic Examples\n\n### Decorator Examples\n\n```python\nfrom django_smart_ratelimit import rate_limit\n\n# Basic IP-based limiting\n@rate_limit(key='ip', rate='10/m')\ndef public_api(request):\n return JsonResponse({'message': 'Hello World'})\n\n# User-based limiting (automatically falls back to IP for anonymous users)\n@rate_limit(key='user', rate='100/h')\ndef user_dashboard(request):\n return JsonResponse({'user_data': '...'})\n\n# Custom key function for more control\n@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')\ndef flexible_api(request):\n return JsonResponse({'data': '...'})\n\n# Block when limit exceeded (default is to continue)\n@rate_limit(key='ip', rate='5/m', block=True)\ndef strict_api(request):\n return JsonResponse({'sensitive': 'data'})\n\n# Skip rate limiting for staff users\n@rate_limit(key='ip', rate='10/m', skip_if=lambda req: req.user.is_staff)\ndef staff_friendly_api(request):\n return JsonResponse({'data': 'staff can access unlimited'})\n\n# Use sliding window algorithm\n@rate_limit(key='user', rate='100/h', algorithm='sliding_window')\ndef smooth_api(request):\n return JsonResponse({'algorithm': 'sliding_window'})\n\n# Use fixed window algorithm\n@rate_limit(key='ip', rate='20/m', algorithm='fixed_window')\ndef burst_api(request):\n return JsonResponse({'algorithm': 'fixed_window'})\n```\n\n### Middleware Configuration\n\n```python\n# settings.py\nRATELIMIT_MIDDLEWARE = {\n # Default rate for all paths\n 'DEFAULT_RATE': '100/m',\n\n # Path-specific rates\n 'RATE_LIMITS': {\n '/api/auth/': '10/m', # Authentication endpoints\n '/api/upload/': '5/h', # File uploads\n '/api/search/': '50/m', # Search endpoints\n '/api/': '200/h', # General API\n },\n\n # Paths to skip (no rate limiting)\n 'SKIP_PATHS': [\n '/admin/',\n '/health/',\n '/static/',\n ],\n\n # Custom key function\n 'KEY_FUNCTION': 'myapp.utils.get_api_key_or_ip',\n\n # Block requests when limit exceeded\n 'BLOCK': True,\n}\n```\n\n## \ud83d\udd27 Backend Options\n\n### Redis (Recommended for Production)\n\n```python\nRATELIMIT_BACKEND = 'redis'\nRATELIMIT_REDIS = {\n 'host': 'localhost',\n 'port': 6379,\n 'db': 0,\n 'password': 'your-password', # if needed\n 'socket_timeout': 0.1,\n}\n```\n\n### Database (Good for Small Scale)\n\n```python\nRATELIMIT_BACKEND = 'database'\n# No additional configuration needed\n# Uses your default Django database\n```\n\n### Memory (Development Only)\n\n```python\nRATELIMIT_BACKEND = 'memory'\nRATELIMIT_MEMORY_MAX_KEYS = 10000\n```\n\n### Multi-Backend (High Availability)\n\n```python\nRATELIMIT_BACKENDS = [\n {\n 'name': 'primary_redis',\n 'backend': 'redis',\n 'config': {'host': 'redis-primary.example.com'}\n },\n {\n 'name': 'fallback_redis',\n 'backend': 'redis',\n 'config': {'host': 'redis-fallback.example.com'}\n },\n {\n 'name': 'emergency_db',\n 'backend': 'database',\n 'config': {}\n }\n]\nRATELIMIT_MULTI_BACKEND_STRATEGY = 'first_healthy'\n```\n\n## \ud83d\udd0d Monitoring\n\n### Health Checks\n\n```bash\n# Basic health check\npython manage.py ratelimit_health\n\n# Detailed status\npython manage.py ratelimit_health --verbose\n\n# JSON output for monitoring\npython manage.py ratelimit_health --json\n```\n\n### Cleanup (Database Backend)\n\n```bash\n# Clean expired entries\npython manage.py cleanup_ratelimit\n\n# Preview what would be deleted\npython manage.py cleanup_ratelimit --dry-run\n\n# Clean entries older than 24 hours\npython manage.py cleanup_ratelimit --older-than 24\n```\n\n## \ud83c\udd9a Comparison\n\n| Feature | django-smart-ratelimit | django-ratelimit | django-rest-framework |\n| ----------------- | --------------------------- | ------------------ | --------------------- |\n| Multiple Backends | \u2705 Redis, DB, Memory, Multi | \u274c Cache only | \u274c Cache only |\n| Sliding Window | \u2705 | \u274c | \u274c |\n| Auto-Fallback | \u2705 | \u274c | \u274c |\n| Health Monitoring | \u2705 | \u274c | \u274c |\n| Standard Headers | \u2705 | \u274c | \u26a0\ufe0f Limited |\n| Atomic Operations | \u2705 | \u26a0\ufe0f Race conditions | \u26a0\ufe0f Race conditions |\n| Production Ready | \u2705 | \u26a0\ufe0f | \u26a0\ufe0f |\n\n## \ud83d\udcda Comprehensive Examples\n\nThe `examples/` directory contains detailed examples for every use case:\n\n- **[basic_rate_limiting.py](examples/basic_rate_limiting.py)** - IP, user, and session-based limiting\n- **[advanced_rate_limiting.py](examples/advanced_rate_limiting.py)** - Complex scenarios with custom logic\n- **[custom_key_functions.py](examples/custom_key_functions.py)** - Geographic, device, and business logic keys\n- **[jwt_rate_limiting.py](examples/jwt_rate_limiting.py)** - JWT token and role-based limiting\n- **[tenant_rate_limiting.py](examples/tenant_rate_limiting.py)** - Multi-tenant applications\n- **[backend_configuration.py](examples/backend_configuration.py)** - All backend configurations\n- **[monitoring_examples.py](examples/monitoring_examples.py)** - Health checks and metrics\n- **[django_integration.py](examples/django_integration.py)** - Complete Django project setup\n\nSee the **[Examples README](examples/README.md)** for detailed usage instructions.\n\n## \ud83e\udd1d Contributing\n\nWe welcome contributions! See our [Contributing Guide](CONTRIBUTING.md) for details on:\n\n- Setting up the development environment\n- Running tests and code quality checks\n- Submitting pull requests\n- Code style guidelines\n\n## \ud83d\udc96 Support the Project\n\nIf you find this project helpful and want to support its development, you can make a donation:\n\n- **USDT (Ethereum)**: `0x202943b3a6CC168F92871d9e295537E6cbc53Ff4`\n\nYour support helps maintain and improve this open-source project for the Django community! \ud83d\ude4f\n\n## \ud83d\udcdc License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n## \ud83d\ude4f Acknowledgments\n\n- Inspired by various rate limiting implementations in the Django ecosystem\n- Built with performance and reliability in mind for production use\n- Community feedback and contributions help make this better\n\n---\n\n**[Documentation](docs/)** \u2022 **[Examples](examples/)** \u2022 **[Contributing](CONTRIBUTING.md)** \u2022 **[Issues](https://github.com/YasserShkeir/django-smart-ratelimit/issues)**\n",
"bugtrack_url": null,
"license": null,
"summary": "A flexible and efficient rate limiting library for Django applications",
"version": "0.4.1",
"project_urls": {
"Changelog": "https://github.com/YasserShkeir/django-smart-ratelimit/blob/main/CHANGELOG.md",
"Documentation": "https://django-smart-ratelimit.readthedocs.io",
"Homepage": "https://github.com/YasserShkeir/django-smart-ratelimit",
"Issues": "https://github.com/YasserShkeir/django-smart-ratelimit/issues",
"Repository": "https://github.com/YasserShkeir/django-smart-ratelimit"
},
"split_keywords": [
"decorator",
" django",
" middleware",
" rate-limiting",
" redis"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "f178f7fa68d9436fdde366c23174c756bdfb0787521e652762886f43138f9c82",
"md5": "dacbe8df5d6da911ef3008e167486c2a",
"sha256": "b28ecdbedac68aae5c95478354c71d1ad53c1ed1a04e12981b3133a614773906"
},
"downloads": -1,
"filename": "django_smart_ratelimit-0.4.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "dacbe8df5d6da911ef3008e167486c2a",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.9",
"size": 36873,
"upload_time": "2025-07-08T13:20:43",
"upload_time_iso_8601": "2025-07-08T13:20:43.805384Z",
"url": "https://files.pythonhosted.org/packages/f1/78/f7fa68d9436fdde366c23174c756bdfb0787521e652762886f43138f9c82/django_smart_ratelimit-0.4.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "229ec6beadf6c0b9187efc2dd73b0eef3a40bfeb90a8ea5cd976052c32b95acd",
"md5": "bd76ebddb140b81bd7177d70df1e1620",
"sha256": "36d1772b104952d38e44a2b99c54447d889acc1d267427f13ee9a98a4c649d25"
},
"downloads": -1,
"filename": "django_smart_ratelimit-0.4.1.tar.gz",
"has_sig": false,
"md5_digest": "bd76ebddb140b81bd7177d70df1e1620",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.9",
"size": 58305,
"upload_time": "2025-07-08T13:20:44",
"upload_time_iso_8601": "2025-07-08T13:20:44.925161Z",
"url": "https://files.pythonhosted.org/packages/22/9e/c6beadf6c0b9187efc2dd73b0eef3a40bfeb90a8ea5cd976052c32b95acd/django_smart_ratelimit-0.4.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-07-08 13:20:44",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "YasserShkeir",
"github_project": "django-smart-ratelimit",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [
{
"name": "Django",
"specs": [
[
">=",
"3.2"
]
]
},
{
"name": "redis",
"specs": [
[
">=",
"4.0"
]
]
},
{
"name": "pymongo",
"specs": [
[
">=",
"4.0"
]
]
}
],
"lcname": "django-smart-ratelimit"
}