Skip to main content

Sweet Potato Authentication & Payment Service Python client

Project description


id: spaps-python-sdk title: Sweet Potato Python Client category: sdk tags:

  • sdk
  • python
  • client ai_summary: | Explains installation, configuration, and usage patterns for the spaps Python SDK, including environment setup, async support, and integration guidance for backend services. last_updated: 2025-10-14

Sweet Potato Python Client

Python SDK for the Sweet Potato Authentication & Payment Service (SPAPS).

This package is under active development. The sections below outline the supported surface area, test coverage, and release checks we use to keep the client aligned with the SPAPS API.

Installation

Install from PyPI:

pip install spaps

For local development inside this repository:

pip install -e .[dev]

Development

Source for the Python client lives in src/spaps_client/. Tests are split between tests/unit/ (feature coverage) and tests/integration/ (build/install guards). Use pytest directly during local TDD, or run the npm script npm run test:python-client from the repo root if you need the full harness. The repository npm scripts automatically install the dev extras (pip install -e .[dev]) before linting, typing, or testing so you do not have to manage that bootstrap step manually.

pytest

Quality Checks

Before opening a PR or publishing, run the standard gates:

  • npm run lint:python-client – ensures the ruff configuration passes
  • npm run typecheck:python-client – validates mypy typing coverage
  • npm run test:python-client – executes the pytest suite with respx mocks
  • npm run build:python-client – builds wheel/sdist and performs a twine check
  • npm run docs:validate-all – keeps the docs manifest in sync across SDKs
  • npm run publish:python-client – builds and uploads via twine (requires PYPI_TOKEN)

Available clients

  • AuthClient – wallet, email/password, and magic link flows
  • SessionsClient – current session, validation, listing, revocation
  • PaymentsClient – checkout sessions, wallet deposits, crypto invoices
  • UsageClient – feature usage snapshots, recording, aggregated history
  • SecureMessagesClient – encrypted message creation and retrieval
  • MetricsClient – health and metrics convenience helpers

Quickstart

from spaps_client import SpapsClient

spaps = SpapsClient(base_url="http://localhost:3300", api_key="test_key_local_dev_only")

# Authenticate (tokens are persisted automatically)
spaps.auth.sign_in_with_password(email="user@example.com", password="Secret123!")

# Call downstream services using the stored access token
current = spaps.sessions.get_current_session()
print(current.session_id)

checkout = spaps.payments.create_checkout_session(
    price_id="price_123",
    mode="subscription",
    success_url="https://example.com/success",
    cancel_url="https://example.com/cancel",
    require_legal_consent=True,
    legal_consent_text="I am 18+ and accept the HTMA Terms & Privacy.",
)
print(checkout.checkout_url)

spaps.close()

require_legal_consent forces Stripe’s Terms/Privacy checkbox. legal_consent_text is stripped to plain text, must be ≤120 characters, and defaults to “I agree to the Terms of Service and Privacy Policy.” when omitted.

Configure retry/backoff and structured logging when constructing the client:

from spaps_client import SpapsClient, RetryConfig, default_logging_hooks

spaps = SpapsClient(
    base_url="http://localhost:3300",
    api_key="test_key_local_dev_only",
    retry_config=RetryConfig(max_attempts=4, backoff_factor=0.2),
    logging_hooks=default_logging_hooks(),
)

Magic Link & Wallet Authentication

# Send a sign-in email
spaps.auth.send_magic_link(email="user@example.com")

# Later, exchange the token from the link for session tokens (persisted automatically)
magic_result = spaps.auth.verify_magic_link(token="token-from-email")
print(magic_result.user.email)

# Wallet flow (Solana/Ethereum)
nonce = spaps.auth.request_nonce(wallet_address="0xabc...", chain="ethereum")
signature = sign_message_with_wallet(nonce.message)  # your wallet integration
wallet_tokens = spaps.auth.verify_wallet(
    wallet_address="0xabc...",
    signature=signature,
    message=nonce.message,
    chain="ethereum",
)
print(wallet_tokens.user.wallet_address)

Current User Profile

profile = spaps.auth.get_current_user()
print(profile.id, profile.email, profile.tier)

Password Reset

spaps.auth.request_password_reset(email="user@example.com")

spaps.auth.confirm_password_reset(
    token="reset-token-from-email",
    new_password="Sup3rStrong!",
)

Product Catalog

catalog = spaps.payments.list_products(category="subscription", active=True, limit=10)
for product in catalog.products:
    print(product.name, product.default_price)

detail = spaps.payments.get_product("prod_123")
print(detail.prices[0].nickname)

Subscription & Billing Helpers

# Fetch active subscriptions for the current user
subs = spaps.payments.list_subscriptions(status="active")
print(subs.subscriptions[0].status)

# Inspect a specific subscription and switch to a new price
detail = spaps.payments.get_subscription(subscription_id="sub_123")
print(detail.plan.interval)

spaps.payments.update_subscription(subscription_id="sub_123", price_id="price_plus")

# Cancel immediately (versus at period end)
spaps.payments.cancel_subscription(subscription_id="sub_123", immediately=True)

Checkout Session Management

# Lookup previously created checkout sessions
session = spaps.payments.get_checkout_session(session_id="cs_test_123")
print(session.payment_status)

sessions = spaps.payments.list_checkout_sessions(limit=5)
print(len(sessions.sessions))

# Force-expire a stale session
spaps.payments.expire_checkout_session(session_id="cs_test_123")
# API-key-only guest checkout helpers
guest = spaps.payments.create_guest_checkout_session(
    customer_email="guest@example.com",
    mode="payment",
    line_items=[{"price_id": "price_basic", "quantity": 1}],
    success_url="https://example.com/success",
    cancel_url="https://example.com/cancel",
)

guest_detail = spaps.payments.get_guest_checkout_session(session_id=guest.id)
print(guest_detail.payment_status)

guest_sessions = spaps.payments.list_guest_checkout_sessions(limit=10)
print(guest_sessions.sessions[0].session_id)

Payment History

history = spaps.payments.list_payment_history(limit=20, status="succeeded")
for charge in history.payments:
    print(charge.id, charge.amount, charge.status)

detail = spaps.payments.get_payment_detail(payment_id="pi_123")
print(detail.metadata)

Async Quickstart

import asyncio
from spaps_client import AsyncSpapsClient

async def main():
    client = AsyncSpapsClient(base_url="http://localhost:3300", api_key="test_key_local_dev_only")
    try:
        await client.auth.sign_in_with_password(email="user@example.com", password="Secret123!")
        current = await client.sessions.list_sessions()
        print(len(current.sessions))
    finally:
        await client.aclose()

asyncio.run(main())

Async helpers mirror the synchronous API:

nonce = await client.auth.request_nonce(wallet_address="0xabc...", chain="solana")
signature = await sign_message_async(nonce.message)
await client.auth.verify_wallet(
    wallet_address="0xabc...",
    signature=signature,
    message=nonce.message,
    chain="solana",
)
profile = await client.auth.get_current_user()
print(profile.username)

Permission Utilities

from spaps_client import PermissionChecker

checker = PermissionChecker(customAdmins=["founder@example.com"])
role = checker.getRole("user@example.com")
if checker.requiresAdmin({"email": "user@example.com"}):
    raise PermissionError(checker.getErrorMessage("admin", role, action="change billing settings"))

Documentation Notes

Additional API references under docs/api/ include Python usage snippets for sessions, payments, usage, whitelist, and secure messages. Those guides ship with the repository; clone the project if you need the full documentation set.

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

spaps-0.1.4.tar.gz (54.6 kB view details)

Uploaded Source

Built Distribution

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

spaps-0.1.4-py3-none-any.whl (51.9 kB view details)

Uploaded Python 3

File details

Details for the file spaps-0.1.4.tar.gz.

File metadata

  • Download URL: spaps-0.1.4.tar.gz
  • Upload date:
  • Size: 54.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.12

File hashes

Hashes for spaps-0.1.4.tar.gz
Algorithm Hash digest
SHA256 19a173c7c6f29cc4905e9ad4034ac80b16d871a5812b7b68010db8d8a61c7afc
MD5 ca76e2afaceccf39aff55f1186f763fd
BLAKE2b-256 5d1da5c080968f37b637ebcc8631c528bb1a39ede0eb45e1a85c0e9f6c02f5e4

See more details on using hashes here.

File details

Details for the file spaps-0.1.4-py3-none-any.whl.

File metadata

  • Download URL: spaps-0.1.4-py3-none-any.whl
  • Upload date:
  • Size: 51.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.12

File hashes

Hashes for spaps-0.1.4-py3-none-any.whl
Algorithm Hash digest
SHA256 d10603ad5650561cbba4a9fef5f335600cdad43dd5533395b103f642e41672b1
MD5 fd0bc6c83e78ec35dddd4a351d5796c1
BLAKE2b-256 feb5331ba4632dcb3ca29c66ef0eceb0d165944d6abc3f50ab3417017be8550f

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