Skip to content

Commit

Permalink
Added support for views and changed how RedisLimiter and MemcachedLim…
Browse files Browse the repository at this point in the history
…iter are imported.
  • Loading branch information
Nebulizer1213 committed Nov 28, 2022
1 parent a0ef419 commit 6f9af0f
Show file tree
Hide file tree
Showing 13 changed files with 51 additions and 19 deletions.
1 change: 0 additions & 1 deletion .github/ISSUE_TEMPLATE/bug-report.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ assignees: Nebulizer1213
# Bug Report

Before you submit this request make sure you are using the latest version of aiohttp-ratelimiter.
If you want faster support you can go to https://jgltechnologies.com/contact and link this issue in the message box.

### Python version

Expand Down
2 changes: 1 addition & 1 deletion .idea/aiohttp-ratelimiter.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 15 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ Example

```python
from aiohttp import web
from aiohttplimiter import default_keyfunc, Limiter, RedisLimiter, MemcachedLimiter
from aiohttplimiter import default_keyfunc, Limiter
from aiohttplimiter.redis_limiter import RedisLimiter
from aiohttplimiter.memcached_limiter import MemcachedLimiter

app = web.Application()
routes = web.RouteTableDef()
Expand Down Expand Up @@ -116,5 +118,17 @@ def home(request):
return web.Response(text="Hello")
```

<br>

Views Example

```python
@routes.view("/")
class Home(View):
@limiter.limit("1/second")
def get(self: web.Request):
return web.Response(text="hello")
```



18 changes: 16 additions & 2 deletions aiohttp_ratelimiter.egg-info/PKG-INFO
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: aiohttp-ratelimiter
Version: 4.0.1
Version: 4.1.1
Summary: A simple rate limiter for aiohttp.web
Home-page: https://jgltechnologies.com/aiohttplimiter
Author: George Luca
Expand Down Expand Up @@ -48,7 +48,9 @@ Example

```python
from aiohttp import web
from aiohttplimiter import default_keyfunc, Limiter, RedisLimiter, MemcachedLimiter
from aiohttplimiter import default_keyfunc, Limiter
from aiohttplimiter.redis_limiter import RedisLimiter
from aiohttplimiter.memcached_limiter import MemcachedLimiter

app = web.Application()
routes = web.RouteTableDef()
Expand Down Expand Up @@ -134,6 +136,18 @@ def home(request):
return web.Response(text="Hello")
```

<br>

Views Example

```python
@routes.view("/")
class Home(View):
@limiter.limit("1/second")
def get(self: web.Request):
return web.Response(text="hello")
```




Expand Down
2 changes: 0 additions & 2 deletions aiohttplimiter/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
from .limiter import default_keyfunc, Allow, RateLimitExceeded
from .memory_limiter import Limiter
from .redis_limiter import RedisLimiter
from .memcached_limiter import MemcachedLimiter
12 changes: 8 additions & 4 deletions aiohttplimiter/limiter.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,18 @@
import json
from typing import Callable, Awaitable, Union, Optional, Coroutine, Any
import asyncio
from aiohttp.web import Request, Response
from aiohttp.web import Request, Response, View
from limits.aio.storage import Storage, MemoryStorage
from limits.aio.strategies import MovingWindowRateLimiter
from limits import parse


def default_keyfunc(request: Request) -> str:
def default_keyfunc(request: Union[Request, View]) -> str:
"""
Returns the user's IP
"""
if isinstance(request, View):
request = request.request
ip = request.headers.get(
"X-Forwarded-For") or request.remote or "127.0.0.1"
ip = ip.split(",")[0]
Expand Down Expand Up @@ -51,9 +53,11 @@ def __init__(self, db: Storage, path_id: str, keyfunc: Callable,
self.path_id = path_id
self.moving_window = moving_window

def __call__(self, func: Union[Callable, Awaitable]) -> Coroutine[Any, Any, Response]:
def __call__(self, func: Union[Callable, Awaitable]) -> Callable[[Union[Request, View]], Coroutine[Any, Any, Response]]:
@wraps(func)
async def wrapper(request: Request) -> Response:
async def wrapper(request: Union[Request, View]) -> Response:
if isinstance(request, View):
request = request.request
key = self.keyfunc(request)
db_key = f"{key}:{self.path_id or request.path}"

Expand Down
5 changes: 3 additions & 2 deletions aiohttplimiter/memcached_limiter.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from typing import Callable, Awaitable, Union, Optional
from typing import Callable, Awaitable, Union, Optional, Any, Coroutine
from aiohttp.web import Request, Response, View
from limits.aio.storage import MemcachedStorage
from .limiter import BaseRateLimitDecorator
from limits.aio.strategies import MovingWindowRateLimiter
Expand Down Expand Up @@ -26,7 +27,7 @@ def __init__(self, keyfunc: Callable, uri: str, exempt_ips: Optional[set] = None

def limit(self, ratelimit: str, keyfunc: Callable = None, exempt_ips: Optional[set] = None,
error_handler: Optional[Union[Callable, Awaitable]] = None, path_id: str = None) -> Callable:
def wrapper(func: Callable) -> Awaitable:
def wrapper(func: Callable) -> Callable[[Union[Request, View]], Coroutine[Any, Any, Response]]:
_exempt_ips = exempt_ips or self.exempt_ips
_keyfunc = keyfunc or self.keyfunc
_error_handler = self.error_handler or error_handler
Expand Down
5 changes: 3 additions & 2 deletions aiohttplimiter/memory_limiter.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from aiohttp.web import Request, Response, View
from limits.aio.storage import MemoryStorage
from limits.aio.strategies import MovingWindowRateLimiter
from .limiter import BaseRateLimitDecorator
from typing import Callable, Optional, Union, Awaitable
from typing import Callable, Optional, Union, Awaitable, Any, Coroutine


class Limiter:
Expand All @@ -26,7 +27,7 @@ def __init__(self, keyfunc: Callable, exempt_ips: Optional[set] = None,

def limit(self, ratelimit: str, keyfunc: Callable = None, exempt_ips: Optional[set] = None,
error_handler: Optional[Union[Callable, Awaitable]] = None, path_id: str = None) -> Callable:
def wrapper(func: Callable) -> Awaitable:
def wrapper(func: Callable) -> Callable[[Union[Request, View]], Coroutine[Any, Any, Response]]:
_exempt_ips = exempt_ips or self.exempt_ips
_keyfunc = keyfunc or self.keyfunc
_error_handler = self.error_handler or error_handler
Expand Down
5 changes: 3 additions & 2 deletions aiohttplimiter/redis_limiter.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from typing import Callable, Awaitable, Union, Optional
from typing import Callable, Awaitable, Union, Optional, Any, Coroutine
import coredis
from aiohttp.web import Request, Response, View
from limits.aio.storage import RedisStorage
from .limiter import BaseRateLimitDecorator
from limits.aio.strategies import MovingWindowRateLimiter
Expand Down Expand Up @@ -27,7 +28,7 @@ def __init__(self, keyfunc: Callable, uri: str, exempt_ips: Optional[set] = None

def limit(self, ratelimit: str, keyfunc: Callable = None, exempt_ips: Optional[set] = None,
error_handler: Optional[Union[Callable, Awaitable]] = None, path_id: str = None) -> Callable:
def wrapper(func: Callable) -> Awaitable:
def wrapper(func: Callable) -> Callable[[Union[Request, View]], Coroutine[Any, Any, Response]]:
_exempt_ips = exempt_ips or self.exempt_ips
_keyfunc = keyfunc or self.keyfunc
_error_handler = self.error_handler or error_handler
Expand Down
Binary file removed dist/aiohttp-ratelimiter-4.0.1.tar.gz
Binary file not shown.
Binary file added dist/aiohttp-ratelimiter-4.1.1.tar.gz
Binary file not shown.
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def get_long_description():
return file.read()


VERSION = "4.0.1"
VERSION = "4.1.1"

classifiers = [
"Development Status :: 5 - Production/Stable",
Expand Down

0 comments on commit 6f9af0f

Please sign in to comment.