1- import time
21import logging
2+ import time
33from pathlib import Path
4- from typing import Optional , Tuple
54
65import redis .asyncio as redis
76
87from app .core .rate_limiter .rate_limiting_algorithm .base import BaseRateLimiter
98
109logger = logging .getLogger (__name__ )
1110
12- SCRIPT_PATH = Path (__file__ ).parent / ".." / ".." / ".." / "alembic" / "rate_limiting_algorithms" / "sliding_window.lua"
11+ SCRIPT_PATH = (
12+ Path (__file__ ).resolve ()
13+ .parents [3 ]
14+ / "alembic"
15+ / "rate_limiting_algorithms"
16+ / "sliding_window.lua"
17+ )
1318
1419
1520class SlidingWindowRateLimiter (BaseRateLimiter ):
@@ -18,7 +23,7 @@ def __init__(self, redis_client: redis.Redis, fail_open: bool):
1823 self .lua_script = None
1924 self .fail_open = fail_open
2025
21- async def load_script (self ):
26+ async def load_script (self ) -> str | None :
2227 if self .lua_script is None :
2328 script_text = SCRIPT_PATH .read_text ()
2429 # LOAD script into redis → returns SHA
@@ -30,16 +35,18 @@ async def allow_request(
3035 key : str ,
3136 limit : int ,
3237 window_seconds : int ,
33- member_id : Optional [ str ] = None
34- ) -> Tuple [bool , Optional [ int ] ]:
38+ member_id : str | None = None
39+ ) -> tuple [bool , int | None ]:
3540
3641 now_ms = int (time .time () * 1000 )
3742 window_ms = window_seconds * 1000
3843 member = member_id or f"{ now_ms } "
3944
4045 try :
4146 sha = await self .load_script ()
42- res = await self .redis .evalsha (
47+ if sha is None :
48+ raise Exception
49+ res = await self .redis .evalsha (# type: ignore[misc]
4350 sha ,
4451 1 ,
4552 key ,
@@ -62,5 +69,5 @@ async def allow_request(
6269
6370 return False , retry_after_s
6471
65- def get_fail_open (self ):
72+ def get_fail_open (self ) -> bool :
6673 return self .fail_open
0 commit comments