Skip to Content
SPAPS is proprietary hosted SaaS. Paid access required; pre-1.0 contracts may change. Terms and access
PackagesPython Client

SPAPS Python Client

The Python client distribution name is spaps, and the import path is spaps_client.

Verified source surface: spaps 0.7.1 at Sweet Potato 5b09d3df1194577c5313c865fef1db98f694cdea, with Python 3.9 or newer. The API described below comes from packages/python-client/src/spaps_client; an installed or published package may lag the checkout.

Install vs Import

pip install spaps python -c "from importlib.metadata import version; print(version('spaps'))"
from spaps_client import SpapsClient, AsyncSpapsClient

Install name and import name are intentionally different: spaps (package) and spaps_client (module).

Sync And Async Aggregate Clients

Both aggregate clients expose a grouped API surface and shared token helpers (set_tokens, get_tokens, clear_tokens):

ClientMain grouped helpers
SpapsClientauth, sessions, payments, usage, whitelist, secure_messages, issue_reporting, metrics, support_telemetry
AsyncSpapsClientauth, sessions, payments, usage, whitelist, secure_messages, issue_reporting, metrics, entitlements, dayrate, users

Sync Example

from spaps_client import MfaRequiredChallenge, SpapsClient client = SpapsClient( base_url="http://localhost:3301", # Built-in key for local mode only; never deploy or reuse it in production. api_key="spaps_local_development_key", ) try: auth_result = client.auth.sign_in_with_password( email="user@example.com", password="correct-horse-battery-staple", ) if isinstance(auth_result, MfaRequiredChallenge): raise RuntimeError(f"Complete MFA challenge {auth_result.challenge_id} before API calls") if auth_result.user is None: raise RuntimeError("Sign-in returned tokens without a user projection") session = client.sessions.get_current_session() print(auth_result.user.email, session.session_id) finally: client.close()

Async Example

import asyncio from spaps_client import AsyncSpapsClient, MfaRequiredChallenge async def main() -> None: client = AsyncSpapsClient( base_url="http://localhost:3301", # Built-in key for local mode only; use a provisioned secret key elsewhere. api_key="spaps_local_development_key", ) try: auth_result = await client.auth.sign_in_with_password( email="user@example.com", password="correct-horse-battery-staple", ) if isinstance(auth_result, MfaRequiredChallenge): raise RuntimeError( f"Complete MFA challenge {auth_result.challenge_id} before API calls" ) items = await client.issue_reporting.list_issue_reports(limit=10) print(items.total) finally: await client.aclose() asyncio.run(main())

Helper Clients And Utilities

The package also exports narrower helpers when you do not want the aggregate clients:

HelperPurpose
EntitlementsClient, AsyncEntitlementsClientEntitlement list/check/claim/history and admin grant/revoke flows
IssueReportingClient, AsyncIssueReportingClientIssue status/history/create/update/reply and voice-token support
EmailClient, AsyncEmailClientTemplate list/preview/send
UsersClient, AsyncUsersClientBatch email and user lookup helpers
DeviceFlowClientOAuth device flow (/api/cli/device/authorize, /api/cli/device/token)
PermissionChecker and related helpersRole/admin permission checks
verify_spaps_webhookSPAPS webhook signature verification
verify_crypto_webhook_signatureCrypto webhook signature verification

Retry, Logging, And Token Storage

spaps_client.http exposes RetryConfig, LoggingHooks, and default_logging_hooks. Token persistence is available via TokenStorage implementations:

  • InMemoryTokenStorage
  • FileTokenStorage (defaults to ~/.config/spaps/tokens.json)
from spaps_client import ( FileTokenStorage, RetryConfig, SpapsClient, default_logging_hooks, ) client = SpapsClient( base_url="https://api.example.test", api_key="spaps_sec_example", retry_config=RetryConfig(max_attempts=4, backoff_factor=0.2), logging_hooks=default_logging_hooks(), token_storage=FileTokenStorage(), )

Device Flow

DeviceFlowClient implements RFC 8628-style device authorization for CLI/headless flows.

from spaps_client import DeviceFlowClient flow = DeviceFlowClient( base_url="https://api.example.test", client_id="application-slug", api_key="spaps_pub_example", ) # start() -> returns user_code + verification_uri # poll() -> waits for token issuance

Webhook Verification

from spaps_client import verify_spaps_webhook payload = verify_spaps_webhook( body=request_body_bytes, signature=request_headers["X-SPAPS-Signature"], secret="whsec_example", ) print(payload.type)

Issue Reporting Surface

IssueReportingClient and AsyncIssueReportingClient expose:

  • get_issue_report_status
  • list_issue_reports
  • get_issue_report
  • create_issue_report
  • update_issue_report
  • reply_to_issue_report
  • create_voice_token

Use create_voice_token for browser voice-input integrations so the browser gets a short-lived token from SPAPS instead of a long-lived provider secret.

Entitlements Surface

EntitlementsClient and AsyncEntitlementsClient expose:

  • get_user_entitlements
  • check_access
  • claim_pending
  • get_purchase_history
  • get_changes
  • grant_manual and revoke (admin flows)

These helper clients are useful when you want entitlement logic outside the aggregate client surface.

Validation

From the monorepo root:

npm run lint:python-client npm run typecheck:python-client npm run test:python-client

From packages/python-client:

pip install -e '.[dev]'

Pair this page with Issue reporting and support and Billing and entitlements for backend contract details.