Skip to main content

Python SDK for usethatapp.com — verify launch envelopes and query user license tiers.

Project description

usethatapp

Python SDK for usethatapp.com. Verifies the encrypted+signed launch envelope the marketplace POSTs to your app and lets you pull the user's current license tier on demand.

Framework-agnostic. Use with Django, Flask, FastAPI, Starlette, Dash, Streamlit, Pyramid, Bottle, AIOHTTP, plain WSGI, or a CLI. The only runtime dependencies are cryptography and httpx. A Django helper is shipped, but only imported when Django is installed.

v1.0 is a breaking rewrite. The old browser-side usethatapp.js / requestAccessLevel() / iframe handshake has been removed. See CHANGELOG.md for migration notes.

How it works

usethatapp.com uses a two-phase, license-centric handoff:

  1. Launch (one-way push). When a user clicks Launch app on usethatapp.com, the marketplace POSTs an encrypted+signed envelope to your app's URL. The envelope carries an opaque user_key. Your app verifies + decrypts it, persists user_key against its own session, and renders your UI.
  2. Query (server-to-server pull). Whenever your app needs the user's current license tier, it POSTs a signed request to https://usethatapp.com/licensing/getversion/ with the user_key and gets back the live product name (or null).

Install

pip install usethatapp

Requires Python 3.9+. Runtime deps: cryptography, httpx. No web framework required.

Settings

The SDK reads from django.conf.settings only if Django is installed and configured; otherwise it falls back to environment variables. Non-Django users just export these:

Name Required Purpose
UTA_APP_ID yes Your app's UUID on usethatapp.com.
UTA_PRIVATE_KEY yes† Your RSA-2048 private key (PEM string or RSAPrivateKey object).
UTA_PRIVATE_KEY_PATH yes† Filesystem path to a PEM file containing the private key. †Set this or UTA_PRIVATE_KEY.
UTA_MARKET_PUBLIC_KEY yes* Marketplace public key (PEM string or RSAPublicKey). *A production default is bundled.
UTA_MARKET_PUBLIC_KEY_PATH no Filesystem path to a PEM file containing the marketplace public key (alternative to UTA_MARKET_PUBLIC_KEY).
UTA_API_URL no Defaults to https://usethatapp.com.
UTA_CLOCK_SKEW_SECONDS no Defaults to 60.
UTA_REQUEST_TIMEOUT_SECONDS no Defaults to 10.

The *_PATH variants are intended for hosting providers that mount secret files into the container (Render Secret Files, Fly.io volumes, Kubernetes secret volumes, GCP Secret Manager volume mounts, etc.). The SDK reads the file at boot. If both the direct setting and the path setting are provided for the same key, the direct value wins.

Public API

Three functions cover every integration:

from usethatapp import (
    get_user,                       # framework-agnostic: takes the raw uta_payload str/dict
    get_user_from_request,          # auto-detects Django / Flask / Werkzeug requests
    get_user_from_request_async,    # for Starlette / FastAPI (await)
    get_version,                    # signed server-to-server license-tier lookup
    get_version_async,              # async variant
    UtaUser,                        # frozen dataclass: user_key, app_id, iat, exp, version_hint
    # typed errors:
    UtaError, UtaSignatureError, UtaPayloadExpiredError,
    UtaAppMismatchError, UtaBadRequestError, UtaSessionRevokedError,
    UtaUnknownSessionError, UtaServerError, UtaConfigError,
    # Django-only (imported lazily — present only if Django is installed):
    uta_launch_view,
)

UtaUser carries only the opaque user_key — no PII. Persist it against your own session; pass it to get_version whenever you need the live license tier.

Quickstart — any framework

from usethatapp import get_user, get_version, UtaError

# In your POST handler — however your framework spells it:
raw_payload = read_form_field("uta_payload")  # str
try:
    uta_user = get_user(raw_payload)
except UtaError as e:
    return bad_request(str(e))

save_to_session("uta_user_key", uta_user.user_key)

# Later, anywhere in your app:
version = get_version(load_from_session("uta_user_key"))  # str | None

Framework examples

Runnable single-file examples for each major framework live under examples/:

uta_user.version_hint is not the source of truth. Use it only for first paint. The authoritative value comes from get_version(user_key).

Error mapping

get_version maps server status codes to typed exceptions:

Status Exception Meaning
400 UtaBadRequestError Bad JSON / ts outside window / replay.
401 UtaSignatureError Signature verification failed.
403 UtaSessionRevokedError Treat as "user logged out".
404 UtaUnknownSessionError Unknown user_key or app_id.
5xx UtaServerError Retriable with backoff.

All inherit from UtaError — catch that for a single except clause.

License

MIT — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

usethatapp-1.0.0.tar.gz (26.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

usethatapp-1.0.0-py3-none-any.whl (17.3 kB view details)

Uploaded Python 3

File details

Details for the file usethatapp-1.0.0.tar.gz.

File metadata

  • Download URL: usethatapp-1.0.0.tar.gz
  • Upload date:
  • Size: 26.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.8

File hashes

Hashes for usethatapp-1.0.0.tar.gz
Algorithm Hash digest
SHA256 71cc887e24663ed43433952a5ef93b39a291900d2662ff9bff8e6b077841a265
MD5 9a360d15054bf638c87818a211ad86bf
BLAKE2b-256 aa1f80c91d2d2ce2c35ee11937d3d8c98c449baedcbc560d45d5e53e38df85a4

See more details on using hashes here.

File details

Details for the file usethatapp-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: usethatapp-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 17.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.8

File hashes

Hashes for usethatapp-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 86b787faa5bd95f73104abefef188c2c12bd4a88a03d6d73dd8b0402da3ac7ab
MD5 19b3d5a4538ddb3d52cea909b175175b
BLAKE2b-256 9fda81f54bc3da85788b4a3f5b58784847f5c8bb8c83abb87703ef48d559d00e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page