Hooks¶
Lifecycle callbacks for app policy (welcome email, trial grant, audit log). A hook fires uniformly across every path that creates or authenticates a user.
crudauth.hooks.AuthHooks
dataclass
¶
AuthHooks(
on_after_register: Hook | None = None,
on_after_login: Hook | None = None,
on_after_logout: Hook | None = None,
on_after_recovery_verified: Hook | None = None,
on_after_password_reset: Hook | None = None,
on_after_password_changed: Hook | None = None,
on_after_email_changed: Hook | None = None,
on_after_sudo: Hook | None = None,
on_after_mfa_enabled: Hook | None = None,
on_after_mfa_disabled: Hook | None = None,
on_after_recovery_code_used: Hook | None = None,
)
Container of optional lifecycle callbacks.
Every hook may be sync or async. user is passed as a plain dict so
hooks don't depend on your ORM type. Example:
```python
async def after_register(user, *, db, context):
await grant_trial(user["id"], db=db)
AuthHooks(on_after_register=after_register)
```
Note
Hooks run after the operation is done (the account created, the session
stored, the password changed), so they can't block or undo it. An
exception a hook raises is logged on the crudauth.hooks logger with its
traceback and the request completes normally. A hook that writes through
db owns that work: commit it, or roll back on its own failure.
crudauth.hooks.HookContext
dataclass
¶
HookContext(
ip_address: str | None = None,
user_agent: str | None = None,
transport: str | None = None,
request: "Request | None" = None,
extra: dict[str, Any] | None = None,
)
Ambient request/identity info passed to hooks as context=.