Official Python SDK for the TruAgents Unsubscribe API.
Project description
truagents — Python SDK for the TruAgents Unsubscribe API
Official Python SDK for the TruAgents Unsubscribe API. Handles OAuth token acquisition and refresh, retries, rate limiting, and observability so you can focus on the business logic.
Install
pip install truagents
Requires Python >= 3.11.
Quickstart (sync)
from truagents import Client
with Client(client_id="...", client_secret="...") as client:
resp = client.list_email_unsubscribes()
for record in resp.data:
print(record.email, record.unsubscribed)
Quickstart (async)
import asyncio
from truagents import AsyncClient
async def main() -> None:
async with AsyncClient(client_id="...", client_secret="...") as client:
resp = await client.list_email_unsubscribes()
for record in resp.data:
print(record.email, record.unsubscribed)
asyncio.run(main())
Authentication
TokenManager (owned by the client) mints an access token via
client_credentials on the first request and refreshes it via refresh_token
refresh_threshold_seconds before the server-side expiry (default: 60s).
Concurrent callers are de-duplicated: a thundering herd of sync threads or
async coroutines results in a single /oauth/token round-trip.
If the cached refresh token is rejected with invalid_grant (RFC 6749 §5.2
family revoke), the manager transparently drops it and re-mints via
client_credentials. Partners never see the intermediate InvalidGrant.
A mid-flight TokenExpired (HTTP 401) on an API endpoint is NOT
auto-remedied. It signals that your credentials were revoked externally and
you need to investigate. This is a deliberate design decision — silently
re-minting on 401 would mask real revocations.
Retries + rate limiting
Every request goes through a shared RetryPolicy:
| Failure | Retry? |
|---|---|
NetworkError |
Yes — up to max_attempts with exp. back-off |
ServerError (5xx) |
Yes — up to max_attempts with exp. back-off |
RateLimited (HTTP 429) |
Yes — honours Retry-After (capped at 60s) |
InvalidRequest (HTTP 400) |
No |
NotFound (HTTP 404) |
No |
TokenExpired (HTTP 401) |
No |
Override defaults by constructing your own RetryPolicy:
from truagents import Client, RetryPolicy
policy = RetryPolicy(max_attempts=5, base_delay=0.1, retry_after_cap=30.0)
client = Client(client_id="...", client_secret="...", retry=policy)
Observability hooks
Hooks fire around every HTTP call (token endpoint and API endpoint alike).
Broken hooks never break an SDK call — they are logged and swallowed.
from truagents import Client, Hooks, Request, Response
def log_request(req: Request) -> None:
print(f"-> {req.method} {req.url}")
def log_response(resp: Response, elapsed_ms: float) -> None:
print(f"<- {resp.status_code} ({elapsed_ms:.0f}ms)")
hooks = Hooks(on_request=log_request, on_response=log_response)
client = Client(client_id="...", client_secret="...", hooks=hooks)
Error handling
All SDK exceptions inherit from truagents.errors.TruAgentsError.
| Exception | Raised when |
|---|---|
AuthError |
Base of OAuth token endpoint failures. |
InvalidClient |
Token endpoint returned 401 (bad client_id/secret). |
InvalidGrant |
Token endpoint returned 400 invalid_grant. Almost always caught + recovered internally. |
TokenExpired |
API endpoint returned 401 (external revocation). |
APIError |
Base of API endpoint failures. |
InvalidRequest |
API endpoint returned 400. |
NotFound |
API endpoint returned 404. |
RateLimited |
API endpoint returned 429. Carries retry_after. |
ServerError |
API endpoint returned 5xx. |
NetworkError |
Transport failure (DNS, connection reset, timeout). Wraps the underlying httpx exception. |
Every subclass carries a code class variable (e.g. "INVALID_CLIENT") so
you can log it without importing the class.
Version stability
The SDK is at 0.x. Minor bumps may introduce breaking changes. See
docs/versioning.md at the repository root for
the full policy and the 1.0.0 promotion criteria.
Links
- Homepage: https://github.com/ablt-ai/truagents-sdk
- Docs: https://docs.truagents.com
- Issues: https://github.com/ablt-ai/truagents-sdk/issues
- License: Apache 2.0 (see
LICENSE)
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 truagents-0.1.1.tar.gz.
File metadata
- Download URL: truagents-0.1.1.tar.gz
- Upload date:
- Size: 34.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d357405e1d8584f47717eed6eb661cdbfc29e7317c9264e19d27269edbec0360
|
|
| MD5 |
4b8d30c2c0c689805cb402cab7fbb626
|
|
| BLAKE2b-256 |
e5fe8e7cd572655ef8bab52dcd68bce4754eb7c05eb5047a204b84d5890288b1
|
Provenance
The following attestation bundles were made for truagents-0.1.1.tar.gz:
Publisher:
release-python.yml on ablt-ai/truagents-sdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
truagents-0.1.1.tar.gz -
Subject digest:
d357405e1d8584f47717eed6eb661cdbfc29e7317c9264e19d27269edbec0360 - Sigstore transparency entry: 2165272073
- Sigstore integration time:
-
Permalink:
ablt-ai/truagents-sdk@19b38980cd6af93fb178a517a2c61dbb2b59b637 -
Branch / Tag:
refs/tags/sdk-python-v0.1.1 - Owner: https://github.com/ablt-ai
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-python.yml@19b38980cd6af93fb178a517a2c61dbb2b59b637 -
Trigger Event:
push
-
Statement type:
File details
Details for the file truagents-0.1.1-py3-none-any.whl.
File metadata
- Download URL: truagents-0.1.1-py3-none-any.whl
- Upload date:
- Size: 57.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
36190e7515798d76e281b495e6364eec61ee27e5f0dd7b196b484a9a4fce6869
|
|
| MD5 |
ee83d15a0da308d3f603363de259a4aa
|
|
| BLAKE2b-256 |
f01a93384d192fd42a79b580ef615a7975364273eb3a6e685c04accb4ee6e900
|
Provenance
The following attestation bundles were made for truagents-0.1.1-py3-none-any.whl:
Publisher:
release-python.yml on ablt-ai/truagents-sdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
truagents-0.1.1-py3-none-any.whl -
Subject digest:
36190e7515798d76e281b495e6364eec61ee27e5f0dd7b196b484a9a4fce6869 - Sigstore transparency entry: 2165272089
- Sigstore integration time:
-
Permalink:
ablt-ai/truagents-sdk@19b38980cd6af93fb178a517a2c61dbb2b59b637 -
Branch / Tag:
refs/tags/sdk-python-v0.1.1 - Owner: https://github.com/ablt-ai
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-python.yml@19b38980cd6af93fb178a517a2c61dbb2b59b637 -
Trigger Event:
push
-
Statement type: