from __future__ import annotations import urllib from abc import ABC, abstractmethod from types import ModuleType from limits.util import get_package_data class RedisBridge(ABC): RES_DIR = "resources/redis/lua_scripts" SCRIPT_MOVING_WINDOW = get_package_data(f"{RES_DIR}/moving_window.lua") SCRIPT_ACQUIRE_MOVING_WINDOW = get_package_data( f"{RES_DIR}/acquire_moving_window.lua" ) SCRIPT_CLEAR_KEYS = get_package_data(f"{RES_DIR}/clear_keys.lua") SCRIPT_INCR_EXPIRE = get_package_data(f"{RES_DIR}/incr_expire.lua") SCRIPT_SLIDING_WINDOW = get_package_data(f"{RES_DIR}/sliding_window.lua") SCRIPT_ACQUIRE_SLIDING_WINDOW = get_package_data( f"{RES_DIR}/acquire_sliding_window.lua" ) def __init__( self, uri: str, dependency: ModuleType, key_prefix: str, ) -> None: self.uri = uri self.parsed_uri = urllib.parse.urlparse(self.uri) self.dependency = dependency self.parsed_auth = {} self.key_prefix = key_prefix if self.parsed_uri.username: self.parsed_auth["username"] = self.parsed_uri.username if self.parsed_uri.password: self.parsed_auth["password"] = self.parsed_uri.password def prefixed_key(self, key: str) -> str: return f"{self.key_prefix}:{key}" @abstractmethod def register_scripts(self) -> None: ... @abstractmethod def use_sentinel( self, service_name: str | None, use_replicas: bool, sentinel_kwargs: dict[str, str | float | bool] | None, **options: str | float | bool, ) -> None: ... @abstractmethod def use_basic(self, **options: str | float | bool) -> None: ... @abstractmethod def use_cluster(self, **options: str | float | bool) -> None: ... @property @abstractmethod def base_exceptions( self, ) -> type[Exception] | tuple[type[Exception], ...]: ... @abstractmethod async def incr( self, key: str, expiry: int, amount: int = 1, ) -> int: ... @abstractmethod async def get(self, key: str) -> int: ... @abstractmethod async def clear(self, key: str) -> None: ... @abstractmethod async def get_moving_window( self, key: str, limit: int, expiry: int ) -> tuple[float, int]: ... @abstractmethod async def get_sliding_window( self, previous_key: str, current_key: str, expiry: int ) -> tuple[int, float, int, float]: ... @abstractmethod async def acquire_entry( self, key: str, limit: int, expiry: int, amount: int = 1, ) -> bool: ... @abstractmethod async def acquire_sliding_window_entry( self, previous_key: str, current_key: str, limit: int, expiry: int, amount: int = 1, ) -> bool: ... @abstractmethod async def get_expiry(self, key: str) -> float: ... @abstractmethod async def check(self) -> bool: ... @abstractmethod async def reset(self) -> int | None: ... @abstractmethod async def lua_reset(self) -> int | None: ...