Logging cleanup, linter.

This commit is contained in:
Leo Vasanko
2026-01-24 01:08:00 +00:00
parent f7f529d8b9
commit 0097bb4011
5 changed files with 38 additions and 66 deletions
+3 -6
View File
@@ -57,7 +57,6 @@ async def flush() -> None:
async def _background_loop():
"""Background task that periodically flushes changes and cleans up."""
_logger.info("Background loop starting")
# Run cleanup immediately on startup to clear old expired items
cleanup()
await flush()
@@ -77,18 +76,17 @@ async def _background_loop():
await flush() # Flush cleanup changes
last_cleanup = now
except asyncio.CancelledError:
_logger.info("Background loop cancelled, final flush")
# Final flush before exit
await flush()
break
except Exception:
_logger.exception("Error in database background loop")
_logger.debug("Error in database background loop", exc_info=True)
async def start_background():
"""Start the background flush/cleanup task."""
global _background_task
# Check if task exists but is no longer running (e.g., after uvicorn reload)
if _background_task is not None:
if _background_task.done():
@@ -106,10 +104,9 @@ async def start_background():
except Exception as e:
_logger.debug("Error checking background task loop: %s, restarting", e)
_background_task = None
if _background_task is None:
_background_task = asyncio.create_task(_background_loop())
_logger.info("Database background task started")
else:
_logger.debug("Background task already running: %s", _background_task)
+3 -4
View File
@@ -84,7 +84,9 @@ def compute_diff(previous: dict, current: dict) -> dict | None:
return diff if diff else None
def create_change_record(action: str, diff: dict, user: str | None = None) -> _ChangeRecord:
def create_change_record(
action: str, diff: dict, user: str | None = None
) -> _ChangeRecord:
"""Create a change record for persistence."""
return _ChangeRecord(
ts=datetime.now(timezone.utc),
@@ -121,9 +123,6 @@ async def flush_changes(
# Append all lines in a single write (binary mode for Windows compatibility)
async with aiofiles.open(db_path, "ab") as f:
await f.write(b"\n".join(lines) + b"\n")
_logger.debug(
"Flushed %d change(s) to %s", len(changes_to_write), db_path
)
return True
except OSError:
_logger.exception("Failed to flush database changes")
+24 -44
View File
@@ -7,9 +7,11 @@ Write operations: Functions that validate and commit, or raise ValueError.
"""
import hashlib
import json
import logging
import os
import secrets
import sys
from collections import deque
from contextlib import contextmanager
from datetime import datetime, timezone
@@ -113,19 +115,15 @@ class DB:
user_display = self._data.users[user_uuid].display_name
except (ValueError, KeyError):
user_display = self._current_user
import json
diff_json = json.dumps(diff, default=str)
if user_display:
_logger.info(
"DB %s by %s: %s",
self._current_action,
user_display,
json.dumps(diff, default=str),
print(
f"{self._current_action} by {user_display}: {diff_json}",
file=sys.stderr,
)
else:
_logger.info(
"DB %s: %s", self._current_action, json.dumps(diff, default=str)
)
print(f"{self._current_action}: {diff_json}", file=sys.stderr)
@contextmanager
def transaction(
@@ -527,9 +525,7 @@ def get_session_context(
# -------------------------------------------------------------------------
def create_permission(
perm: Permission, *, ctx: SessionContext | None = None
) -> None:
def create_permission(perm: Permission, *, ctx: SessionContext | None = None) -> None:
"""Create a new permission."""
if perm.uuid in _db._data.permissions:
raise ValueError(f"Permission {perm.uuid} already exists")
@@ -542,9 +538,7 @@ def create_permission(
)
def update_permission(
perm: Permission, *, ctx: SessionContext | None = None
) -> None:
def update_permission(perm: Permission, *, ctx: SessionContext | None = None) -> None:
"""Update a permission's scope, display_name, and domain."""
if perm.uuid not in _db._data.permissions:
raise ValueError(f"Permission {perm.uuid} not found")
@@ -583,9 +577,7 @@ def rename_permission(
_db._data.permissions[key].domain = domain
def delete_permission(
uuid: str | UUID, *, ctx: SessionContext | None = None
) -> None:
def delete_permission(uuid: str | UUID, *, ctx: SessionContext | None = None) -> None:
"""Delete a permission and remove it from all roles."""
if isinstance(uuid, str):
uuid = UUID(uuid)
@@ -598,9 +590,7 @@ def delete_permission(
del _db._data.permissions[uuid]
def create_organization(
org: Org, *, ctx: SessionContext | None = None
) -> None:
def create_organization(org: Org, *, ctx: SessionContext | None = None) -> None:
"""Create a new organization with an Administration role.
Automatically creates an 'Administration' role with auth:org:admin permission.
@@ -651,9 +641,7 @@ def update_organization_name(
_db._data.orgs[uuid].display_name = display_name
def delete_organization(
uuid: str | UUID, *, ctx: SessionContext | None = None
) -> None:
def delete_organization(uuid: str | UUID, *, ctx: SessionContext | None = None) -> None:
"""Delete organization and all its roles/users."""
if isinstance(uuid, str):
uuid = UUID(uuid)
@@ -742,9 +730,7 @@ def remove_permission_from_organization(
_db._data.permissions[permission_uuid].orgs.pop(org_uuid, None)
def create_role(
role: Role, *, ctx: SessionContext | None = None
) -> None:
def create_role(role: Role, *, ctx: SessionContext | None = None) -> None:
"""Create a new role."""
if role.uuid in _db._data.roles:
raise ValueError(f"Role {role.uuid} already exists")
@@ -809,9 +795,7 @@ def remove_permission_from_role(
_db._data.roles[role_uuid].permissions.pop(permission_uuid, None)
def delete_role(
uuid: str | UUID, *, ctx: SessionContext | None = None
) -> None:
def delete_role(uuid: str | UUID, *, ctx: SessionContext | None = None) -> None:
"""Delete a role."""
if isinstance(uuid, str):
uuid = UUID(uuid)
@@ -824,9 +808,7 @@ def delete_role(
del _db._data.roles[uuid]
def create_user(
new_user: User, *, ctx: SessionContext | None = None
) -> None:
def create_user(new_user: User, *, ctx: SessionContext | None = None) -> None:
"""Create a new user."""
if new_user.uuid in _db._data.users:
raise ValueError(f"User {new_user.uuid} already exists")
@@ -849,7 +831,7 @@ def update_user_display_name(
ctx: SessionContext | None = None,
) -> None:
"""Update user display name.
For self-service (user updating own name), ctx can be None and user is derived from uuid.
For admin operations, ctx should be provided.
"""
@@ -909,9 +891,7 @@ def update_user_role_in_organization(
_db._data.users[user_uuid].role = new_role_uuid
def delete_user(
uuid: str | UUID, *, ctx: SessionContext | None = None
) -> None:
def delete_user(uuid: str | UUID, *, ctx: SessionContext | None = None) -> None:
"""Delete user and their credentials/sessions."""
if isinstance(uuid, str):
uuid = UUID(uuid)
@@ -933,9 +913,7 @@ def delete_user(
del _db._data.users[uuid]
def create_credential(
cred: Credential, *, ctx: SessionContext | None = None
) -> None:
def create_credential(cred: Credential, *, ctx: SessionContext | None = None) -> None:
"""Create a new credential."""
if cred.uuid in _db._data.credentials:
raise ValueError(f"Credential {cred.uuid} already exists")
@@ -1056,7 +1034,7 @@ def set_session_host(key: str, host: str, *, ctx: SessionContext | None = None)
def delete_session(key: str, *, ctx: SessionContext | None = None) -> None:
"""Delete a session.
For logout (user deleting own session), ctx can be None and user is derived from session.
For admin operations, ctx should be provided.
"""
@@ -1068,9 +1046,11 @@ def delete_session(key: str, *, ctx: SessionContext | None = None) -> None:
del _db._data.sessions[key]
def delete_sessions_for_user(user_uuid: str | UUID, *, ctx: SessionContext | None = None) -> None:
def delete_sessions_for_user(
user_uuid: str | UUID, *, ctx: SessionContext | None = None
) -> None:
"""Delete all sessions for a user.
For logout-all (user deleting own sessions), ctx can be None and user is derived from user_uuid.
For admin operations, ctx should be provided.
"""
@@ -1093,7 +1073,7 @@ def create_reset_token(
ctx: SessionContext | None = None,
) -> None:
"""Create a reset token from a passphrase.
For self-service (user creating own recovery link), ctx can be None and user is derived from user_uuid.
For admin operations, ctx should be provided.
"""
+5 -11
View File
@@ -214,9 +214,7 @@ async def admin_add_org_permission(
ctx = await authz.verify(
auth, ["auth:admin"], host=request.headers.get("host"), match=permutil.has_all
)
db.add_permission_to_organization(
str(org_uuid), permission_id, ctx=ctx
)
db.add_permission_to_organization(str(org_uuid), permission_id, ctx=ctx)
return {"status": "ok"}
@@ -240,9 +238,7 @@ async def admin_remove_org_permission(
"This would lock you out of admin access."
)
db.remove_permission_from_organization(
str(org_uuid), permission_id, ctx=ctx
)
db.remove_permission_from_organization(str(org_uuid), permission_id, ctx=ctx)
return {"status": "ok"}
@@ -273,7 +269,7 @@ async def admin_create_role(
perms = payload.get("permissions") or []
org = db.get_organization(str(org_uuid))
grantable = set(org.permissions or [])
# Normalize permission IDs to UUIDs
permission_uuids = []
for pid in perms:
@@ -284,7 +280,7 @@ async def admin_create_role(
if perm_uuid_str not in grantable:
raise ValueError(f"Permission not grantable by org: {pid}")
permission_uuids.append(perm_uuid_str)
role = RoleDC(
uuid=role_uuid,
org_uuid=org_uuid,
@@ -1060,9 +1056,7 @@ async def admin_rename_permission(
_check_admin_lockout(str(perm.uuid), domain_value, request.headers.get("host"))
# All current backends support rename_permission
db.rename_permission(
old_scope, new_scope, display_name, domain_value, ctx=ctx
)
db.rename_permission(old_scope, new_scope, display_name, domain_value, ctx=ctx)
return {"status": "ok"}
+3 -1
View File
@@ -120,7 +120,9 @@ async def second_org_session_token(
@pytest_asyncio.fixture(scope="function")
async def org_admin_role(test_db: DB, test_org: Org, org_admin_permission: Permission) -> Role:
async def org_admin_role(
test_db: DB, test_org: Org, org_admin_permission: Permission
) -> Role:
"""Create a role with org admin permission only (no global admin)."""
role = Role(
uuid=uuid7.create(),