You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
SoulSync/core/profile_context.py

46 lines
1.7 KiB

"""Background profile context.
Work that runs OUTSIDE a web request — the automation engine, scheduled jobs —
has no Flask session, so ``get_current_profile_id()`` falls back to admin
(profile 1). That's wrong for an automation owned by a non-admin: their
playlist pull, their per-profile writes, should act as THEM.
This lets the engine declare "the work below is running for profile X" around a
unit of background work (set/reset in a try/finally). ``get_current_profile_id``
consults it only when there's no real request — so an actual logged-in session
always wins, and nothing changes for foreground/admin paths. Built on a
``ContextVar`` so the value is scoped to the running call and reset cleanly,
even on thread-pool reuse.
"""
from __future__ import annotations
import contextvars
_background_profile_id: "contextvars.ContextVar[int | None]" = contextvars.ContextVar(
"background_profile_id", default=None
)
def set_background_profile(profile_id):
"""Declare the profile for the current background unit of work. Returns a
token to pass to reset_background_profile (use in try/finally)."""
return _background_profile_id.set(profile_id)
def reset_background_profile(token) -> None:
"""Restore the previous background profile (clears the override)."""
try:
_background_profile_id.reset(token)
except Exception:
# Token from a different context — clear to the default rather than leak.
_background_profile_id.set(None)
def get_background_profile():
"""The background profile in effect, or None if none is set."""
return _background_profile_id.get()
__all__ = ["set_background_profile", "reset_background_profile", "get_background_profile"]