PPUSSH Ecosystem SDK — Accounts (OIDC) + Payments client for Python
Project description
ppussh
Official Python SDK for the PPUSSH platform — Accounts (OIDC / OAuth 2.0) and Payments in a single, async-first client.
Requirements
- Python 3.12+
- An Accounts client_id and client_secret (obtain from the Accounts admin console)
- A running instance of the Accounts and Payments services (typically behind the API gateway)
Installation
pip install ppussh
Configuration
The SDK authenticates as your product — it uses your client_id /
client_secret for the OAuth token exchange and product/admin API keys for
Payments calls. It never forwards end-user tokens: your product backend issues
its own session cookies from the token returned by exchange_code().
In a standard deployment every call goes through the API gateway, which validates JWTs and injects service-to-service headers:
| Environment variable | Purpose |
|---|---|
PPUSSH_ACCOUNTS_URL |
Gateway base URL (proxies /oauth/, /users/, … to Accounts) |
PPUSSH_ACCOUNTS_FRONTEND_URL |
Accounts frontend base URL (the login page users see) |
PPUSSH_PAYMENTS_URL |
Gateway /payments prefix (e.g. https://gw/payments) |
PPUSSH_GATEWAY_URL |
Optional, stored for reference (defaults to accounts_url) |
PPUSSH_PAYMENTS_ADMIN_KEY |
Optional admin key for Payments admin endpoints |
export PPUSSH_ACCOUNTS_URL="https://api.example.com"
export PPUSSH_ACCOUNTS_FRONTEND_URL="https://accounts.example.com"
export PPUSSH_PAYMENTS_URL="https://api.example.com/payments"
Quick start
from ppussh import PpusshClient
client = PpusshClient(
client_id="your-product-client-id",
client_secret="your-product-client-secret",
payments_product_key="your-payments-product-key", # optional; only if Payments is active
payments_admin_key="your-payments-admin-key", # optional; only for admin calls
)
OIDC callback (FastAPI example)
from fastapi import FastAPI, Query
from ppussh import PpusshClient
app = FastAPI()
client = PpusshClient(client_id="...", client_secret="...")
REDIRECT_URI = "https://yourapp.example.com/auth/callback"
@app.get("/auth/callback")
async def callback(code: str = Query(...)):
token = await client.accounts.exchange_code(code, redirect_uri=REDIRECT_URI)
# The SDK authenticated AS the product; token.user is the logged-in user.
# Set your own session cookie from token.user.id / token.access_token.
return {"user_id": token.user.id, "email": token.user.email}
Login redirect
import secrets
state = secrets.token_urlsafe(16)
login_url = client.accounts.build_login_url(redirect_uri=REDIRECT_URI, state=state)
# → redirect the browser to login_url
Billing — create a customer and subscription
from uuid import uuid4
customer = await client.payments.create_customer(
owner_user_id=token.user.id,
workspace_id="ws-123", # optional
)
plans = await client.payments.list_plans(payment_product_id="prod-abc")
subscription = await client.payments.create_subscription(
customer_id=customer.id,
payment_product_id="prod-abc",
plan_key="pro",
idempotency_key=str(uuid4()),
)
Async context manager (scripts / one-off usage)
async with PpusshClient(client_id="...", client_secret="...") as client:
token = await client.accounts.exchange_code(code, redirect_uri=REDIRECT_URI)
For long-lived services, call await client.aclose() during application
shutdown to drain the connection pool.
Error handling
All exceptions are subclasses of PpusshError:
from ppussh import (
PpusshError, # base class
PpusshAuthError, # 401 — invalid or expired token / credentials
PpusshConsentRequired,# 403 — user hasn't consented to this product's scopes
PpusshPaymentError, # non-2xx from the Payments service
PpusshNetworkError, # all retries exhausted / connection failure
)
try:
token = await client.accounts.exchange_code(code, redirect_uri=REDIRECT_URI)
except PpusshConsentRequired as exc:
redirect_to_consent(exc.client_id, exc.product_name)
except PpusshAuthError:
...
except PpusshNetworkError:
...
Retry policy
| Condition | Behaviour |
|---|---|
| 5xx / network error | Up to 3 attempts, exponential backoff (0.5 s, 1 s, 2 s) |
| 429 Too Many Requests | Respects Retry-After header, max 2 retries |
| 4xx (not 429) | Never retried — raises immediately |
API reference
client.accounts
| Method | Description |
|---|---|
build_login_url(redirect_uri, state, *, next_url?) |
Build the Accounts login redirect URL |
exchange_code(code, redirect_uri, *, state?, next_url?) |
Exchange an auth code for a token (OIDC callback) |
client.payments
| Method | Auth | Description |
|---|---|---|
create_customer(owner_user_id, ...) |
product key | Create or retrieve a customer record |
get_customer(customer_id) |
product key | Fetch a customer by ID |
create_subscription(...) |
product key | Create a subscription |
list_subscriptions(customer_id, ...) |
product key | List subscriptions for a customer |
get_subscription(subscription_id) |
product key | Fetch a subscription by ID |
cancel_subscription(subscription_id, ...) |
product key | Cancel a subscription |
list_plans(payment_product_id) |
product key | List billing plans |
create_checkout_session(...) |
product key | Create a checkout session (returns checkout_url) |
check_access(user_id, feature_code, ...) |
product key | Feature access check |
get_paddle_config() |
public | Paddle client token + environment |
get_product_by_accounts_id(accounts_product_id) |
admin key | Resolve a payments product by its Accounts ID |
get_mrr(...) |
admin key | Fetch MRR analytics |
get_billing_portal(customer_id, ...) |
— | Not yet implemented (raises NotImplementedError) |
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ppussh-0.3.0.tar.gz.
File metadata
- Download URL: ppussh-0.3.0.tar.gz
- Upload date:
- Size: 18.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
23a473779df9b8bdae6a89b1be79dad95876370a9edf1bf83a95745d9bf540bf
|
|
| MD5 |
5180521fba0838303e5731bde8b7a568
|
|
| BLAKE2b-256 |
160c1debbdebfe5290cea1c43f2f724bb426d3a272a16a2fbaa0701fcd6ec7c7
|
File details
Details for the file ppussh-0.3.0-py3-none-any.whl.
File metadata
- Download URL: ppussh-0.3.0-py3-none-any.whl
- Upload date:
- Size: 24.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f8042bd4e0d284110c9e51f4304df03af0d76d89e5cafa41b8c11f42f3d3202f
|
|
| MD5 |
0fe166beb01d7a9577ed7a6766237e8f
|
|
| BLAKE2b-256 |
3fbdb64eee9df9c378b09c3eb23ad21f0f48d212d6b9552dfff0f0a0c6cc319c
|