Skip to main content

Official Python SDK for the TruAgents Unsubscribe API.

Project description

truagents — Python SDK for the TruAgents Unsubscribe API

PyPI version Python versions CI

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

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

truagents-0.1.0.tar.gz (34.6 kB view details)

Uploaded Source

Built Distribution

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

truagents-0.1.0-py3-none-any.whl (57.6 kB view details)

Uploaded Python 3

File details

Details for the file truagents-0.1.0.tar.gz.

File metadata

  • Download URL: truagents-0.1.0.tar.gz
  • Upload date:
  • Size: 34.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for truagents-0.1.0.tar.gz
Algorithm Hash digest
SHA256 b41b530bd7072b96fe22c72047338c4240a4f0a1d4652db8ead9d0be2eaf1983
MD5 6f2dc1943f3da30e0b31a536241b83f3
BLAKE2b-256 2b47c8e713455a4e016e4a61b8c56120d581949f80217c662cfa7c62c3e22bf1

See more details on using hashes here.

Provenance

The following attestation bundles were made for truagents-0.1.0.tar.gz:

Publisher: release-python.yml on ablt-ai/truagents-sdk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file truagents-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: truagents-0.1.0-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.12

File hashes

Hashes for truagents-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6a991f7eafdf0249716f6f6f952823135eae71c5ce63191285074ba992738689
MD5 7c9b4c89cc7f8b7800bc849ac2228c47
BLAKE2b-256 a6e76ed5f8ff91b0c6172a7fc30982f577f7c458160e46a1682c564f803242b9

See more details on using hashes here.

Provenance

The following attestation bundles were made for truagents-0.1.0-py3-none-any.whl:

Publisher: release-python.yml on ablt-ai/truagents-sdk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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