Python: Authentication
Sign app users up and in with passwords, magic links, SMS codes and providers; manage sessions, MFA, app users and roles with the Python SDK.
Sign app users — the people who use your app — in and out of your project. After sign_in, every call from this client runs as that user, so your policies and row-level security apply.
from sovaria import create_client
async with create_client("https://<project-ref>.sovaria.in", "<anon-key>") as sovaria:
await sovaria.sign_up("ada@example.com", "Correct-Horse-9!", "Ada")
await sovaria.sign_in("ada@example.com", "Correct-Horse-9!")
me = await sovaria.get_me()
await sovaria.logout()Methods
sovaria.ban_product_user
Toggle a product user's active state in the resolved scope.
await sovaria.ban_product_user(
user_id: str,
*, org_id: str | None = None,
project_id: str | None = None,
env_id: str | None = None,
) -> dict[str, Any]Parameters
user_idstrrequiredorg_idstr | NoneoptionaldefaultNoneproject_idstr | NoneoptionaldefaultNoneenv_idstr | NoneoptionaldefaultNone
- Returns
dict[str, Any]
sovaria.confirm_verification_email
Confirm an email verification token.
await sovaria.confirm_verification_email(token: str) -> dict[str, Any]Parameters
tokenstrrequired
- Returns
dict[str, Any]
sovaria.console_login
Strict console-lane login for Sovaria operators.
await sovaria.console_login(email: str, password: str) -> TokenResponseParameters
emailstrrequiredpasswordstrrequired
- Returns
TokenResponse
sovaria.create_event_hook
Create event hook.
await sovaria.create_event_hook(body: dict[str, Any]) -> dict[str, Any]Parameters
bodydict[str, Any]required
- Returns
dict[str, Any]
sovaria.create_product_user
Create product user.
await sovaria.create_product_user(
body: dict[str, Any],
*, org_id: str | None = None,
project_id: str | None = None,
env_id: str | None = None,
) -> dict[str, Any]Parameters
bodydict[str, Any]requiredorg_idstr | NoneoptionaldefaultNoneproject_idstr | NoneoptionaldefaultNoneenv_idstr | NoneoptionaldefaultNone
- Returns
dict[str, Any]
sovaria.delete_event_hook
Delete event hook.
await sovaria.delete_event_hook(hook_id: str) -> dict[str, Any]Parameters
hook_idstrrequired
- Returns
dict[str, Any]
sovaria.delete_product_user
Delete a product user credential in the resolved scope.
await sovaria.delete_product_user(
user_id: str,
*, org_id: str | None = None,
project_id: str | None = None,
env_id: str | None = None,
) -> dict[str, Any]Parameters
user_idstrrequiredorg_idstr | NoneoptionaldefaultNoneproject_idstr | NoneoptionaldefaultNoneenv_idstr | NoneoptionaldefaultNone
- Returns
dict[str, Any]
sovaria.disable_mfa
Disable mfa.
await sovaria.disable_mfa(totp_code: str) -> dict[str, Any]Parameters
totp_codestrrequired
- Returns
dict[str, Any]
sovaria.disconnect_github
Disconnect github.
await sovaria.disconnect_github(*, project_id: str) -> dict[str, Any]Parameters
project_idstrrequired
- Returns
dict[str, Any]
sovaria.enroll_mfa
Enroll mfa.
await sovaria.enroll_mfa() -> dict[str, Any]- Returns
dict[str, Any]
sovaria.fn_github_commit
Fn github commit.
await sovaria.fn_github_commit(body: dict[str, Any]) -> dict[str, Any]Parameters
bodydict[str, Any]required
- Returns
dict[str, Any]
sovaria.fn_github_import
Fn github import.
await sovaria.fn_github_import(body: dict[str, Any]) -> dict[str, Any]Parameters
bodydict[str, Any]required
- Returns
dict[str, Any]
sovaria.fn_list_github_repos
Fn list github repos.
await sovaria.fn_list_github_repos(
*, token: str | None = None,
limit: int = 40,
) -> dict[str, Any]Parameters
tokenstr | NoneoptionaldefaultNonelimitintoptionaldefault40
- Returns
dict[str, Any]
sovaria.get_github_connection_state
Get github connection state.
await sovaria.get_github_connection_state(
*, project_id: str,
) -> dict[str, Any]Parameters
project_idstrrequired
- Returns
dict[str, Any]
sovaria.get_me
Return the authenticated user's profile (user_id, email, roles).
await sovaria.get_me() -> dict[str, Any]- Returns
dict[str, Any]
sovaria.get_mfa_status
Get mfa status.
await sovaria.get_mfa_status() -> dict[str, Any]- Returns
dict[str, Any]
sovaria.get_product_user_roles
Return a product user's app roles in the resolved scope.
await sovaria.get_product_user_roles(
user_id: str,
*, org_id: str | None = None,
project_id: str | None = None,
env_id: str | None = None,
) -> dict[str, Any]Parameters
user_idstrrequiredorg_idstr | NoneoptionaldefaultNoneproject_idstr | NoneoptionaldefaultNoneenv_idstr | NoneoptionaldefaultNone
- Returns
dict[str, Any]
sovaria.get_providers_config
Get providers config.
await sovaria.get_providers_config() -> dict[str, Any]- Returns
dict[str, Any]
sovaria.get_sessions_config
Get sessions config.
await sovaria.get_sessions_config() -> dict[str, Any]- Returns
dict[str, Any]
sovaria.list_console_product_users
List console product users.
await sovaria.list_console_product_users() -> list[dict[str, Any]]- Returns
list[dict[str, Any]]
sovaria.list_event_hooks
List event hooks.
await sovaria.list_event_hooks() -> list[dict[str, Any]]- Returns
list[dict[str, Any]]
sovaria.list_product_users
Every project/product user in the resolved org/project scope (follows the API's pages).
For large projects prefer list_product_users_page and page with next_cursor.
await sovaria.list_product_users(
*, org_id: str | None = None,
project_id: str | None = None,
env_id: str | None = None,
) -> list[dict[str, Any]]Parameters
org_idstr | NoneoptionaldefaultNoneproject_idstr | NoneoptionaldefaultNoneenv_idstr | NoneoptionaldefaultNone
- Returns
list[dict[str, Any]]
sovaria.list_product_users_page
One page of product users, newest first: {"users", "next_cursor", "total"}.
search matches part of an email or an exact user id; status is active or banned.
await sovaria.list_product_users_page(
*, org_id: str | None = None,
project_id: str | None = None,
env_id: str | None = None,
limit: int = 50,
cursor: str | None = None,
search: str | None = None,
status: str | None = None,
) -> dict[str, Any]total (for the filter) comes with the first page.
Parameters
org_idstr | NoneoptionaldefaultNoneproject_idstr | NoneoptionaldefaultNoneenv_idstr | NoneoptionaldefaultNonelimitintoptionaldefault50- Page size.
cursorstr | NoneoptionaldefaultNonenext_cursorfrom the previous page.searchstr | NoneoptionaldefaultNone- Part of an email or name.
statusstr | NoneoptionaldefaultNone
- Returns
dict[str, Any]
cursor = None
while True:
page = await sovaria.list_product_users_page(limit=100, cursor=cursor)
for user in page["users"]:
print(user["email"])
cursor = page.get("next_cursor")
if not cursor:
breaksovaria.list_sessions
List sessions.
await sovaria.list_sessions() -> list[dict[str, Any]]- Returns
list[dict[str, Any]]
sovaria.login
Deprecated compatibility login.
Unscoped calls post to POST /api/v1/auth/console/login.
await sovaria.login(email: str, password: str) -> TokenResponseWhen set_scope(org_id, project_id) has been called, posts to POST /api/v1/auth/project/login. Prefer console_login() or project_login() in new code.
Parameters
emailstrrequiredpasswordstrrequired
- Returns
TokenResponse
sovaria.login_console
Alias for console_login(), matching TypeScript lane terminology.
await sovaria.login_console(email: str, password: str) -> TokenResponseParameters
emailstrrequiredpasswordstrrequired
- Returns
TokenResponse
sovaria.login_product
Alias for project_login(), matching TypeScript lane terminology.
await sovaria.login_product(
email: str,
password: str,
*, org_id: str | None = None,
project_id: str | None = None,
env_id: str | None = None,
) -> TokenResponseParameters
emailstrrequiredpasswordstrrequiredorg_idstr | NoneoptionaldefaultNoneproject_idstr | NoneoptionaldefaultNoneenv_idstr | NoneoptionaldefaultNone
- Returns
TokenResponse
sovaria.logout
Revoke the active refresh token server-side, then clear in-memory tokens.
Sends Authorization: Bearer plus {"refresh_token": ...}.
await sovaria.logout() -> NoneNon-2xx responses are treated as failure. Local session state (tokens + KEK) is always cleared, including when the HTTP call fails.
- Returns
None
sovaria.oauth_handoff
Exchange an OAuth handoff token for a session.
Passwordless: session KEK is not derived unless password is supplied and the response includes argon2_salt.
await sovaria.oauth_handoff(
token: str,
password: str | None = None,
) -> TokenResponseParameters
tokenstrrequiredpasswordstr | NoneoptionaldefaultNone
- Returns
TokenResponse
sovaria.product_users_list
Alias for list_product_users(), matching TypeScript productUsers.list().
await sovaria.product_users_list(**kwargs) -> list[dict[str, Any]]- Returns
list[dict[str, Any]]
sovaria.product_users_set_roles
Alias for replace_product_user_roles(), matching TypeScript productUsers.setRoles().
await sovaria.product_users_set_roles(
user_id: str,
roles: list[str],
**kwargs,
) -> dict[str, Any]Parameters
user_idstrrequired- The app user's id.
roleslist[str]required- App roles, e.g.
["librarian"](policies useapp:<role>).
- Returns
dict[str, Any]
sovaria.project_login
Strict project-lane login for product end-users.
await sovaria.project_login(
email: str,
password: str,
*, org_id: str | None = None,
project_id: str | None = None,
env_id: str | None = None,
) -> TokenResponseParameters
emailstrrequiredpasswordstrrequiredorg_idstr | NoneoptionaldefaultNoneproject_idstr | NoneoptionaldefaultNoneenv_idstr | NoneoptionaldefaultNone
- Returns
TokenResponse
sovaria.register
Create an app user in a project (or, with no project scope at all, a Sovaria console account).
The project comes from org_id/project_id or the client's scope (set_scope).
await sovaria.register(
email: str,
password: str,
name: str,
*, org_id: str | None = None,
project_id: str | None = None,
env_id: str | None = None,
) -> TokenResponseWithout either, the account created is a console account — app code should always pass a scope. Registration may not return tokens when the project requires email verification.
Parameters
emailstrrequiredpasswordstrrequirednamestrrequiredorg_idstr | NoneoptionaldefaultNoneproject_idstr | NoneoptionaldefaultNoneenv_idstr | NoneoptionaldefaultNone
- Returns
TokenResponse
sovaria.replace_product_user_roles
Replace a product user's app roles in the resolved scope.
await sovaria.replace_product_user_roles(
user_id: str,
roles: list[str],
*, org_id: str | None = None,
project_id: str | None = None,
env_id: str | None = None,
) -> dict[str, Any]Parameters
user_idstrrequiredroleslist[str]requiredorg_idstr | NoneoptionaldefaultNoneproject_idstr | NoneoptionaldefaultNoneenv_idstr | NoneoptionaldefaultNone
- Returns
dict[str, Any]
sovaria.revoke_other_sessions
Revoke other sessions.
await sovaria.revoke_other_sessions() -> dict[str, Any]- Returns
dict[str, Any]
sovaria.revoke_session
Revoke session.
await sovaria.revoke_session(session_id: str) -> dict[str, Any]Parameters
session_idstrrequired
- Returns
dict[str, Any]
sovaria.send_magic_link
Send a passwordless login link.
await sovaria.send_magic_link(
email: str,
*, org_id: str | None = None,
project_id: str | None = None,
redirect_to: str | None = None,
) -> dict[str, Any]redirect_to must be the Site URL or allow-listed.
Parameters
emailstrrequired- Where to send the link.
org_idstr | NoneoptionaldefaultNoneproject_idstr | NoneoptionaldefaultNoneredirect_tostr | NoneoptionaldefaultNone- Your page the link opens (Site URL or an allowed redirect).
- Returns
dict[str, Any]
- Succeeds whether or not the address has an account.
sovaria.send_otp
Send an SMS OTP code for phone-based login.
await sovaria.send_otp(
phone: str,
*, org_id: str | None = None,
project_id: str | None = None,
env_id: str | None = None,
) -> dict[str, Any]Parameters
phonestrrequiredorg_idstr | NoneoptionaldefaultNoneproject_idstr | NoneoptionaldefaultNoneenv_idstr | NoneoptionaldefaultNone
- Returns
dict[str, Any]
sovaria.send_verification_email
Trigger a verification email for the authenticated user.
await sovaria.send_verification_email() -> dict[str, Any]- Returns
dict[str, Any]
sovaria.sign_in
Sign an app user in with email and password (same as project_login).
await sovaria.sign_in(email: str, password: str) -> TokenResponseParameters
emailstrrequired- The user's email.
passwordstrrequired- Their password.
- Returns
TokenResponse
try:
await sovaria.sign_in(email, password)
except SovariaError as err:
if err.status_code == 401:
print("Wrong email or password")
else:
raisesovaria.sign_up
Create an app user and sign them in (unless the project requires email confirmation).
await sovaria.sign_up(
email: str,
password: str,
name: str = '',
) -> TokenResponseParameters
emailstrrequired- The user's email.
passwordstrrequired- Must meet the project's password rules.
namestroptionaldefault''- Display name.
- Returns
TokenResponse
403 SIGNUP_DISABLEDwhen new sign-ups are off.
sovaria.update_providers_config
Update providers config.
await sovaria.update_providers_config(
body: dict[str, Any],
) -> dict[str, Any]Parameters
bodydict[str, Any]required
- Returns
dict[str, Any]
sovaria.update_sessions_config
Update sessions config.
await sovaria.update_sessions_config(
body: dict[str, Any],
) -> dict[str, Any]Parameters
bodydict[str, Any]required
- Returns
dict[str, Any]
sovaria.verify_magic_link
Exchange a magic-link token for an access + refresh token pair.
Passwordless: session KEK is not derived unless password is supplied and the response includes argon2_salt.
await sovaria.verify_magic_link(
token: str,
password: str | None = None,
) -> TokenResponseParameters
tokenstrrequiredpasswordstr | NoneoptionaldefaultNone
- Returns
TokenResponse
sovaria.verify_mfa
Complete MFA using a pre-MFA challenge token from login.
await sovaria.verify_mfa(
code: str,
*, method: str = 'totp',
) -> TokenResponseParameters
codestrrequiredmethodstroptionaldefault'totp'
- Returns
TokenResponse
sovaria.verify_otp
Verify an SMS OTP code and establish a session.
Passwordless by default: pass password when argon2_salt is present if you need session-cached E2EE without a follow-up login.
await sovaria.verify_otp(
phone: str,
code: str,
*, org_id: str | None = None,
project_id: str | None = None,
env_id: str | None = None,
password: str | None = None,
) -> TokenResponseParameters
phonestrrequiredcodestrrequiredorg_idstr | NoneoptionaldefaultNoneproject_idstr | NoneoptionaldefaultNoneenv_idstr | NoneoptionaldefaultNonepasswordstr | NoneoptionaldefaultNone
- Returns
TokenResponse