pypresscart — A Python Library for the Presscart API
📚 Documentation · PyPI · Issues
⚠️ Unofficial library. This project is not affiliated with, endorsed by, or supported by Presscart. It's a community-maintained Python client for the Presscart API.
- Pythonic, typed resource methods (
client.outlets.list(...),client.orders.create_checkout(...), ...) - Dual-mode: pass Pydantic models or plain dicts; get Pydantic models or plain dicts back
- Single dependency stack —
requests+pydantic - Built-in exponential-backoff retry for
429/5xxresponses, honoringRetry-After - Typed exception hierarchy (
BadRequestError,AuthenticationError,RateLimitError, ...)
Install
uv add pypresscart
# or
pip install pypresscart
Python 3.10+.
Quickstart
from pypresscart import PresscartClient
client = PresscartClient(api_token="pc_...")
me = client.auth.whoami()
print(me.team_id, me.scopes)
outlets = client.outlets.list(limit=5, filters={"country": "United States"})
for row in outlets.records:
print(row.outlet_name, row.website_url)
Dual-mode usage
The library accepts both Pydantic models and raw dicts on the way in, and returns either on the way out.
from pypresscart import CheckoutLineItem, CheckoutRequest, PresscartClient
client = PresscartClient(api_token="pc_...")
# Pydantic in, Pydantic out (default)
order = client.orders.create_checkout(
CheckoutRequest(
profile_id="YOUR_PROFILE_ID",
line_items=[CheckoutLineItem(product_id="YOUR_PRODUCT_ID", quantity=1)],
)
)
print(order.reference_number)
# Dict in, dict out
raw = client.orders.create_checkout(
{
"profile_id": "YOUR_PROFILE_ID",
"line_items": [
{"product_id": "YOUR_PRODUCT_ID", "quantity": 1, "is_add_on": False}
],
"discount": 0,
},
as_json=True,
)
print(raw["reference_number"])
You can also set the default for the whole client:
client = PresscartClient(api_token="pc_...", response_mode="json")
Per-call as_json=True / as_json=False always wins over the client default.
Error handling
from pypresscart import (
AuthenticationError,
NotFoundError,
PresscartAPIError,
RateLimitError,
ValidationError,
)
try:
client.campaigns.get("missing")
except NotFoundError as exc:
print("not found:", exc.message)
except AuthenticationError:
print("token invalid or expired")
except RateLimitError as exc:
print("slow down; retry after", exc.retry_after)
except ValidationError as exc:
for issue in exc.issues:
print("field", issue["path"], issue["message"])
except PresscartAPIError as exc:
print(exc.status_code, exc.name, exc.message, exc.payload)
All API errors inherit from PresscartAPIError. Network-level failures raise
PresscartTransportError (wrapping the underlying requests exception).
Client options
| Parameter | Default | Description |
|---|---|---|
api_token |
(required) | Bearer token (pc_...) |
base_url |
https://api.presscart.com |
API origin |
timeout |
30.0 |
Per-request timeout (seconds) |
max_retries |
3 |
Additional attempts on 429/5xx/network errors |
retry_backoff_base |
0.25 |
Base backoff seconds |
retry_backoff_max |
4.0 |
Backoff cap |
retry_jitter |
0.1 |
Fractional jitter |
response_mode |
"pydantic" |
"pydantic" or "json" |
user_agent |
"pypresscart/<version>" |
User-Agent header |
session |
None |
Inject a pre-configured requests.Session |
Use as a context manager to close the session automatically:
with PresscartClient(api_token="pc_...") as client:
...
Endpoints
Every endpoint documented at docs.presscart.com is covered by a method on one of the resource services:
| Service | Methods |
|---|---|
client.auth |
whoami |
client.outlets |
list, get, list_products, list_countries, list_states, list_cities, list_tags, list_disclaimers |
client.products |
get, list_listings, list_categories |
client.orders |
list, get, create_checkout |
client.order_items |
list |
client.profiles |
list_team_profiles, list_orders, list_order_items, list_campaigns |
client.campaigns |
list, get, create, update, list_articles, article_status_counts, assign_order_items, link_questionnaire |
client.articles |
get, update, approve_brief, approve_draft |
client.files |
list, get, upload, download, move, delete |
client.folders |
list, create, rename, delete |
Each method's docstring includes the required token scope.
Documentation
Full documentation lives at https://pypresscart.github.io/py-presscart/ — Sphinx site built from docs/ and deployed automatically by .github/workflows/docs.yml on every push to main.
Build locally:
uv sync --group docs
uv run sphinx-build -b html -n -W --keep-going docs docs/_build/html
open docs/_build/html/index.html
# Or with live reload:
uv run sphinx-autobuild docs docs/_build/html --watch src/pypresscart
Development
uv sync --group dev
uv run pytest -v
uv run ruff check .
uv run ruff format --check .
uv run mypy src
uv build
Pre-commit hooks
This repo ships a .pre-commit-config.yaml with ruff,
mypy, whitespace/EOL/yaml/toml checks, and a pytest hook on pre-push.
uv run pre-commit install # ruff + mypy on every commit
uv run pre-commit install --hook-type pre-push # pytest on every push
uv run pre-commit run --all-files # run everything now
Branch protection
main is protected — no direct pushes. Every change goes through a pull
request that must pass CI (ruff, ruff format, mypy, pytest on Python 3.10
through 3.13, and the distribution build) before it can merge. Force-pushes
and branch deletion are denied.
Releasing
Releases are cut by a human via the Release GitHub Actions workflow, which
uses OIDC trusted publishing — no PyPI tokens are stored anywhere.
Prerequisites (one-time)
- Project
pypresscartregistered as a trusted publisher on both PyPI and TestPyPI, pointing at this repo + workflowrelease.yml+ environmentspypi/testpypi. - GitHub repo environments
pypiandtestpypiexist. Optionally add required reviewers onpypiif you want a human to approve every prod publish.
Cutting a new release
-
Decide the version. Follow SemVer:
MAJOR— anything that could break existing callers (renames, removed fields, changed defaults, raised minimum Python).MINOR— backwards-compatible additions (new endpoints, new optional parameters).PATCH— bug fixes only.
-
Open a bump PR. On a branch, update both:
src/pypresscart/_version.py—__version__ = "X.Y.Z"pyproject.toml—[project].version = "X.Y.Z"
Also add an entry to
docs/changelog.mdunder## [Unreleased]and roll it into a new## [X.Y.Z] — <date>heading. -
Merge the PR. Wait for CI to go green, then merge. The docs site rebuilds and picks up the new version string automatically.
-
Publish to TestPyPI first. Actions → Release → Run workflow → pick
testpypi→ run. Wait for green. -
Smoke-test from TestPyPI in a throwaway environment:
uv run --no-project \ --with pypresscart==X.Y.Z \ --index-url https://test.pypi.org/simple/ \ --extra-index-url https://pypi.org/simple/ \ python -c "from pypresscart import PresscartClient, __version__; print(__version__)"
-
Publish to PyPI. Actions → Release → Run workflow → pick
pypi→ run. (If you added required reviewers on thepypienvironment, approve the deployment when prompted.) -
Tag and announce.
git tag -a vX.Y.Z -m "pypresscart X.Y.Z" git push origin vX.Y.Z gh release create vX.Y.Z \ --title "pypresscart X.Y.Z" \ --notes-file <(awk '/^## \[X\.Y\.Z\]/,/^## \[/' docs/changelog.md | sed '$d')
If something goes wrong
- Published a broken version? You can't overwrite a PyPI release. Cut a
new patch release (
X.Y.Z+1) that reverts or fixes the issue.yankon PyPI hides the broken version from resolvers but keeps it available to pinned installs. - TestPyPI upload failed but PyPI didn't run? Re-dispatch with
target=testpypi. The workflow hasskip-existing: trueon TestPyPI so re-uploading the same version is a no-op. - Trusted publisher rejected the OIDC token? Confirm the pending
publisher on PyPI has the exact workflow filename (
release.yml) and environment name (pypi/testpypi). One-character typos fail silently.
License
MIT — see LICENSE.
Presscart™ and the Presscart logo are trademarks of their respective owners. This library is an independent, unofficial client.
Metadata
Release files for pypresscart 0.1.8
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| pypresscart-0.1.8.tar.gz | 28.9 kB | With provenance | Details for pypresscart-0.1.8.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| pypresscart-0.1.8-py3-none-any.whl | Python 3 | none | any | Details for pypresscart-0.1.8-py3-none-any.whl |
Total release size: 66.6 kB
Release files / pypresscart-0.1.8.tar.gz
| Download URL | pypresscart-0.1.8.tar.gz |
|---|---|
| Size | 28.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
1a9385416f5ccb3bcfb396f6f6a2a4c22d647f40522ef83d491503941eca2a3a
|
|
BLAKE2b-256 checksum How to use checksums |
ea0f6e60f41a6a628eb53ba4c06ed4338a01d906e80ebac16c0443d1dbb5ebf5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 12, 2026.
Transparency logRelease files / pypresscart-0.1.8-py3-none-any.whl
| Download URL | pypresscart-0.1.8-py3-none-any.whl |
|---|---|
| Size | 37.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
77be08cb483d5a4abbc176ec92c0603ba942e7f7972d3a3e8746c3ef2f1e3a7c
|
|
BLAKE2b-256 checksum How to use checksums |
58468d17179903382cddb177cecb6964852c985297f504cd7f688dc67f96f6f3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 12, 2026.
Transparency logSecurity for pypresscart 0.1.8
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for pypresscart-0.1.8.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 12, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.