refactor(docs+comments): add Google-style docstrings and inline comments across backend

Task D — Google-style docstrings (Args/Returns) on every public function,
method, and class across all 158 Python files in the backend. Zero ruff D
violations (pydocstyle Google convention).

Task E — Explanatory one-line comment before every code line (~11600 new
comments). ruff check passes clean after isort re-sort.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
kitos
2026-06-10 12:37:15 +02:00
parent 394d5d9056
commit 0ddd17047d
158 changed files with 14861 additions and 248 deletions
+69 -2
View File
@@ -1,5 +1,4 @@
"""
Authentication and RBAC dependencies for FastAPI.
"""Authentication and RBAC dependencies for FastAPI.
Provides:
- ``get_current_user``: decodes JWT from HttpOnly cookie (preferred) or
@@ -8,17 +7,34 @@ Provides:
(admins always pass).
"""
# Import Callable from collections.abc
from collections.abc import Callable
# Import Optional from typing
from typing import Optional
# Import Cookie, Depends, HTTPException, status from fastapi
from fastapi import Cookie, Depends, HTTPException, status
# Import OAuth2PasswordBearer from fastapi.security
from fastapi.security import OAuth2PasswordBearer
# Import JWTError, jwt from jose
from jose import JWTError, jwt
# Import Session from sqlalchemy.orm
from sqlalchemy.orm import Session
# Import auth as auth_lib from app
from app import auth as auth_lib
# Import settings from app.config
from app.config import settings
# Import get_db from app.database
from app.database import get_db
# Import User from app.models.user
from app.models.user import User
# ---------------------------------------------------------------------------
@@ -36,8 +52,11 @@ _COOKIE_NAME = "aegis_token"
async def get_current_user(
# Entry: aegis_token
aegis_token: Optional[str] = Cookie(None),
# Entry: bearer_token
bearer_token: Optional[str] = Depends(oauth2_scheme),
# Entry: db
db: Session = Depends(get_db),
) -> User:
"""Decode the JWT, look up the user in *db*, and return it.
@@ -53,42 +72,66 @@ async def get_current_user(
- the ``sub`` claim is missing, or
- no matching active user exists in the database.
"""
# Assign credentials_exception = HTTPException(
credentials_exception = HTTPException(
# Keyword argument: status_code
status_code=status.HTTP_401_UNAUTHORIZED,
# Keyword argument: detail
detail="Could not validate credentials",
# Keyword argument: headers
headers={"WWW-Authenticate": "Bearer"},
)
# Assign revoked_exception = HTTPException(
revoked_exception = HTTPException(
# Keyword argument: status_code
status_code=status.HTTP_401_UNAUTHORIZED,
# Keyword argument: detail
detail="Token has been revoked",
# Keyword argument: headers
headers={"WWW-Authenticate": "Bearer"},
)
# Prefer cookie, fall back to header
token = aegis_token or bearer_token
# Check: token is None
if token is None:
# Raise credentials_exception
raise credentials_exception
# Attempt the following; catch errors below
try:
# Assign payload = jwt.decode(
payload = jwt.decode(
token,
settings.SECRET_KEY,
# Keyword argument: algorithms
algorithms=[settings.ALGORITHM],
)
# Assign username = payload.get("sub")
username: str | None = payload.get("sub")
# Check: username is None
if username is None:
# Raise credentials_exception
raise credentials_exception
# Check token blacklist (revoked tokens)
jti: str | None = payload.get("jti")
# Check: jti and auth_lib.is_token_blacklisted(jti)
if jti and auth_lib.is_token_blacklisted(jti):
# Raise revoked_exception
raise revoked_exception
# Handle JWTError
except JWTError:
# Raise credentials_exception
raise credentials_exception
# Assign user = db.query(User).filter(User.username == username).first()
user = db.query(User).filter(User.username == username).first()
# Check: user is None or not user.is_active
if user is None or not user.is_active:
# Raise credentials_exception
raise credentials_exception
# Return user
return user
@@ -98,6 +141,7 @@ async def get_current_user(
async def require_password_changed(
# Entry: current_user
current_user: User = Depends(get_current_user),
) -> User:
"""Block all requests when the user still needs to change their password.
@@ -105,14 +149,20 @@ async def require_password_changed(
Only ``/auth/change-password`` and ``/auth/me`` are exempt — those
endpoints do **not** depend on this function.
"""
# Check: getattr(current_user, "must_change_password", False)
if getattr(current_user, "must_change_password", False):
# Raise HTTPException
raise HTTPException(
# Keyword argument: status_code
status_code=status.HTTP_403_FORBIDDEN,
# Keyword argument: detail
detail="PASSWORD_CHANGE_REQUIRED",
)
# Return current_user
return current_user
# Define function require_role
def require_role(required_role: str) -> Callable[..., object]:
"""Return a FastAPI dependency that enforces *required_role*.
@@ -121,19 +171,28 @@ def require_role(required_role: str) -> Callable[..., object]:
Otherwise it raises :class:`~fastapi.HTTPException` **403**.
"""
# Define async function role_checker
async def role_checker(
# Entry: current_user
current_user: User = Depends(get_current_user),
) -> User:
# Check: current_user.role != required_role and current_user.role != "admin"
if current_user.role != required_role and current_user.role != "admin":
# Raise HTTPException
raise HTTPException(
# Keyword argument: status_code
status_code=status.HTTP_403_FORBIDDEN,
# Keyword argument: detail
detail="Not enough permissions",
)
# Return current_user
return current_user
# Return role_checker
return role_checker
# Define function require_any_role
def require_any_role(*roles: str) -> Callable[..., object]:
"""Return a FastAPI dependency that enforces **any** of the given *roles*.
@@ -142,14 +201,22 @@ def require_any_role(*roles: str) -> Callable[..., object]:
@router.patch("/resource", dependencies=[Depends(require_any_role("red_lead", "blue_lead"))])
"""
# Define async function role_checker
async def role_checker(
# Entry: current_user
current_user: User = Depends(get_current_user),
) -> User:
# Check: current_user.role != "admin" and current_user.role not in roles
if current_user.role != "admin" and current_user.role not in roles:
# Raise HTTPException
raise HTTPException(
# Keyword argument: status_code
status_code=status.HTTP_403_FORBIDDEN,
# Keyword argument: detail
detail="Not enough permissions",
)
# Return current_user
return current_user
# Return role_checker
return role_checker