91 lines
2.1 KiB
Python
91 lines
2.1 KiB
Python
"""Abstract base class for rate limit storage backends."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from abc import ABC, abstractmethod
|
|
from typing import Any
|
|
|
|
|
|
class Backend(ABC):
|
|
"""Abstract base class for rate limit storage backends."""
|
|
|
|
@abstractmethod
|
|
async def get(self, key: str) -> dict[str, Any] | None:
|
|
"""Get the current state for a key.
|
|
|
|
Args:
|
|
key: The rate limit key.
|
|
|
|
Returns:
|
|
The stored state dictionary or None if not found.
|
|
"""
|
|
...
|
|
|
|
@abstractmethod
|
|
async def set(self, key: str, value: dict[str, Any], *, ttl: float) -> None:
|
|
"""Set the state for a key with TTL.
|
|
|
|
Args:
|
|
key: The rate limit key.
|
|
value: The state dictionary to store.
|
|
ttl: Time-to-live in seconds.
|
|
"""
|
|
...
|
|
|
|
@abstractmethod
|
|
async def delete(self, key: str) -> None:
|
|
"""Delete the state for a key.
|
|
|
|
Args:
|
|
key: The rate limit key.
|
|
"""
|
|
...
|
|
|
|
@abstractmethod
|
|
async def exists(self, key: str) -> bool:
|
|
"""Check if a key exists.
|
|
|
|
Args:
|
|
key: The rate limit key.
|
|
|
|
Returns:
|
|
True if the key exists, False otherwise.
|
|
"""
|
|
...
|
|
|
|
@abstractmethod
|
|
async def increment(self, key: str, amount: int = 1) -> int:
|
|
"""Atomically increment a counter.
|
|
|
|
Args:
|
|
key: The rate limit key.
|
|
amount: The amount to increment by.
|
|
|
|
Returns:
|
|
The new value after incrementing.
|
|
"""
|
|
...
|
|
|
|
@abstractmethod
|
|
async def clear(self) -> None:
|
|
"""Clear all rate limit data."""
|
|
...
|
|
|
|
@abstractmethod
|
|
async def close(self) -> None:
|
|
"""Close the backend connection."""
|
|
pass
|
|
|
|
async def __aenter__(self) -> Backend:
|
|
"""Async context manager entry."""
|
|
return self
|
|
|
|
async def __aexit__(
|
|
self,
|
|
exc_type: type[BaseException] | None,
|
|
exc_val: BaseException | None,
|
|
exc_tb: Any,
|
|
) -> None:
|
|
"""Async context manager exit."""
|
|
await self.close()
|