Source code for app.model.abuse_limit_counter

from datetime import datetime
from uuid import uuid4

from pydantic import ConfigDict
from sqlalchemy import Index, Integer, UniqueConstraint
from sqlalchemy.dialects.postgresql import UUID
from sqlmodel import Column, DateTime, Field, SQLModel, String, func


[docs] class AbuseLimitCounter(SQLModel, table=True): """ Stores per-scope counters used by abuse-prevention and rate-limiting rules. The tuple (scopeType, scopeValue, windowName, windowStart) is unique and represents one logical bucket. """ __tablename__ = "abuse_limit_counter" __table_args__ = ( UniqueConstraint( "scopeType", "scopeValue", "windowName", "windowStart", name="uq_abuse_limit_counter_scope_window", ), Index( "ix_abuse_limit_counter_lookup", "scopeType", "scopeValue", "windowName", "windowStart", ), ) id: str = Field( default_factory=uuid4, sa_column=Column(UUID(as_uuid=True), primary_key=True, index=True), ) created_at: datetime = Field( sa_column=Column(DateTime(timezone=True), default=func.now()) ) updated_at: datetime = Field( sa_column=Column( DateTime(timezone=True), default=func.now(), onupdate=func.now() ) ) scopeType: str = Field(sa_column=Column(String, nullable=False)) scopeValue: str = Field(sa_column=Column(String, nullable=False)) windowName: str = Field(sa_column=Column(String, nullable=False)) windowStart: datetime = Field( sa_column=Column(DateTime(timezone=True), nullable=False) ) counter: int = Field(sa_column=Column(Integer, nullable=False, default=0)) model_config = ConfigDict(from_attributes=True) def __str__(self): return ( "AbuseLimitCounter: " f"(id={self.id}, scopeType={self.scopeType}, scopeValue={self.scopeValue}, " f"windowName={self.windowName}, windowStart={self.windowStart}, " f"counter={self.counter})" ) def __repr__(self): return self.__str__() def __eq__(self, other): return ( isinstance(other, AbuseLimitCounter) and self.scopeType == other.scopeType and self.scopeValue == other.scopeValue and self.windowName == other.windowName and self.windowStart == other.windowStart and self.counter == other.counter )