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.2.0.tar.gz (35.3 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.2.0-py3-none-any.whl (58.0 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for truagents-0.2.0.tar.gz
Algorithm Hash digest
SHA256 5c005b4e3eca5668c378214525f71347fb8fd1fbd0b6525b0f8dbfed03d4c718
MD5 e0761deff4a6e727a13f6040065c2be8
BLAKE2b-256 f75b1894193fea85e8440840b583c6f7437d69041e411a922358db1976e06641

See more details on using hashes here.

Provenance

The following attestation bundles were made for truagents-0.2.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.2.0-py3-none-any.whl.

File metadata

  • Download URL: truagents-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 58.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for truagents-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 421bdadd6de8f6a120446e289cd77de8751147ef96bb5ab0f672c9c4905a52bf
MD5 1ea9744e87572d341041b03ad8f70e0f
BLAKE2b-256 72b9c298feef8568380bf7c17f16548c9c9f06a10f05eb073fabd7fecddce4a0

See more details on using hashes here.

Provenance

The following attestation bundles were made for truagents-0.2.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