Skip to main content

tausi (Python)

Official Python SDK for Tausi, with Django, Django REST framework and Flask integrations. It needs Python 3.9 or later and has no runtime dependencies: it uses the standard library for HTTP.

Key Use it for
tausi.TausiBackend secret key sk_… Protecting your API (verifying session tokens) and managing your project's users.
tausi.TausiClient publishable key pk_… Server-rendered apps where Python signs the user in and keeps their token in the session, plus scripts and CLIs.
pip install tausi            # core
pip install "tausi[django]"  # + Django
pip install "tausi[flask]"   # + Flask

Protect your API

Your frontend (built with @tausi-auth/js, Flutter, etc.) sends the user's session token as Authorization: Bearer <token>. Your backend checks it with the secret key:

import os
from tausi import TausiBackend

tausi = TausiBackend("https://tausi.app", os.environ["TAUSI_SECRET_KEY"])

auth = tausi.authenticate_request(request)   # any request with .headers, or the header value itself
if auth is None:
    ...                                       # 401
print(auth.user.id, auth.user.email, auth.session.expires_at)

authenticate_request() and verify_session(token) return None when a token is invalid, expired, revoked or belongs to another project. They raise TausiError only when the problem is on your side: a wrong key, a network failure or a 5xx response.

Django

# settings.py
TAUSI_URL = "https://tausi.app"
TAUSI_SECRET_KEY = os.environ["TAUSI_SECRET_KEY"]

# views.py
from django.http import JsonResponse
from tausi.django import tausi_required, tausi_optional

@tausi_required                   # 401 JSON without a valid token; works on async views too
def me(request):
    return JsonResponse(request.tausi.user.to_dict())

@tausi_optional                   # request.tausi is an AuthResult or None
def feed(request):
    ...

To set request.tausi on every request, add "tausi.django.TausiAuthMiddleware" to MIDDLEWARE. Only requests that carry a bearer token cost a call to Tausi. When Tausi can't be reached, the decorators and middleware answer 503 with code AUTH_UNAVAILABLE.

Each setting falls back to the environment variable of the same name (TAUSI_URL, TAUSI_SECRET_KEY, TAUSI_PUBLISHABLE_KEY). TAUSI_TIMEOUT sets the request timeout in seconds (default 10).

Django REST framework

REST_FRAMEWORK = {
    "DEFAULT_AUTHENTICATION_CLASSES": ["tausi.django.rest_framework.TausiAuthentication"],
    "DEFAULT_PERMISSION_CLASSES": ["rest_framework.permissions.IsAuthenticated"],
}

In views, request.user is a tausi.User (with is_authenticated = True) and request.auth is the full AuthResult. Requests without a bearer token fall through to your other authentication classes.

Flask

from flask import Flask, g
from tausi.flask import Tausi

app = Flask(__name__)
app.config["TAUSI_URL"] = "https://tausi.app"
app.config["TAUSI_SECRET_KEY"] = os.environ["TAUSI_SECRET_KEY"]
tausi = Tausi(app)                # or tausi = Tausi(); tausi.init_app(app)

@app.get("/api/me")
@tausi.required                   # 401 JSON without a valid token
def me():
    return g.tausi.user.to_dict()

@app.get("/api/feed")
@tausi.optional                   # g.tausi is an AuthResult or None
def feed():
    ...

Manage users

page = tausi.users.list(q="asha", verified=True, page=1, page_size=50)   # Page[User]
for user in page.items:
    print(user.email, user.status, user.active_sessions, user.last_sign_in_at)

detail = tausi.users.get(user_id)        # {"user": User, "accounts": [...], "sessions": [...], "recentAudit": [...]}
tausi.users.update(user_id, name="Asha", email_verified=True)
tausi.users.revoke_sessions(user_id)     # sign out everywhere
tausi.users.delete(user_id)
tausi.sessions.list(page=1)
tausi.get_project()                      # startup check that the key works

From Django you get the configured backend with tausi.django.get_backend(); from Flask, tausi.backend inside an app context.

Server-rendered sign-in

When your Python app renders the sign-in form itself, use TausiClient with the publishable key. The token stays in the server-side session and never reaches the browser.

Django

# settings.py: TAUSI_PUBLISHABLE_KEY = os.environ["TAUSI_PUBLISHABLE_KEY"], plus SessionMiddleware
from django.shortcuts import redirect, render
from tausi import TausiError
from tausi.django import get_client, tausi_login_required

def sign_in(request):
    if request.method == "POST":
        try:
            get_client(request).sign_in(request.POST["email"], request.POST["password"])
            return redirect(request.GET.get("next", "/"))
        except TausiError as e:
            return render(request, "sign_in.html", {"error": e.message, "code": e.code})
    return render(request, "sign_in.html")

def sign_out(request):
    get_client(request).sign_out()
    return redirect("/")

@tausi_login_required             # redirects to settings.LOGIN_URL with ?next=
def dashboard(request):
    return render(request, "dashboard.html", {"user": request.tausi.user})

Flask

@app.post("/sign-in")
def login():
    try:
        tausi.client().sign_in(request.form["email"], request.form["password"])
    except TausiError as e:
        return render_template("sign_in.html", error=e.message), 400
    return redirect(request.args.get("next", "/"))

@app.get("/dashboard")
@tausi.login_required(login_endpoint="login")
def dashboard():
    return render_template("dashboard.html", user=g.tausi.user)

Social sign-in (PKCE)

def start_google(request):
    start = get_client(request).start_oauth("google", redirect_to="https://example.com/auth/callback")
    request.session["tausi_verifier"] = start.code_verifier
    return redirect(start.url)

def callback(request):
    verifier = request.session.pop("tausi_verifier", "")
    try:
        get_client(request).handle_oauth_redirect(request.build_absolute_uri(), verifier)
    except TausiError as e:
        return render(request, "sign_in.html", {"error": e.message})
    return redirect("/")

redirect_to must be on one of the project's allowed origins.

All client methods

sign_up, sign_in, sign_out, get_session, send_verification_email, verify_email, forgot_password, reset_password, change_password, get_user, update_user, delete_account, list_sessions, revoke_session, revoke_other_sessions, get_providers, start_oauth, exchange_oauth_code, handle_oauth_redirect.

Outside a web framework, TausiClient keeps the token in memory. Pass token_store= with any object that has get() and set(token) to keep it elsewhere; MappingTokenStore(some_dict) stores it in a dict-like session.

Errors

Every failure is a TausiError with status, code, message, details, request_id and retry_after (seconds, for RATE_LIMITED). Network failures have status == 0 and code NETWORK_ERROR or TIMEOUT. Branch on code, not on the message.

try:
    client.sign_in(email, password)
except TausiError as e:
    if e.code == "EMAIL_NOT_VERIFIED":
        ...

Custom HTTP

The default transport is urllib from the standard library. To use requests, httpx or a test double, pass transport= to either client: a callable (method, url, headers, body, timeout) -> tausi.HttpResponse.

Development

python -m venv .venv && .venv/bin/pip install -e ".[dev]"
.venv/bin/pytest

Metadata

Release files for tausi 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for tausi 0.1.0
File Size Uploaded Provenance Actions
tausi-0.1.0.tar.gz 23.0 kB Without provenance Details for tausi-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for tausi 0.1.0
File Interpreter ABI Platform Actions
tausi-0.1.0-py3-none-any.whl Python 3 none any Details for tausi-0.1.0-py3-none-any.whl

Total release size: 47.2 kB

Release files / tausi-0.1.0.tar.gz

Download URL tausi-0.1.0.tar.gz
Size 23.0 kB
Tags Source
SHA-256 checksum
How to use checksums
8ceca36dd233feef80f0be3c263ebd7e4146d1c044446db356a74f10d5ada931
BLAKE2b-256 checksum
How to use checksums
0b0ba9ed3b4e7cc73bd044b9210687ff8065f02900b2c0f080ce93a9202bb539
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.8

Release files / tausi-0.1.0-py3-none-any.whl

Download URL tausi-0.1.0-py3-none-any.whl
Size 24.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
947e77e6faf47b8b5b51f590ebfe6b426335e7ad8f13178ff3cdb10bb066ffa5
BLAKE2b-256 checksum
How to use checksums
5d252e6371b2c81e4fce93d515ca5626b209a795cd67902bc5649b94309d4d44
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.8

Security for tausi 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page