django-smart-ratelimit


Namedjango-smart-ratelimit JSON
Version 0.7.6 PyPI version JSON
download
home_pageNone
SummaryA flexible and efficient rate limiting library for Django applications
upload_time2025-07-20 12:55:56
maintainerNone
docs_urlNone
authorNone
requires_python>=3.9
licenseNone
keywords decorator django middleware rate-limiting redis
VCS
bugtrack_url
requirements Django redis pymongo
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Django Smart Ratelimit

[![CI](https://github.com/YasserShkeir/django-smart-ratelimit/workflows/CI/badge.svg)](https://github.com/YasserShkeir/django-smart-ratelimit/actions)
[![PyPI version](https://img.shields.io/pypi/v/django-smart-ratelimit.svg)](https://pypi.org/project/django-smart-ratelimit/)
[![PyPI status](https://img.shields.io/pypi/status/django-smart-ratelimit.svg)](https://pypi.org/project/django-smart-ratelimit/)
[![Python versions](https://img.shields.io/pypi/pyversions/django-smart-ratelimit.svg)](https://pypi.org/project/django-smart-ratelimit/)
[![Django versions](https://img.shields.io/badge/Django-3.2%20%7C%204.0%20%7C%204.1%20%7C%204.2%20%7C%205.0%20%7C%205.1-blue.svg)](https://pypi.org/project/django-smart-ratelimit/)
[![Downloads](https://img.shields.io/pypi/dm/django-smart-ratelimit.svg)](https://pypi.org/project/django-smart-ratelimit/)
[![License](https://img.shields.io/pypi/l/django-smart-ratelimit.svg)](https://github.com/YasserShkeir/django-smart-ratelimit/blob/main/LICENSE)
[![GitHub Discussions](https://img.shields.io/github/discussions/YasserShkeir/django-smart-ratelimit)](https://github.com/YasserShkeir/django-smart-ratelimit/discussions)

A comprehensive rate limiting library for Django applications with multiple algorithms, backends, and flexible configuration options.

## Why Rate Limiting Matters

Rate limiting helps protect your Django applications from:

- **Resource exhaustion** from excessive requests
- **Brute force attacks** on authentication endpoints
- **API abuse** and scraping attempts
- **Unintentional traffic spikes** that can overwhelm your server

## Library Features

- **Multiple algorithms**: Token bucket, sliding window, and fixed window
- **Backend flexibility**: Redis, Database, Memory, and Multi-Backend support
- **Atomic operations**: Redis Lua scripts prevent race conditions
- **Automatic failover**: Graceful degradation between backends
- **Type safety**: Full mypy compatibility with strict type checking
- **Framework integration**: Native Django and Django REST Framework support
- **Monitoring tools**: Health checks and cleanup management commands
- **Standard headers**: X-RateLimit-\* headers for client information

## Quick Start

### Installation

```bash
pip install django-smart-ratelimit[redis]
```

### Basic Usage

```python
from django_smart_ratelimit import rate_limit

# IP-based rate limiting
@rate_limit(key='ip', rate='100/h')
def api_endpoint(request):
    return JsonResponse({'data': 'protected'})

# User-based rate limiting
@rate_limit(key='user', rate='50/h')
def user_dashboard(request):
    return JsonResponse({'user_data': '...'})
```

### Authentication Protection

```python
@rate_limit(key='ip', rate='5/m', block=True)
def login_view(request):
    return authenticate_user(request)
```

### Django REST Framework

```python
from rest_framework import viewsets
from django_smart_ratelimit import rate_limit

class APIViewSet(viewsets.ViewSet):
    @rate_limit(key='ip', rate='100/h')
    def list(self, request):
        return Response({'data': 'list'})
```

### Middleware Configuration

```python
# settings.py
MIDDLEWARE = ['django_smart_ratelimit.middleware.RateLimitMiddleware']
RATELIMIT_MIDDLEWARE = {
    'DEFAULT_RATE': '1000/h',
    'RATE_LIMITS': {
        '/api/auth/': '10/m',
        '/api/': '500/h',
    }
}
```

## Algorithm Comparison

| Algorithm          | Characteristics              | Best For                   |
| ------------------ | ---------------------------- | -------------------------- |
| **token_bucket**   | Allows traffic bursts        | APIs with variable load    |
| **sliding_window** | Smooth request distribution  | Consistent traffic control |
| **fixed_window**   | Simple, predictable behavior | Basic rate limiting needs  |

### Token Bucket Algorithm

The token bucket algorithm allows for burst traffic handling:

```python
@rate_limit(
    key='user',
    rate='100/h',  # Base rate
    algorithm='token_bucket',
    algorithm_config={
        'bucket_size': 200,  # Allow bursts up to 200 requests
        'refill_rate': 2.0,  # Refill tokens at 2 per second
    }
)
def api_with_bursts(request):
    return JsonResponse({'data': 'handled'})
```

**Common use cases:**

- Mobile app synchronization after offline periods
- Batch file processing
- API retry mechanisms

## Backend Configuration

### Redis (Recommended)

```python
RATELIMIT_BACKEND = 'redis'
RATELIMIT_REDIS = {
    'host': 'localhost',
    'port': 6379,
    'db': 0,
}
```

### Database

```python
RATELIMIT_BACKEND = 'database'
# Uses your default Django database
```

### Multi-Backend with Failover

```python
RATELIMIT_BACKENDS = [
    {
        'name': 'primary_redis',
        'backend': 'redis',
        'config': {'host': 'redis-primary.example.com'}
    },
    {
        'name': 'fallback_db',
        'backend': 'database',
        'config': {}
    }
]
```

## Response Headers

The library adds standard rate limit headers to responses:

```http
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 99
X-RateLimit-Reset: 1642678800
```

## Monitoring and Management

### Health Checks

```bash
# Check backend health
python manage.py ratelimit_health

# Detailed status
python manage.py ratelimit_health --verbose
```

### Cleanup (Database Backend)

```bash
# Clean expired entries
python manage.py cleanup_ratelimit

# Preview cleanup
python manage.py cleanup_ratelimit --dry-run
```

## Library Features

- **Multiple algorithms**: Token bucket, sliding window, and fixed window
- **Backend flexibility**: Redis, Database, Memory, and Multi-Backend support
- **Atomic operations**: Redis Lua scripts prevent race conditions
- **Automatic failover**: Graceful degradation between backends
- **Type safety**: Full mypy compatibility with strict type checking
- **Framework integration**: Native Django and Django REST Framework support

## Examples

The library includes comprehensive examples for various use cases:

- **[Basic Rate Limiting](https://github.com/YasserShkeir/django-smart-ratelimit/blob/main/examples/basic_rate_limiting.py)** - IP and user-based limiting
- **[Custom Key Functions](https://github.com/YasserShkeir/django-smart-ratelimit/blob/main/examples/custom_key_functions.py)** - Geographic and device-based keys
- **[JWT Rate Limiting](https://github.com/YasserShkeir/django-smart-ratelimit/blob/main/examples/jwt_rate_limiting.py)** - Token-based limiting
- **[DRF Integration](https://github.com/YasserShkeir/django-smart-ratelimit/blob/main/examples/drf_integration/)** - Django REST Framework examples
- **[Multi-tenant Applications](https://github.com/YasserShkeir/django-smart-ratelimit/blob/main/examples/tenant_rate_limiting.py)** - Tenant-aware rate limiting

## Configuration Options

### Decorator Parameters

```python
@rate_limit(
    key='user',                    # Key function or string
    rate='100/h',                  # Rate limit (requests/period)
    algorithm='token_bucket',      # Algorithm choice
    algorithm_config={},           # Algorithm-specific config
    backend='redis',               # Backend override
    block=True,                    # Block vs. continue on limit
    skip_if=lambda req: req.user.is_staff,  # Skip condition
)
```

## Testing

```bash
# Run tests
python -m pytest

# Run with coverage
python -m pytest --cov=django_smart_ratelimit
```

### 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'})

# Use token bucket algorithm (NEW!)
@rate_limit(
    key='api_key',
    rate='100/m',  # Base rate: 100 requests per minute
    algorithm='token_bucket',
    algorithm_config={
        'bucket_size': 200,  # Allow bursts up to 200 requests
        'refill_rate': 2.0,  # Refill at 2 tokens per second
    }
)
def api_with_bursts(request):
    return JsonResponse({'algorithm': 'token_bucket', 'burst_allowed': True})
```

## Community & Support

- **[GitHub Discussions](https://github.com/YasserShkeir/django-smart-ratelimit/discussions)** - Community support and questions
- **[Issues](https://github.com/YasserShkeir/django-smart-ratelimit/issues)** - Bug reports and feature requests
- **[Contributing](https://github.com/YasserShkeir/django-smart-ratelimit/blob/main/CONTRIBUTING.md)** - Contributing guidelines
- **[AI Usage Policy](https://github.com/YasserShkeir/django-smart-ratelimit/blob/main/AI_USAGE.md)** - Transparency about AI assistance in development

## 💖 Support the Project

If you find this project helpful and want to support its development, you can make a donation to help maintain and improve this open-source library:

### Cryptocurrency Donations

- **USDT (Ethereum Network)**: `0xBD90e5df7389295AE6fbaB5FEf6817f22A8123eF`
- **Solana (SOL)**: `WzQHS7hzBcznkYoR7TkMH1DRo3WLYQdWCNBuy6ZfY3h`
- **Ripple (XRP)**: `rE8CM2sv4gBEDhek2Ajm2vMmqMXdPV34jC`

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

## License

This project is licensed under the MIT License - see the [LICENSE](https://github.com/YasserShkeir/django-smart-ratelimit/blob/main/LICENSE) file for details.

---

**[📚 Documentation](https://github.com/YasserShkeir/django-smart-ratelimit/blob/main/docs/)** • **[💡 Examples](https://github.com/YasserShkeir/django-smart-ratelimit/blob/main/examples/)** • **[🤝 Contributing](https://github.com/YasserShkeir/django-smart-ratelimit/blob/main/CONTRIBUTING.md)** • **[💬 Discussions](https://github.com/YasserShkeir/django-smart-ratelimit/discussions)** • **[🤖 AI Usage](https://github.com/YasserShkeir/django-smart-ratelimit/blob/main/AI_USAGE.md)**

            

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/c8/f5/b15c9c4875f7d5551ba0b2c01993479c891e82afa165b9731c20d8266ae6/django_smart_ratelimit-0.7.6.tar.gz",
    "platform": null,
    "description": "# Django Smart Ratelimit\n\n[![CI](https://github.com/YasserShkeir/django-smart-ratelimit/workflows/CI/badge.svg)](https://github.com/YasserShkeir/django-smart-ratelimit/actions)\n[![PyPI version](https://img.shields.io/pypi/v/django-smart-ratelimit.svg)](https://pypi.org/project/django-smart-ratelimit/)\n[![PyPI status](https://img.shields.io/pypi/status/django-smart-ratelimit.svg)](https://pypi.org/project/django-smart-ratelimit/)\n[![Python versions](https://img.shields.io/pypi/pyversions/django-smart-ratelimit.svg)](https://pypi.org/project/django-smart-ratelimit/)\n[![Django versions](https://img.shields.io/badge/Django-3.2%20%7C%204.0%20%7C%204.1%20%7C%204.2%20%7C%205.0%20%7C%205.1-blue.svg)](https://pypi.org/project/django-smart-ratelimit/)\n[![Downloads](https://img.shields.io/pypi/dm/django-smart-ratelimit.svg)](https://pypi.org/project/django-smart-ratelimit/)\n[![License](https://img.shields.io/pypi/l/django-smart-ratelimit.svg)](https://github.com/YasserShkeir/django-smart-ratelimit/blob/main/LICENSE)\n[![GitHub Discussions](https://img.shields.io/github/discussions/YasserShkeir/django-smart-ratelimit)](https://github.com/YasserShkeir/django-smart-ratelimit/discussions)\n\nA comprehensive rate limiting library for Django applications with multiple algorithms, backends, and flexible configuration options.\n\n## Why Rate Limiting Matters\n\nRate limiting helps protect your Django applications from:\n\n- **Resource exhaustion** from excessive requests\n- **Brute force attacks** on authentication endpoints\n- **API abuse** and scraping attempts\n- **Unintentional traffic spikes** that can overwhelm your server\n\n## Library Features\n\n- **Multiple algorithms**: Token bucket, sliding window, and fixed window\n- **Backend flexibility**: Redis, Database, Memory, and Multi-Backend support\n- **Atomic operations**: Redis Lua scripts prevent race conditions\n- **Automatic failover**: Graceful degradation between backends\n- **Type safety**: Full mypy compatibility with strict type checking\n- **Framework integration**: Native Django and Django REST Framework support\n- **Monitoring tools**: Health checks and cleanup management commands\n- **Standard headers**: X-RateLimit-\\* headers for client information\n\n## Quick Start\n\n### Installation\n\n```bash\npip install django-smart-ratelimit[redis]\n```\n\n### Basic Usage\n\n```python\nfrom django_smart_ratelimit import rate_limit\n\n# IP-based rate limiting\n@rate_limit(key='ip', rate='100/h')\ndef api_endpoint(request):\n    return JsonResponse({'data': 'protected'})\n\n# User-based rate limiting\n@rate_limit(key='user', rate='50/h')\ndef user_dashboard(request):\n    return JsonResponse({'user_data': '...'})\n```\n\n### Authentication Protection\n\n```python\n@rate_limit(key='ip', rate='5/m', block=True)\ndef login_view(request):\n    return authenticate_user(request)\n```\n\n### Django REST Framework\n\n```python\nfrom rest_framework import viewsets\nfrom django_smart_ratelimit import rate_limit\n\nclass APIViewSet(viewsets.ViewSet):\n    @rate_limit(key='ip', rate='100/h')\n    def list(self, request):\n        return Response({'data': 'list'})\n```\n\n### Middleware Configuration\n\n```python\n# settings.py\nMIDDLEWARE = ['django_smart_ratelimit.middleware.RateLimitMiddleware']\nRATELIMIT_MIDDLEWARE = {\n    'DEFAULT_RATE': '1000/h',\n    'RATE_LIMITS': {\n        '/api/auth/': '10/m',\n        '/api/': '500/h',\n    }\n}\n```\n\n## Algorithm Comparison\n\n| Algorithm          | Characteristics              | Best For                   |\n| ------------------ | ---------------------------- | -------------------------- |\n| **token_bucket**   | Allows traffic bursts        | APIs with variable load    |\n| **sliding_window** | Smooth request distribution  | Consistent traffic control |\n| **fixed_window**   | Simple, predictable behavior | Basic rate limiting needs  |\n\n### Token Bucket Algorithm\n\nThe token bucket algorithm allows for burst traffic handling:\n\n```python\n@rate_limit(\n    key='user',\n    rate='100/h',  # Base rate\n    algorithm='token_bucket',\n    algorithm_config={\n        'bucket_size': 200,  # Allow bursts up to 200 requests\n        'refill_rate': 2.0,  # Refill tokens at 2 per second\n    }\n)\ndef api_with_bursts(request):\n    return JsonResponse({'data': 'handled'})\n```\n\n**Common use cases:**\n\n- Mobile app synchronization after offline periods\n- Batch file processing\n- API retry mechanisms\n\n## Backend Configuration\n\n### Redis (Recommended)\n\n```python\nRATELIMIT_BACKEND = 'redis'\nRATELIMIT_REDIS = {\n    'host': 'localhost',\n    'port': 6379,\n    'db': 0,\n}\n```\n\n### Database\n\n```python\nRATELIMIT_BACKEND = 'database'\n# Uses your default Django database\n```\n\n### Multi-Backend with Failover\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_db',\n        'backend': 'database',\n        'config': {}\n    }\n]\n```\n\n## Response Headers\n\nThe library adds standard rate limit headers to responses:\n\n```http\nX-RateLimit-Limit: 100\nX-RateLimit-Remaining: 99\nX-RateLimit-Reset: 1642678800\n```\n\n## Monitoring and Management\n\n### Health Checks\n\n```bash\n# Check backend health\npython manage.py ratelimit_health\n\n# Detailed status\npython manage.py ratelimit_health --verbose\n```\n\n### Cleanup (Database Backend)\n\n```bash\n# Clean expired entries\npython manage.py cleanup_ratelimit\n\n# Preview cleanup\npython manage.py cleanup_ratelimit --dry-run\n```\n\n## Library Features\n\n- **Multiple algorithms**: Token bucket, sliding window, and fixed window\n- **Backend flexibility**: Redis, Database, Memory, and Multi-Backend support\n- **Atomic operations**: Redis Lua scripts prevent race conditions\n- **Automatic failover**: Graceful degradation between backends\n- **Type safety**: Full mypy compatibility with strict type checking\n- **Framework integration**: Native Django and Django REST Framework support\n\n## Examples\n\nThe library includes comprehensive examples for various use cases:\n\n- **[Basic Rate Limiting](https://github.com/YasserShkeir/django-smart-ratelimit/blob/main/examples/basic_rate_limiting.py)** - IP and user-based limiting\n- **[Custom Key Functions](https://github.com/YasserShkeir/django-smart-ratelimit/blob/main/examples/custom_key_functions.py)** - Geographic and device-based keys\n- **[JWT Rate Limiting](https://github.com/YasserShkeir/django-smart-ratelimit/blob/main/examples/jwt_rate_limiting.py)** - Token-based limiting\n- **[DRF Integration](https://github.com/YasserShkeir/django-smart-ratelimit/blob/main/examples/drf_integration/)** - Django REST Framework examples\n- **[Multi-tenant Applications](https://github.com/YasserShkeir/django-smart-ratelimit/blob/main/examples/tenant_rate_limiting.py)** - Tenant-aware rate limiting\n\n## Configuration Options\n\n### Decorator Parameters\n\n```python\n@rate_limit(\n    key='user',                    # Key function or string\n    rate='100/h',                  # Rate limit (requests/period)\n    algorithm='token_bucket',      # Algorithm choice\n    algorithm_config={},           # Algorithm-specific config\n    backend='redis',               # Backend override\n    block=True,                    # Block vs. continue on limit\n    skip_if=lambda req: req.user.is_staff,  # Skip condition\n)\n```\n\n## Testing\n\n```bash\n# Run tests\npython -m pytest\n\n# Run with coverage\npython -m pytest --cov=django_smart_ratelimit\n```\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# Use token bucket algorithm (NEW!)\n@rate_limit(\n    key='api_key',\n    rate='100/m',  # Base rate: 100 requests per minute\n    algorithm='token_bucket',\n    algorithm_config={\n        'bucket_size': 200,  # Allow bursts up to 200 requests\n        'refill_rate': 2.0,  # Refill at 2 tokens per second\n    }\n)\ndef api_with_bursts(request):\n    return JsonResponse({'algorithm': 'token_bucket', 'burst_allowed': True})\n```\n\n## Community & Support\n\n- **[GitHub Discussions](https://github.com/YasserShkeir/django-smart-ratelimit/discussions)** - Community support and questions\n- **[Issues](https://github.com/YasserShkeir/django-smart-ratelimit/issues)** - Bug reports and feature requests\n- **[Contributing](https://github.com/YasserShkeir/django-smart-ratelimit/blob/main/CONTRIBUTING.md)** - Contributing guidelines\n- **[AI Usage Policy](https://github.com/YasserShkeir/django-smart-ratelimit/blob/main/AI_USAGE.md)** - Transparency about AI assistance in development\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 to help maintain and improve this open-source library:\n\n### Cryptocurrency Donations\n\n- **USDT (Ethereum Network)**: `0xBD90e5df7389295AE6fbaB5FEf6817f22A8123eF`\n- **Solana (SOL)**: `WzQHS7hzBcznkYoR7TkMH1DRo3WLYQdWCNBuy6ZfY3h`\n- **Ripple (XRP)**: `rE8CM2sv4gBEDhek2Ajm2vMmqMXdPV34jC`\n\nYour support helps maintain and improve this project for the Django community! \ud83d\ude4f\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](https://github.com/YasserShkeir/django-smart-ratelimit/blob/main/LICENSE) file for details.\n\n---\n\n**[\ud83d\udcda Documentation](https://github.com/YasserShkeir/django-smart-ratelimit/blob/main/docs/)** \u2022 **[\ud83d\udca1 Examples](https://github.com/YasserShkeir/django-smart-ratelimit/blob/main/examples/)** \u2022 **[\ud83e\udd1d Contributing](https://github.com/YasserShkeir/django-smart-ratelimit/blob/main/CONTRIBUTING.md)** \u2022 **[\ud83d\udcac Discussions](https://github.com/YasserShkeir/django-smart-ratelimit/discussions)** \u2022 **[\ud83e\udd16 AI Usage](https://github.com/YasserShkeir/django-smart-ratelimit/blob/main/AI_USAGE.md)**\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "A flexible and efficient rate limiting library for Django applications",
    "version": "0.7.6",
    "project_urls": {
        "Changelog": "https://github.com/YasserShkeir/django-smart-ratelimit/blob/main/CHANGELOG.md",
        "Discussions": "https://github.com/YasserShkeir/django-smart-ratelimit/discussions",
        "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": "62216e54ad3f88206812f72ccf0bb3783f631353e9b474f02b9b4189426297e5",
                "md5": "84f46bd4804a35fa7e1c7a85aa2d11ec",
                "sha256": "2368edb08477b3adc2c94fced332dbd9ae4a3306b0c6000bd6501869d68dc412"
            },
            "downloads": -1,
            "filename": "django_smart_ratelimit-0.7.6-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "84f46bd4804a35fa7e1c7a85aa2d11ec",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.9",
            "size": 75870,
            "upload_time": "2025-07-20T12:55:55",
            "upload_time_iso_8601": "2025-07-20T12:55:55.062415Z",
            "url": "https://files.pythonhosted.org/packages/62/21/6e54ad3f88206812f72ccf0bb3783f631353e9b474f02b9b4189426297e5/django_smart_ratelimit-0.7.6-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "c8f5b15c9c4875f7d5551ba0b2c01993479c891e82afa165b9731c20d8266ae6",
                "md5": "a7a7875be57dd704df823fb7909625da",
                "sha256": "4fa1468672193f074331b82c549d78dfdce6ad461d78a770f1709ec05ba8aa9f"
            },
            "downloads": -1,
            "filename": "django_smart_ratelimit-0.7.6.tar.gz",
            "has_sig": false,
            "md5_digest": "a7a7875be57dd704df823fb7909625da",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9",
            "size": 136237,
            "upload_time": "2025-07-20T12:55:56",
            "upload_time_iso_8601": "2025-07-20T12:55:56.331146Z",
            "url": "https://files.pythonhosted.org/packages/c8/f5/b15c9c4875f7d5551ba0b2c01993479c891e82afa165b9731c20d8266ae6/django_smart_ratelimit-0.7.6.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-07-20 12:55:56",
    "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"
}
        
Elapsed time: 0.83137s