This commit is contained in:
2025-10-23 19:41:24 +02:00
parent c81a493fb1
commit ffb182e3ba
7 changed files with 180 additions and 643 deletions

View File

@@ -91,13 +91,19 @@ def get_series_app() -> Optional[SeriesApp]:
@app.on_event("startup")
async def startup_event():
async def startup_event() -> None:
"""Initialize application on startup."""
try:
# Initialize SeriesApp with configured directory and store it on
# application state so it can be injected via dependencies.
if settings.anime_directory:
app.state.series_app = SeriesApp(settings.anime_directory)
else:
# Log warning when anime directory is not configured
print(
"WARNING: ANIME_DIRECTORY not configured. "
"Some features may be unavailable."
)
# Initialize progress service with websocket callback
progress_service = get_progress_service()
@@ -105,7 +111,7 @@ async def startup_event():
async def broadcast_callback(
message_type: str, data: dict, room: str
):
) -> None:
"""Broadcast progress updates via WebSocket."""
message = {
"type": message_type,
@@ -118,6 +124,7 @@ async def startup_event():
print("FastAPI application started successfully")
except Exception as e:
print(f"Error during startup: {e}")
raise # Re-raise to prevent app from starting in broken state
@app.on_event("shutdown")

View File

@@ -46,7 +46,11 @@ class AuthMiddleware(BaseHTTPMiddleware):
}
def __init__(
self, app: ASGIApp, *, rate_limit_per_minute: int = 5
self,
app: ASGIApp,
*,
rate_limit_per_minute: int = 5,
window_seconds: int = 60
) -> None:
super().__init__(app)
# in-memory rate limiter: ip -> {count, window_start}
@@ -54,15 +58,16 @@ class AuthMiddleware(BaseHTTPMiddleware):
# origin-based rate limiter for CORS: origin -> {count, window_start}
self._origin_rate: Dict[str, Dict[str, float]] = {}
self.rate_limit_per_minute = rate_limit_per_minute
self.window_seconds = 60
self.window_seconds = window_seconds
# Track last cleanup time to prevent memory leaks
self._last_cleanup = time.time()
self._cleanup_interval = 300 # Clean every 5 minutes
def _cleanup_old_entries(self) -> None:
"""Remove rate limit entries older than cleanup interval.
This prevents memory leaks from accumulating old IP addresses and origins.
This prevents memory leaks from accumulating old IP addresses
and origins.
"""
now = time.time()
if now - self._last_cleanup < self._cleanup_interval:

View File

@@ -64,6 +64,15 @@ class AuthService:
return pwd_context.hash(password)
def _verify_password(self, plain: str, hashed: str) -> bool:
"""Verify a password against a hash.
Args:
plain: Plain text password
hashed: Hashed password
Returns:
bool: True if password matches, False otherwise
"""
try:
return pwd_context.verify(plain, hashed)
except Exception: