🛍️ py-aliexpress-affiliate
⚠️ Disclaimer:
py-aliexpress-affiliateis an unofficial, independent open-source community library. It is not affiliated with, endorsed by, or sponsored by AliExpress or Alibaba Group. "AliExpress" and "Alibaba" are trademarks of Alibaba Group Holding Limited.
A production-quality, fully typed (mypy --strict) Python library that wraps all 15 official AliExpress Affiliate (AE Affiliate) Open Platform API endpoints with both synchronous and asynchronous (httpx) clients and Pydantic v2 domain models.
✨ Features
- 🎯 Complete AE Affiliate API Coverage (15/15 Endpoints):
- 🔗 Links (
aliexpress.affiliate.link.generate) - 🗂️ Categories (
aliexpress.affiliate.category.get+ parent/child filtering & caching) - 🎉 Featured Promotions (
featuredpromo.get,featuredpromo.products.get) - 📦 Products & Hot Products (
product.query,hotproduct.query,hotproduct.download,productdetail.get,product.smartmatch) - 🚚 Shipping & SKU Details (
product.shipping.get,product.sku.detail.get) - 🎟️ Real-time Coupons & Promotions (
promotion.info.get) - 🧾 Orders (
order.get,order.list,order.listbyindex)
- 🔗 Links (
- 🧩 Clean Domain Return Types:
- Single-item methods (
get_product_details,get_order_details,generate_affiliate_link,get_category,get_product_shipping_info,get_product_sku_details,get_promotion_info) accept a single identifier and return a single domain model (or raiseProductNotFoundError,OrderNotFoundError,CategoryNotFoundError,LinkGenerationError). - Batch methods (
get_products_details,get_orders_details,get_affiliate_links,get_promotions_info) accept sequences of identifiers and returnlist[Model]. - Paginated list methods (
get_products,get_hot_products,download_hot_products,get_featured_promo_products,smart_match_products,get_order_list,get_order_list_by_index) return genericPage[Model]orCursorPage[Model]containers (items,page_no,page_size,total_count,total_pages,has_next).
- Single-item methods (
- 🔐 Exact TOP Request Signing: Preserves the battle-tested TOP MD5 signing algorithm from
sergioteula/python-aliexpress-api. - ⚡ Sync & Async Parity:
AliExpressClientandAsyncAliExpressClientexpose identical methods and resource namespaces (.links,.categories,.products,.orders,.promotions). - 🛡️ Reliability & Security by Default: Configurable timeouts, exponential backoff retries (including automatic retry on transient
ApiCallLimitgateway rate limits), and automatic redaction of secrets (app_secret,session,app_signature) inrepr(),str(), transport exception messages, and debug logs.
📦 Installation
pip install py-aliexpress-affiliate
For development:
pip install -e ".[dev]"
⚙️ Configuration
You can pass credentials and defaults directly to AliExpressClient / AsyncAliExpressClient or configure them via environment variables:
| Constructor Arg | Environment Variable | Default | Description |
|---|---|---|---|
app_key |
ALIEXPRESS_APP_KEY |
(Required) | AliExpress Open Platform App Key |
app_secret |
ALIEXPRESS_APP_SECRET |
(Required) | AliExpress Open Platform App Secret (redacted in repr) |
tracking_id |
ALIEXPRESS_TRACKING_ID |
None |
Default affiliate tracking ID |
language |
ALIEXPRESS_LANGUAGE |
"EN" |
Target language (Language.EN, "ES", etc.) |
currency |
ALIEXPRESS_CURRENCY |
"USD" |
Target currency (Currency.USD, "EUR", etc.) |
country |
ALIEXPRESS_COUNTRY |
None |
Default destination country ("US", "DE", etc.) |
app_signature |
ALIEXPRESS_APP_SIGNATURE |
None |
Optional legacy API signature (redacted in repr) |
session |
ALIEXPRESS_SESSION |
None |
Optional TOP session token (redacted in repr) |
base_url |
ALIEXPRESS_BASE_URL |
"https://api-sg.aliexpress.com" |
AliExpress TOP Gateway URL |
🚀 Quickstart
🔄 Synchronous Usage
from aliexpress_affiliate import (
AliExpressClient,
Currency,
Language,
LinkType,
OrderStatus,
SortBy,
)
with AliExpressClient(
app_key="YOUR_APP_KEY",
app_secret="YOUR_APP_SECRET",
tracking_id="default",
language=Language.EN,
currency=Currency.USD,
country="US",
) as client:
# 1. Single-item lookup: returns ONE Product (or raises ProductNotFoundError)
product = client.get_product_details("1005004757833857")
print(product.id, product.title, product.target_sale_price_decimal)
# 2. Batch lookup: returns list[Product]
products = client.get_products_details(
["1005004757833857", "https://www.aliexpress.com/item/33006951782.html"]
)
# 3. Generate a single affiliate link: returns ONE AffiliateLink
link = client.generate_affiliate_link(
"https://www.aliexpress.com/item/1005004757833857.html",
promotion_link_type=LinkType.NORMAL,
)
print("Affiliate link:", link.promotion_link)
# 4. Paginated product search: returns Page[Product]
page = client.get_products(
keywords="mechanical keyboard",
sort=SortBy.LAST_VOLUME_DESC,
page_no=1,
page_size=10,
)
print(f"Page {page.page_no}/{page.total_pages} (total={page.total_count}, has_next={page.has_next})")
for item in page.items:
print(item.id, item.title, item.target_sale_price, item.latest_volume)
# 5. Single order lookup by sub_order_id: returns ONE Order (or raises OrderNotFoundError)
order = client.get_order_details(3000000000010001)
print(order.order_id, order.sub_order_id, order.order_status, order.paid_amount_decimal)
# 6. Paginated order list: returns Page[Order]
order_page = client.get_order_list(
status=OrderStatus.PAYMENT_COMPLETED,
start_time="2026-01-01 00:00:00",
end_time="2026-01-07 23:59:59",
page_no=1,
page_size=50,
)
for o in order_page.items:
print(o.order_id, o.sub_order_id, o.paid_amount_decimal, o.estimated_paid_commission_decimal)
⚡ Asynchronous Usage
import asyncio
from aliexpress_affiliate import AsyncAliExpressClient, Currency, Language
async def main() -> None:
async with AsyncAliExpressClient(
app_key="YOUR_APP_KEY",
app_secret="YOUR_APP_SECRET",
tracking_id="default",
language=Language.EN,
currency=Currency.EUR,
country="DE",
) as client:
categories, hot_page = await asyncio.gather(
client.get_parent_categories(),
client.get_hot_products(keywords="earbuds", page_size=5),
)
print(f"Loaded {len(categories)} parent categories and {len(hot_page.items)} hot products")
asyncio.run(main())
📚 API Reference
Both AliExpressClient and AsyncAliExpressClient expose top-level methods as well as grouped resource namespaces (client.links, client.categories, client.products, client.promotions, client.orders):
| AliExpress Method | Single-Item Method -> Return Type | Batch / List Method -> Return Type |
|---|---|---|
aliexpress.affiliate.link.generate |
generate_affiliate_link(url) -> AffiliateLink |
get_affiliate_links(urls) -> list[AffiliateLink] |
aliexpress.affiliate.category.get |
get_category(category_id) -> Category |
get_categories() -> list[Category]get_parent_categories() -> list[Category]get_child_categories(parent_id) -> list[ChildCategory] |
aliexpress.affiliate.featuredpromo.get |
— | get_featured_promos() -> list[FeaturedPromo] |
aliexpress.affiliate.featuredpromo.products.get |
— | get_featured_promo_products(...) -> Page[Product] |
aliexpress.affiliate.hotproduct.download |
— | download_hot_products(category_id, ...) -> Page[Product] |
aliexpress.affiliate.hotproduct.query |
— | get_hot_products(...) -> Page[Product] |
aliexpress.affiliate.product.query |
— | get_products(...) -> Page[Product] |
aliexpress.affiliate.productdetail.get |
get_product_details(product_id) -> Product |
get_products_details(product_ids) -> list[Product] |
aliexpress.affiliate.product.smartmatch |
— | smart_match_products(...) -> Page[Product] |
aliexpress.affiliate.product.shipping.get |
get_product_shipping_info(...) -> ProductShippingInfo |
— |
aliexpress.affiliate.product.sku.detail.get |
get_product_sku_details(product_id) -> ProductSkuDetail |
— |
aliexpress.affiliate.promotion.info.get |
get_promotion_info(product_id) -> ProductPromotionResult |
get_promotions_info(product_ids) -> list[ProductPromotionResult] |
aliexpress.affiliate.order.get |
get_order_details(order_id) -> Order (by sub_order_id) |
get_orders_details(order_ids) -> list[Order] |
aliexpress.affiliate.order.list |
— | get_order_list(...) -> Page[Order] |
aliexpress.affiliate.order.listbyindex |
— | get_order_list_by_index(...) -> CursorPage[Order] |
🚨 Error Handling
All exceptions inherit from AliExpressError:
AliExpressErrorConfigurationError— Missing or invalidapp_key,app_secret, or client settings.ValidationError— Invalid method arguments, passing multiple IDs to a single-item method, or unparseable URLs.NetworkError— HTTP transport failure, timeout, or non-200 status after retries.APIError— Gateway (error_response) or business-level (resp_code != 200) API error.AuthenticationError— Invalidapp_key(code="29"or"InvalidAppKey"), session token, HTTP 401/403, or insufficient API permissions.SignatureError— Invalid TOP request signature (code="25","IncompleteSignature", or"InvalidSignature").
RateLimitError— QPS or call frequency quota exceeded (code="7","ApiCallLimit", or HTTP429).ResourceNotFoundError— Base exception for missing resources (ERROR-405/405) or empty queries whenraise_on_empty=True.ProductNotFoundError— Raised whenget_product_details,get_product_sku_details,get_product_shipping_info, orget_promotion_infofinds no matching product.OrderNotFoundError— Raised whenget_order_detailsfinds no matching order.CategoryNotFoundError— Raised whenget_categoryfinds no matching category.
LinkGenerationError— Raised whengenerate_affiliate_linkfails to produce a promotion URL.
from aliexpress_affiliate import (
AliExpressClient,
APIError,
AuthenticationError,
NetworkError,
OrderNotFoundError,
ProductNotFoundError,
RateLimitError,
SignatureError,
ValidationError,
)
try:
with AliExpressClient() as client:
product = client.get_product_details("33006951782")
order = client.get_order_details(3000000000010001)
except ProductNotFoundError as exc:
print(f"Product {exc.product_id} was not found")
except OrderNotFoundError as exc:
print(f"Order {exc.order_id} was not found")
except SignatureError as exc:
print(f"Signature mismatch: {exc.message} (request_id={exc.request_id})")
except AuthenticationError as exc:
print(f"Auth failed: {exc.code} - {exc.sub_msg}")
except RateLimitError as exc:
print(f"Rate limited: {exc}")
except APIError as exc:
print(f"API error [{exc.code}]: {exc.message}")
except NetworkError as exc:
print(f"Transport error (HTTP {exc.status_code}): {exc.message}")
except ValidationError as exc:
print(f"Invalid input: {exc.message}")
📜 Attribution, Trademarks & License
Released under the MIT License.
- 🙏 The TOP MD5 request-signing logic and legacy compatibility aliases are adapted from
sergioteula/python-aliexpress-api(Copyright (c) 2020 Sergio Abad, MIT License). - ⚖️ Non-Affiliation Notice: This project is an independent, unofficial open-source library and is not affiliated with, endorsed by, or sponsored by AliExpress or Alibaba Group Holding Limited.
Metadata
Release files for py-aliexpress-affiliate 0.2.2
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 |
|---|---|---|---|---|
| py_aliexpress_affiliate-0.2.2.tar.gz | 52.0 kB | With provenance | Details for py_aliexpress_affiliate-0.2.2.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| py_aliexpress_affiliate-0.2.2-py3-none-any.whl | Python 3 | none | any | Details for py_aliexpress_affiliate-0.2.2-py3-none-any.whl |
Total release size: 115.7 kB
Release files / py_aliexpress_affiliate-0.2.2.tar.gz
| Download URL | py_aliexpress_affiliate-0.2.2.tar.gz |
|---|---|
| Size | 52.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
96ea36c5fe3984ced6f7346bd00dd355cdf08b1241773020e14c6ba046486ab3
|
|
BLAKE2b-256 checksum How to use checksums |
c60a661a3da972d6eff56e64bb5c4bd128370f3220872994a9f87b2bdcd55569
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Oct 13, 2026.
Transparency logRelease files / py_aliexpress_affiliate-0.2.2-py3-none-any.whl
| Download URL | py_aliexpress_affiliate-0.2.2-py3-none-any.whl |
|---|---|
| Size | 63.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b77446ca81cf23eada73caaf3ed299a9b09a257c66e964bf83d7d81627762ef2
|
|
BLAKE2b-256 checksum How to use checksums |
364e3fb0f067ed93926e97247a4c0adda53a985694fac82075c6b5432ba92acd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Oct 13, 2026.
Transparency logSecurity for py-aliexpress-affiliate 0.2.2
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 py_aliexpress_affiliate-0.2.2.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 Oct 13, 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.