stack/sdks/implementations/python
Ejiro Asiuwhu a26a68225e refactor: extract _get_actual_status helper to deduplicate header parsing
The x-stack-actual-status header was parsed with identical try/except
blocks in 4 places. Extracted into a single _get_actual_status() static
method on BaseAPIClient, used by _parse_response, _get_retry_delay,
and both sync/async request() loops.
2026-03-26 11:43:38 +01:00
..
src/stack_auth refactor: extract _get_actual_status helper to deduplicate header parsing 2026-03-26 11:43:38 +01:00
tests fix: address PR review findings from bot analysis 2026-03-26 09:01:06 +01:00
pyproject.toml docs: add module docstring with quick-start example and complete PyPI metadata 2026-03-25 02:05:44 +01:00
README.md fix: address PR review findings from bot analysis 2026-03-26 09:01:06 +01:00

Stack Auth Python SDK

Python SDK for Stack Auth — the open-source authentication platform. Provides StackServerApp for server-side user management, team operations, JWT verification, and more.

Installation

pip install stack-auth

Quick Start

from stack_auth import StackServerApp

app = StackServerApp(
    project_id="your-project-id",
    secret_server_key="your-secret-server-key",
)

# List users
users = app.list_users(limit=10)
for user in users.items:
    print(f"{user.display_name} ({user.primary_email})")

# Create a user
user = app.create_user(
    primary_email="user@example.com",
    password="securepassword",
    display_name="Jane Doe",
)

# Get a user
user = app.get_user("user-id")

# Update a user
updated = app.update_user("user-id", display_name="New Name")

# Delete a user
app.delete_user("user-id")

Async Support

Every method has an async equivalent via AsyncStackServerApp:

from stack_auth import AsyncStackServerApp

app = AsyncStackServerApp(
    project_id="your-project-id",
    secret_server_key="your-secret-server-key",
)

user = await app.get_user("user-id")
users = await app.list_users(limit=10)
team = await app.create_team(display_name="Engineering")

Authentication

Verify incoming request tokens without framework-specific middleware:

from stack_auth._auth import sync_authenticate_request
from stack_auth._jwt import SyncJWKSFetcher

fetcher = SyncJWKSFetcher(
    project_id="your-project-id",
    base_url="https://api.stack-auth.com",
)

# Works with any object that has a .headers mapping
result = sync_authenticate_request(request, fetcher=fetcher)

if result.status == "authenticated":
    print(f"User: {result.user_id}")
else:
    print("Not authenticated")

FastAPI Example

from fastapi import Depends, HTTPException, Request
from stack_auth._auth import sync_authenticate_request
from stack_auth._jwt import SyncJWKSFetcher

fetcher = SyncJWKSFetcher(project_id="...", base_url="https://api.stack-auth.com")

def get_user_id(request: Request) -> str:
    result = sync_authenticate_request(request, fetcher=fetcher)
    if result.status != "authenticated":
        raise HTTPException(status_code=401)
    return result.user_id

@app.get("/protected")
def protected_route(user_id: str = Depends(get_user_id)):
    return {"user_id": user_id}

Error Handling

All API errors raise typed exceptions:

from stack_auth.errors import (
    StackAuthError,
    AuthenticationError,
    NotFoundError,
    ValidationError,
)

try:
    user = app.get_user("invalid-id")
except NotFoundError as e:
    print(f"Not found: {e.message}")
except AuthenticationError as e:
    print(f"Auth failed: {e.code}")
except StackAuthError as e:
    print(f"API error: {e.code} - {e.message}")

Teams

# Create a team
team = app.create_team(
    display_name="Engineering",
    creator_user_id="user-id",
)

# List teams
teams = app.list_teams(user_id="user-id")

# Manage members
app.add_team_member(team_id=team.id, user_id="another-user-id")
profiles = app.list_team_member_profiles(team_id=team.id)

# Permissions
app.grant_team_permission(
    team_id=team.id,
    user_id="user-id",
    permission_id="admin",
)

Self-Hosted

Point to your self-hosted Stack Auth instance:

app = StackServerApp(
    project_id="your-project-id",
    secret_server_key="your-secret-key",
    base_url="https://your-stack-auth.example.com",
)

API Reference

StackServerApp / AsyncStackServerApp

Constructor:

  • project_id (str) — Your Stack Auth project ID
  • secret_server_key (str) — Server secret key from the dashboard
  • base_url (str, optional) — API base URL (default: https://api.stack-auth.com)
  • publishable_client_key (str, optional) — Required for projects with requirePublishableClientKey
  • token_store (optional) — Token storage strategy

User methods: get_user, list_users, create_user, update_user, delete_user, get_user_by_api_key, get_partial_user

Team methods: get_team, list_teams, create_team, update_team, delete_team, get_team_by_api_key, add_team_member, remove_team_member, list_team_member_profiles, get_team_member_profile, send_team_invitation, list_team_invitations, revoke_team_invitation

Permission methods: grant_team_permission, revoke_team_permission, list_team_permissions, grant_user_permission, revoke_user_permission, list_user_permissions

Session methods: list_sessions, get_session, revoke_session

Contact channel methods: send_contact_channel_verification, verify_contact_channel, check_contact_channel_verification

API key methods: create_user_api_key, list_user_api_keys, revoke_user_api_key, create_team_api_key, list_team_api_keys, revoke_team_api_key, check_api_key

OAuth methods: list_oauth_providers, create_oauth_provider, get_oauth_provider, list_connected_accounts

Payment methods: list_products, get_item, grant_product, cancel_subscription

Email methods: send_email, get_email_delivery_stats

Data vault: get_data_vault_store → returns DataVaultStore with get, set, delete, list_keys

Development

# Clone the repo
git clone https://github.com/stack-auth/stack-auth.git
cd stack-auth/sdks/implementations/python

# Install in dev mode
pip install -e ".[dev]"

# Run unit tests (no server needed)
python3 -m pytest tests/ -v

# Run E2E tests (requires running Stack Auth)
# First: pnpm start-deps && pnpm dev (from monorepo root)
STACK_E2E=1 python3 -m pytest tests/test_e2e.py -v -s

Requirements

  • Python >= 3.10
  • httpx
  • PyJWT[crypto]
  • pydantic >= 2.7

License

MIT — same as Stack Auth.