Parcel Wing Python SDK
The official Python SDK for the Parcel Wing API.
It is designed for a fast, predictable developer experience:
- resource clients for emails, contacts, segments, topics, and automations
- consistent
ParcelWingErrorexceptions - typed package metadata and exported type hints
- small dependency surface built on
httpx - works with the same public API contract used by Parcel Wing itself
Installation
pip install parcelwing
Quick start
First you'll need an API key. If you don't have one, sign up and create one at https://parcelwing.com/signup. It's free, with no credit card required.
import os
from parcelwing import ParcelWing
parcel_wing = ParcelWing(api_key=os.environ["PARCEL_WING_API_KEY"])
emails = parcel_wing.emails.send(
from_="Acme <hello@yourdomain.com>",
to="person@example.com",
subject="Hello from Parcel Wing",
text="It works.",
)
print(emails[0]["id"])
from is a Python keyword, so the keyword-argument API uses from_. You can also pass a raw API dictionary if you prefer exact API field names:
emails = parcel_wing.emails.send({
"from": "Acme <hello@yourdomain.com>",
"to": "person@example.com",
"subject": "Hello from Parcel Wing",
"text": "It works.",
})
Using templates
emails = parcel_wing.emails.send(
from_="Acme <hello@yourdomain.com>",
to="person@example.com",
template_alias="welcome_email",
template_params={
"first_name": "John",
},
)
Contacts
contact = parcel_wing.contacts.create({
"email": "person@example.com",
"first_name": "John",
"attributes": {
"plan": "pro",
},
})
page = parcel_wing.contacts.list(page=1, limit=20)
print(len(page["data"]), page.get("pagination", {}).get("total"))
Batch create contacts:
result = parcel_wing.contacts.create([
{"email": "one@example.com", "first_name": "One"},
{"email": "two@example.com", "first_name": "Two"},
])
print(result["created"])
print(result["failed"])
Segments
segment = parcel_wing.segments.create({
"name": "Pro plan users",
"filter_criteria": {
"version": 1,
"match": "all",
"conditions": [
{
"field": "attribute",
"attribute_key": "plan",
"operator": "equals",
"value": "pro",
},
],
},
})
Topics
topic = parcel_wing.topics.create({
"name": "Product Updates",
"description": "Feature launches and release notes.",
"default_subscription": "opt_in",
"visibility": "public",
})
Automation events
parcel_wing.automations.track({
"event_name": "user.completed_onboarding",
"contact_id": "6d9dc8f7-c44e-4f2d-8a4e-d04f32f1744f",
"payload": {
"plan": "flight",
},
})
Error handling
from parcelwing import ParcelWingError
try:
parcel_wing.emails.send(
from_="Acme <hello@yourdomain.com>",
to="person@example.com",
subject="Hello",
text="Hi there",
)
except ParcelWingError as error:
print(error.status, error.type, error.code, error.request_id)
print(error.details)
Configuration
parcel_wing = ParcelWing(
api_key=os.environ["PARCEL_WING_API_KEY"],
base_url="https://parcelwing.com",
timeout=30.0,
)
Use the client as a context manager to close the underlying HTTP connection pool automatically:
with ParcelWing(api_key=os.environ["PARCEL_WING_API_KEY"]) as parcel_wing:
emails = parcel_wing.emails.send(
from_="Acme <hello@yourdomain.com>",
to="person@example.com",
subject="Hello",
text="It works.",
)
Local development
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
pytest
ruff check .
mypy src/parcelwing
Publishing
python -m pip install build twine
python -m build
twine upload dist/*
Metadata
Release files for parcelwing 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| parcelwing-0.1.1.tar.gz | 9.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| parcelwing-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 21.5 kB
Release files / parcelwing-0.1.1.tar.gz
| Download URL | parcelwing-0.1.1.tar.gz |
|---|---|
| Size | 9.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
939f89924296d419e9a7a0871172bfc99f66f432d211c00030cc9a1523b54a8d
|
|
BLAKE2b-256 checksum How to use checksums |
cc6ffefadbbac5b40db1a5316e5633137e3658e0e201cf77299226f72f99f984
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.13
|
Release files / parcelwing-0.1.1-py3-none-any.whl
| Download URL | parcelwing-0.1.1-py3-none-any.whl |
|---|---|
| Size | 12.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b0360c4ef4531a6c01f2cfc7703c5de526ae6e255eae99e1d97d0afa465b7bbc
|
|
BLAKE2b-256 checksum How to use checksums |
1f02e8a53fb65f6c2b3f18ed975a1f2c97c19ea8e52b59a37ee28bdd71e286f1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.13
|