Start in Observe on one route. Use the deployment URL and installed package version supplied for your workspace. Historical host examples and source capabilities do not establish a live service or published release.
Install the unpublished source or built package
mandate-python 0.1.0 is in sdks/python/; it is not released on PyPI.
Requires Python3.10+ and cryptography. Use a reviewed checkout or candidate wheel:
python -m pip install '/absolute/path/to/mandate/sdks/python[flask,fastapi]'Flask hosted adapter
import os
from flask import Flask, jsonify
from mandate.flask import require_mandate_hosted
from mandate.verify import HostedValidateOptions
app = Flask(__name__)
options = HostedValidateOptions(
site_secret=os.environ["MANDATE_SITE_SECRET"],
site_key=os.environ["MANDATE_SITE_KEY"],
api_key=os.environ["MANDATE_API_KEY"],
gate_url=os.environ["MANDATE_GATE_URL"],
credential_mode="cookie", credential_cookie_name="Mndt-Sess",
high_value=True, origin="https://app.example.com",
)
@app.post("/api/checkout")
@require_mandate_hosted(options, mode="observe")
def checkout():
return jsonify({"ok": True}) # application authentication remains requiredObserve permits the handler while recording the hosted result; enforce one route
only after reviewing real evidence. Keep authentication before the protected
business action. Missing configured Gate authority refuses locally.
FastAPI hosted adapter
validate_mandate_hosted(request, options) and hosted_response(result) are the
manual async helpers. The response adapter renders the documented refusal and
authenticated updates. If you assemble a successful response yourself, apply all
session/purpose-cookie, companion and native-state updates too; prefer the
Flask decorator for automatic updates, or explicitly call apply_hosted_updates on a FastAPI success response.
from fastapi.responses import JSONResponse
from mandate.fastapi import apply_hosted_updates
# result = await validate_mandate_hosted(request, options)
response = JSONResponse({"ok": True})
response = apply_hosted_updates(response, result)apply_hosted_updates preserves separate Set-Cookie fields and application
cookies; use only the validated result, before mutating it in application code.
The Flask decorator snapshots committed updates before the handler and preserves
them on an application exception. Neither helper retries the business request.
One-call managed wrappers
Flask require_mandate_managed and FastAPI managed_route_class use CLI-preset
connection state and one canonical v1/v2 decision call. Verify defaults on; Limit
is explicit and configured at Gate. Trusted Subject comes from server-side user
or account authentication. Off/valid unmatched routes proceed; malformed,
unavailable or ambiguous authority refuses. Observe proceed does not prove user
identity or browser verification. Native complete-state updates are preserved on
late errors; physical duplicate headers and conflicting body/header state refuse.
Do not follow a managed decision with a second validation/Limit charge.
Production browser credentials stay in an HttpOnly cookie. The repository
reader prefers _mndt and accepts legacy Mndt-Sess only when unambiguous;
the currently deployed writer uses Mndt-Sess. Match the live collector/Gate
configuration. Manual hosted helpers support credentialMode: "cookie" and
credentialCookieName: "Mndt-Sess" or "_mndt"; never rename a cookie without a
coordinated writer/reader rollout. Request proof uses x-md-vq, with legacy
x-mndt-req accepted. x-md-w, x-md-h and md_<seed> purpose cookies are
opaque, authenticated transport. Preserve SDK response updates and application
cookies. Do not copy credentials into page storage or logs.
Recovery and compatibility
Hosted scores remain internal. Branch on documented success/action; keep diagnostic
error/reason private. Enforced throttle/queue/fresh-proof/step-up/block map to
429/202/401/403/403; honor Retry-After and explicit customer retries with opaque
queue tokens. SDKs do not replay business actions.
Local verify_token/verify_request is only bounded legacy/test compatibility.
DEADMAN has its own exact scoped incident reader. Neither is a fallback for
unavailable hosted authority. See Backend and
sdks/python/examples/flask_hosted.py / fastapi_hosted.py.