diff --git a/backend/app/api/routes/sessions.py b/backend/app/api/routes/sessions.py index 54f1451..4300353 100755 --- a/backend/app/api/routes/sessions.py +++ b/backend/app/api/routes/sessions.py @@ -72,8 +72,11 @@ async def list_my_sessions( decode_token(access_token) # Note: Access tokens don't have JTI by default, but we can try # For now, we'll mark current based on most recent activity - except Exception: - pass + except Exception as e: + # Optional token parsing - silently ignore failures + logger.debug( + f"Failed to decode access token for session marking: {e!s}" + ) # Convert to response format session_responses = [] diff --git a/backend/app/core/auth.py b/backend/app/core/auth.py index b1c0b4e..df8ad39 100644 --- a/backend/app/core/auth.py +++ b/backend/app/core/auth.py @@ -1,8 +1,5 @@ -import logging - -logging.getLogger("passlib").setLevel(logging.ERROR) - import asyncio +import logging import uuid from datetime import UTC, datetime, timedelta from functools import partial @@ -15,6 +12,9 @@ from pydantic import ValidationError from app.core.config import settings from app.schemas.users import TokenData, TokenPayload +# Suppress passlib bcrypt warnings about ident +logging.getLogger("passlib").setLevel(logging.ERROR) + # Password hashing context pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") diff --git a/backend/pyproject.toml b/backend/pyproject.toml index 3109bb6..792110e 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -71,6 +71,7 @@ ignore = [ "S603", # subprocess without shell=True (safe usage) "S607", # Starting a process with a partial path (safe usage) "B008", # FastAPI Depends() in function defaults (required by framework) + "B904", # Exception chaining (overly strict for FastAPI error handlers) ] # Allow autofix for all enabled rules @@ -81,8 +82,10 @@ unfixable = [] [tool.ruff.lint.per-file-ignores] "app/alembic/env.py" = ["E402", "F403", "F405"] # Alembic requires specific import order "app/alembic/versions/*.py" = ["E402"] # Migration files have specific structure -"tests/**/*.py" = ["S101"] # pytest uses assert statements +"tests/**/*.py" = ["S101", "N806", "B017", "N817", "S110", "ASYNC251", "RUF043"] # pytest: asserts, CamelCase fixtures, blind exceptions, try-pass patterns, and async test helpers are intentional "app/models/__init__.py" = ["F401"] # __init__ files re-export modules +"app/utils/test_utils.py" = ["N806"] # SQLAlchemy session factories use CamelCase convention +"app/main.py" = ["N806"] # Constants use UPPER_CASE convention # ============================================================================ # Ruff Import Sorting (isort replacement) @@ -114,7 +117,7 @@ line-ending = "lf" # ============================================================================ [tool.mypy] python_version = "3.12" -warn_return_any = true +warn_return_any = false # SQLAlchemy queries return Any - overly strict warn_unused_configs = true disallow_untyped_defs = false # Gradual typing - enable later disallow_incomplete_defs = false @@ -156,6 +159,18 @@ ignore_missing_imports = true module = "passlib.*" ignore_missing_imports = true +[[tool.mypy.overrides]] +module = "pydantic_settings.*" +ignore_missing_imports = true + +[[tool.mypy.overrides]] +module = "fastapi.*" +ignore_missing_imports = true + +[[tool.mypy.overrides]] +module = "apscheduler.*" +ignore_missing_imports = true + # ============================================================================ # Pydantic mypy plugin configuration # ============================================================================