Recipes¶
End-to-end workflows that glue multiple resources together.
Table of contents¶
Run a full campaign workflow¶
Create a campaign, place orders against it, assign the items to the campaign, and walk the article approval flow.
from pypresscart import (
CampaignCreateRequest,
CheckoutLineItem,
CheckoutRequest,
PresscartClient,
)
with PresscartClient(api_token=os.environ["PRESSCART_API_TOKEN"]) as client:
campaign = client.campaigns.create(
CampaignCreateRequest(
name="Q3 Launch",
description="Announce v2.0",
profile_id="prof_1",
objectives="drive awareness",
keywords="AI, SaaS, launch",
target_audience="VPs of Engineering",
tone="authoritative",
writing_samples=None,
file_id=None,
)
)
order = client.orders.create_checkout(
CheckoutRequest(
profile_id="prof_1",
line_items=[
CheckoutLineItem(product_id="prod_featured"),
CheckoutLineItem(product_id="prod_newsletter"),
],
)
)
client.campaigns.assign_order_items(
campaign.id,
{"order_item_ids": [li.id for li in order.line_items]},
)
# Later, approve briefs + drafts as they come in
for art in client.campaigns.list_articles(campaign.id).records:
if art.status and art.status[0].name == "Brief Ready":
client.articles.approve_brief(art.id)
Iterate every paginated resource¶
A reusable paginator. Works for anything returning Paginated[T].
from collections.abc import Callable, Iterator
from typing import TypeVar
T = TypeVar("T")
def all_pages(call: Callable[..., "Paginated[T]"], /, **kwargs) -> Iterator[T]:
page = 1
while True:
result = call(page=page, **kwargs)
yield from result.records
if result.next_page is None:
return
page = result.next_page
for order in all_pages(client.orders.list, limit=100):
...
for outlet in all_pages(client.outlets.list, limit=100, filters={"country": "United States"}):
...
Bulk outlet search with filters¶
Find in-budget US outlets with high domain authority that accept do-follow links.
def in_budget(min_cents: int, max_cents: int):
yield from all_pages(
client.outlets.list,
limit=100,
sort_by="domain_authority",
order_by="desc",
filters={
"country": "United States",
"is_do_follow": True,
"pricing[min]": min_cents,
"pricing[max]": max_cents,
"domain_authority[min]": 50,
},
)
for o in in_budget(5000, 30000):
print(o.outlet_name, o.channels[0].domain_authority, o.prices[0].unit_amount)
Monthly order report¶
from datetime import date, timedelta
start = date.today().replace(day=1)
end = (start + timedelta(days=32)).replace(day=1) - timedelta(days=1)
for profile in client.profiles.list_team_profiles(team_id).records:
orders = list(
all_pages(
client.profiles.list_orders,
profile_id=profile.id,
limit=100,
start_date=start.isoformat(),
end_date=end.isoformat(),
paid_orders_only=True,
)
)
total = sum(o.total or 0 for o in orders) / 100
print(f"{profile.name:30} ${total:>10,.2f} ({len(orders)} orders)")
Upload and attach a brand guide¶
uploaded = client.files.upload(
[("brand-guide-2026.pdf", open("brand-guide.pdf", "rb"), "application/pdf")],
folder_id=folder.id,
).files[0]
client.campaigns.link_questionnaire(
campaign.id,
{
"file_id": uploaded.file_key,
"file_url": uploaded.file_url,
"file_name": uploaded.name,
"file_size": uploaded.size,
},
)
Scope preflight¶
Fail loudly before doing real work.
REQUIRED = {"outlets.lists", "orders.create", "campaigns.create", "campaigns.update"}
info = client.auth.whoami()
if info.token_type != "full_access":
missing = REQUIRED - set(info.scopes)
if missing:
raise SystemExit(f"token missing scopes: {sorted(missing)}")
Retry exhausted? Pause and alert¶
pypresscart retries 429/5xx automatically. If it still fails, back off at the application level.
import time
from pypresscart import RateLimitError, ServerError
def resilient_list_orders():
while True:
try:
return client.orders.list(limit=100)
except RateLimitError as exc:
wait = exc.retry_after or 60
print(f"rate limited — sleeping {wait}s")
time.sleep(wait)
except ServerError:
time.sleep(30) # back off and retry at app level