Async client
AsyncPostmarkClient has the same API as PostmarkClient. Every method and property that makes a request is a coroutine.
Install the async extra, which adds httpx2:
uv pip install 'postmarker[async]'
from postmarker.core import AsyncPostmarkClient
async with AsyncPostmarkClient(server_token="POSTMARK_API_TEST") as postmark:
await postmark.emails.send(
From="sender@example.com",
To="receiver@example.com",
Subject="Postmark test",
HtmlBody="<strong>Hello</strong> dear Postmark user.",
)
async with closes the connection pool on exit. Without it, call await postmark.aclose() when you are done.
Same API, awaited
Managers, models and their methods keep the sync names and arguments:
bounce = await postmark.bounces.get(723626745)
await bounce.activate()
templates = await postmark.templates.all()
await postmark.emails.send_batch(*messages)
Properties that make a request stay properties, so you await them: await bounce.dump, await postmark.status.services, await postmark.bounces.deliverystats.
Each async class has the sync name with an Async prefix, in the same module: AsyncBounce in postmarker.models.bounces, AsyncEmail in postmarker.models.emails.
Webhook wrappers on the async client return async models, so await postmark.bounces.Bounce(payload).message loads the related message.
Differences from the sync client
- Network errors raise httpx2 exceptions, e.g.
httpx2.ConnectErrorandhttpx2.TimeoutException. Postmark API errors raiseClientError, as in the sync client. - An HTTP error without a JSON body, e.g. an HTML 502 from a proxy, raises
httpx2.HTTPStatusErrorinstead ofrequests.HTTPError. max_retriesdoesn't apply to requests through a proxy fromHTTP_PROXY/HTTPS_PROXY: httpx2 doesn't retry proxy connections.- Batches accept the async email classes: pass
AsyncEmailinstances, dictionaries oremail.message.Messageinstances tosend_batch.
Testing
Postmarker ships postmark_async_request and postmark_async_client, the async versions of the sync fixtures.
postmark_async_request records calls in the same shape as postmark_request, so a sync test ports by adding await:
async def test_welcome_email(postmark_async_request):
await send_welcome_email("jane@example.com") # Your code that sends an email
assert postmark_async_request.call_args.kwargs["json"]["To"] == "jane@example.com"
Run async tests with an async test plugin, e.g. anyio's or pytest-asyncio.