Metadata-Version: 2.1
Name: asgi-ratelimit
Version: 0.3.2
Summary: 
Home-page: https://github.com/abersheeran/asgi-ratelimit
License: Apache-2.0
Author: abersheeran
Author-email: me@abersheeran.com
Requires-Python: >=3.6,<4.0
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Provides-Extra: full
Provides-Extra: jwt
Provides-Extra: redis
Requires-Dist: aredis (>=1.1.8,<2.0.0); extra == "redis" or extra == "full"
Requires-Dist: dataclasses (>=0.6,<0.7); python_version >= "3.6" and python_version < "3.7"
Requires-Dist: pyjwt (>=1.7.1,<2.0.0); extra == "jwt" or extra == "full"
Project-URL: Repository, https://github.com/abersheeran/asgi-ratelimit
Description-Content-Type: text/markdown

# ASGI RateLimit

Limit user access frequency. Base on ASGI.

100% coverage. High performance. Support regular matching. Customizable.

## Install

```
# Only install
pip install asgi-ratelimit

# Use redis
pip install asgi-ratelimit[redis]

# Use jwt
pip install asgi-ratelimit[jwt]

# Install all
pip install asgi-ratelimit[full]
```

## Usage

The following example will limit users under the `"default"` group to access `/second_limit` at most once per second and `/minute_limit` at most once per minute. And the users in the `"admin"` group have no restrictions.

```python
from typing import Tuple

from ratelimit import RateLimitMiddleware, Rule
from ratelimit.auths import EmptyInformation
from ratelimit.backends.redis import RedisBackend


async def AUTH_FUNCTION(scope) -> Tuple[str, str]:
    """
    Resolve the user's unique identifier and the user's group from ASGI SCOPE.

    If there is no user information, it should raise `EmptyInformation`.
    If there is no group information, it should return "default".
    """
    return USER_UNIQUE_ID, GROUP_NAME


rate_limit = RateLimitMiddleware(
    ASGI_APP,
    AUTH_FUNCTION,
    RedisBackend(),
    {
        r"^/second_limit": [Rule(second=1), Rule(group="admin")],
        r"^/minute_limit": [Rule(minute=1), Rule(group="admin")],
    },
)

# Or in starlette/fastapi/index.py
app.add_middleware(
    RateLimitMiddleware,
    authenticate=AUTH_FUNCTION,
    backend=RedisBackend(),
    config={
        r"^/second_limit": [Rule(second=1), Rule(group="admin")],
        r"^/minute_limit": [Rule(minute=1), Rule(group="admin")],
    },
)
```

### Block time

When the user's request frequency triggers the upper limit, all requests in the following period of time will be returned with a `429` status code.

Example: `Rule(second=5, block_time=60)`, this rule will limit the user to a maximum of 5 visits per second. Once this limit is exceeded, all requests within the next 60 seconds will return `429`.

### Built-in auth functions

#### Client IP

```python
from ratelimit.auths.ip import client_ip
```

Obtain user IP through `scope["client"]` or `X-Real-IP`.

#### Starlette Session

```python
from ratelimit.auths.session import from_session
```

Get `user` and `group` from `scope["session"]`.

If key `group` not in session, will return `default`. If key `user` not in session, will raise a `EmptyInformation`.

#### Json Web Token

```python
from ratelimit.auths.jwt import create_jwt_auth

jwt_auth = create_jwt_auth("KEY", "HS256")
```

Get `user` and `group` from JWT that in `Authorization` header.

