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.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| tausi-0.2.0.tar.gz | 24.8 kB | With provenance | Details for tausi-0.2.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| tausi-0.2.0-py3-none-any.whl | Python 3 | none | any | Details for tausi-0.2.0-py3-none-any.whl |
Total release size: 50.2 kB
Release files / tausi-0.2.0.tar.gz
| Download URL | tausi-0.2.0.tar.gz |
|---|---|
| Size | 24.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ed9db0f61c651156b7392f533e14407ce4fc3381d60e57ceaffb3d7307aa2d15
|
|
BLAKE2b-256 checksum How to use checksums |
4d2882af9d80ce284da26b2a17a423a3dac940e09692de684669fa5f48faf609
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 5, 2026.
Transparency logRelease files / tausi-0.2.0-py3-none-any.whl
| Download URL | tausi-0.2.0-py3-none-any.whl |
|---|---|
| Size | 25.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
87b184f3b5ec3fa884e938dec2345b2112064e87f57e4498eb4a400782e61d8b
|
|
BLAKE2b-256 checksum How to use checksums |
c16481bf20ffe90833913153ddff413dd8f4b67be8ad5d081254c36c3cfd0915
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 5, 2026.
Transparency logSecurity for tausi 0.2.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.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for tausi-0.2.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 5, 2026.
Transparency logA 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.