Contents

We cannot use django-ratelimit directly for graphql resolve method.
So I modified rateilmit decorator based on the original code, to support the key format like: gql:xxxx

ratelimit_exampleview raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
from functools import wraps
from ratelimit.exceptions import Ratelimited
from ratelimit.utils import is_ratelimited


def GQLRatelimitKey(group, request):
return request.gql_rl_field


def ratelimit(group=None, key=None, rate=None, method=ALL, block=False):
def decorator(fn):
@wraps(fn)
def _wrapped(root, info, **kw):
request = info.context
request.limited = getattr(request, "limited", False)

new_key = key
if key and key.startswith("gql:"):
_key = key.split("gql:")[1]
value = kw.get(_key, None)
if not value:
raise ValueError(f"Cannot get key: {key}")
request.gql_rl_field = value

new_key = GQLRatelimitKey

ratelimited = is_ratelimited(
request=request,
group=group,
fn=fn,
key=new_key,
rate=rate,
method=method,
increment=True,
)
if ratelimited and block:
raise Ratelimited
return fn(root, info, **kw)

return _wrapped

return decorator

class Test(graphene.Mutation):
class Arguments:
phone = graphene.String(required=True)

ok = graphene.Boolean()

@ratelimit(key="ip", rate="10/m", block=True)
@ratelimit(key="gql:phone", rate="5/m", block=True)
def mutate(self, info, phone):
request = info.context
# Do sth
return Test(ok=True)
Contents