├── .github └── workflows │ └── python-publish.yml ├── .gitignore ├── LICENSE ├── README.md ├── aliexpress_api ├── __init__.py ├── api.py ├── errors │ ├── __init__.py │ └── exceptions.py ├── helpers │ ├── __init__.py │ ├── arguments.py │ ├── categories.py │ ├── products.py │ └── requests.py ├── models │ ├── __init__.py │ ├── affiliate_link.py │ ├── category.py │ ├── currencies.py │ ├── hotproducts.py │ ├── languages.py │ ├── order.py │ ├── orderlist.py │ ├── product.py │ └── request_parameters.py ├── skd │ ├── __init__.py │ └── api │ │ ├── __init__.py │ │ ├── base.py │ │ └── rest │ │ ├── AliexpressAffiliateCategoryGetRequest.py │ │ ├── AliexpressAffiliateFeaturedpromoGetRequest.py │ │ ├── AliexpressAffiliateFeaturedpromoProductsGetRequest.py │ │ ├── AliexpressAffiliateHotproductDownloadRequest.py │ │ ├── AliexpressAffiliateHotproductQueryRequest.py │ │ ├── AliexpressAffiliateLinkGenerateRequest.py │ │ ├── AliexpressAffiliateOrderGetRequest.py │ │ ├── AliexpressAffiliateOrderListRequest.py │ │ ├── AliexpressAffiliateOrderListbyindexRequest.py │ │ ├── AliexpressAffiliateProductQueryRequest.py │ │ ├── AliexpressAffiliateProductSmartmatchRequest.py │ │ ├── AliexpressAffiliateProductdetailGetRequest.py │ │ └── __init__.py └── tools │ ├── __init__.py │ └── get_product_id.py └── setup.py /.github/workflows/python-publish.yml: -------------------------------------------------------------------------------- 1 | # This workflow will upload a Python Package using Twine when a release is created 2 | # For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries 3 | 4 | name: Upload Python Package 5 | 6 | on: 7 | release: 8 | types: [created] 9 | 10 | jobs: 11 | deploy: 12 | runs-on: ubuntu-latest 13 | environment: 14 | name: pypi 15 | url: https://pypi.org/p/python-aliexpress-api 16 | permissions: 17 | id-token: write 18 | steps: 19 | - uses: actions/checkout@v2 20 | - name: Set up Python 21 | uses: actions/setup-python@v2 22 | with: 23 | python-version: '3.x' 24 | - name: Install dependencies 25 | run: | 26 | python -m pip install --upgrade pip 27 | pip install setuptools wheel 28 | - name: Build 29 | run: | 30 | python setup.py sdist bdist_wheel 31 | - name: Publish package 32 | uses: pypa/gh-action-pypi-publish@release/v1 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Custom folders and files to ignore 2 | .vscode/ 3 | .DS_Store 4 | test.py 5 | 6 | 7 | # Byte-compiled / optimized / DLL files 8 | __pycache__/ 9 | *.py[cod] 10 | *$py.class 11 | 12 | # C extensions 13 | *.so 14 | 15 | # Distribution / packaging 16 | .Python 17 | build/ 18 | develop-eggs/ 19 | dist/ 20 | downloads/ 21 | eggs/ 22 | .eggs/ 23 | lib/ 24 | lib64/ 25 | parts/ 26 | sdist/ 27 | var/ 28 | wheels/ 29 | *.egg-info/ 30 | .installed.cfg 31 | *.egg 32 | MANIFEST 33 | 34 | # PyInstaller 35 | # Usually these files are written by a python script from a template 36 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 37 | *.manifest 38 | *.spec 39 | 40 | # Installer logs 41 | pip-log.txt 42 | pip-delete-this-directory.txt 43 | 44 | # Unit test / coverage reports 45 | htmlcov/ 46 | .tox/ 47 | .coverage 48 | .coverage.* 49 | .cache 50 | nosetests.xml 51 | coverage.xml 52 | *.cover 53 | .hypothesis/ 54 | .pytest_cache/ 55 | 56 | # Translations 57 | *.mo 58 | *.pot 59 | 60 | # Django stuff: 61 | *.log 62 | local_settings.py 63 | db.sqlite3 64 | 65 | # Flask stuff: 66 | instance/ 67 | .webassets-cache 68 | 69 | # Scrapy stuff: 70 | .scrapy 71 | 72 | # Sphinx documentation 73 | docs/_build/ 74 | 75 | # PyBuilder 76 | target/ 77 | 78 | # Jupyter Notebook 79 | .ipynb_checkpoints 80 | 81 | # pyenv 82 | .python-version 83 | 84 | # celery beat schedule file 85 | celerybeat-schedule 86 | 87 | # SageMath parsed files 88 | *.sage.py 89 | 90 | # Environments 91 | .env 92 | .venv 93 | env/ 94 | venv/ 95 | ENV/ 96 | env.bak/ 97 | venv.bak/ 98 | 99 | # Spyder project settings 100 | .spyderproject 101 | .spyproject 102 | 103 | # Rope project settings 104 | .ropeproject 105 | 106 | # mkdocs documentation 107 | /site 108 | 109 | # mypy 110 | .mypy_cache/ 111 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Sergio Abad 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AliExpress API wrapper for Python 2 | 3 | A simple Python wrapper for the [AliExpress Open Platform API](https://developers.aliexpress.com/en). This module allows getting information and affiliate links from AliExpress using the official API in an easier way. 4 | 5 | [![PyPI](https://img.shields.io/pypi/v/python-aliexpress-api?color=%231182C2&label=PyPI)](https://pypi.org/project/python-aliexpress-api/) 6 | [![Python](https://img.shields.io/badge/Python->3.6-%23FFD140)](https://www.python.org/) 7 | [![License](https://img.shields.io/badge/License-MIT-%23e83633)](https://github.com/sergioteula/python-aliexpress-api/blob/master/LICENSE) 8 | [![Support](https://img.shields.io/badge/Support-Good-brightgreen)](https://github.com/sergioteula/python-aliexpress-api/issues) 9 | 10 | ## Features 11 | 12 | - Object oriented interface for simple usage. 13 | - Requests follow the [official documentation](https://developers.aliexpress.com/en/doc.htm?docId=45803&docType=2). 14 | - Ask for new features through the [issues](https://github.com/sergioteula/python-aliexpress-api/issues) section. 15 | - Join our [Telegram group](https://t.me/PythonAliExpressAPI) for support or development. 16 | 17 | ## Installation 18 | 19 | You can install or upgrade the module with: 20 | 21 | pip install python-aliexpress-api --upgrade 22 | 23 | ## Usage guide 24 | 25 | **Import and initialize the API:** 26 | 27 | ```python 28 | from aliexpress_api import AliexpressApi, models 29 | aliexpress = AliexpressApi(KEY, SECRET, models.Language.EN, models.Currency.EUR, TRACKING_ID) 30 | ``` 31 | 32 | **Get products information:** 33 | 34 | ```python 35 | products = aliexpress.get_products_details(['1000006468625', 'https://aliexpress.com/item/1005003091506814.html']) 36 | print(products[0].product_title, products[1].target_sale_price) 37 | ``` 38 | 39 | **Get affiliate link:** 40 | 41 | ```python 42 | affiliate_links = aliexpress.get_affiliate_links('https://aliexpress.com/item/1005003091506814.html') 43 | print(affiliate_links[0].promotion_link) 44 | ``` 45 | 46 | **Get products:** 47 | 48 | ```python 49 | response = aliexpress.get_products(keywords='bluetooth earphones', max_sale_price=3000) 50 | print(response.products[0].product_title) 51 | ``` 52 | 53 | **Get hotproducts:** 54 | 55 | ```python 56 | response = aliexpress.get_hotproducts(keywords='bluetooth earphones', max_sale_price=3000) 57 | print(response.products[0].product_main_image_url) 58 | ``` 59 | 60 | **Get categories:** 61 | 62 | ```python 63 | parent_categories = aliexpress.get_parent_categories() 64 | child_categories = aliexpress.get_child_categories(parent_categories[0].category_id) 65 | ``` 66 | 67 | ## License 68 | 69 | Copyright © 2020 Sergio Abad. See [license](https://github.com/sergioteula/python-aliexpress-api/blob/master/LICENSE) for details. 70 | -------------------------------------------------------------------------------- /aliexpress_api/__init__.py: -------------------------------------------------------------------------------- 1 | """AliExpress API wrapper for Python""" 2 | 3 | __author__ = 'Sergio Abad' 4 | 5 | from .api import AliexpressApi 6 | from .api import models 7 | -------------------------------------------------------------------------------- /aliexpress_api/api.py: -------------------------------------------------------------------------------- 1 | """AliExpress API wrapper for Python 2 | 3 | A simple Python wrapper for the AliExpress Open Platform API. This module allows 4 | to get product information and affiliate links from AliExpress using the official 5 | API in an easier way. 6 | """ 7 | 8 | from aliexpress_api.errors.exceptions import CategoriesNotFoudException 9 | from aliexpress_api.helpers.categories import filter_child_categories, filter_parent_categories 10 | from aliexpress_api.models.category import ChildCategory 11 | from .skd import setDefaultAppInfo 12 | from .skd import api as aliapi 13 | from .errors import ProductsNotFoudException, InvalidTrackingIdException, OrdersNotFoundException 14 | from .helpers import api_request, parse_products, get_list_as_string, get_product_ids 15 | from . import models 16 | 17 | from typing import List, Union 18 | 19 | 20 | class AliexpressApi: 21 | """Provides methods to get information from AliExpress using your API credentials. 22 | 23 | Args: 24 | key (str): Your API key. 25 | secret (str): Your API secret. 26 | language (str): Language code. Defaults to EN. 27 | currency (str): Currency code. Defaults to USD. 28 | tracking_id (str): The tracking id for link generator. Defaults to None. 29 | """ 30 | 31 | def __init__(self, 32 | key: str, 33 | secret: str, 34 | language: models.Language, 35 | currency: models.Currency, 36 | tracking_id: str = None, 37 | app_signature: str = None, 38 | **kwargs): 39 | self._key = key 40 | self._secret = secret 41 | self._tracking_id = tracking_id 42 | self._language = language 43 | self._currency = currency 44 | self._app_signature = app_signature 45 | self.categories = None 46 | setDefaultAppInfo(self._key, self._secret) 47 | 48 | 49 | def get_products_details(self, 50 | product_ids: Union[str, List[str]], 51 | fields: Union[str, List[str]] = None, 52 | country: str = None, 53 | **kwargs) -> List[models.Product]: 54 | """Get products information. 55 | 56 | Args: 57 | product_ids (``str | list[str]``): One or more links or product IDs. 58 | fields (``str | list[str]``): The fields to include in the results. Defaults to all. 59 | country (``str``): Filter products that can be sent to that country. Returns the price 60 | according to the country's tax rate policy. 61 | 62 | Returns: 63 | ``list[models.Product]``: A list of products. 64 | 65 | Raises: 66 | ``ProductsNotFoudException`` 67 | ``InvalidArgumentException`` 68 | ``ApiRequestException`` 69 | ``ApiRequestResponseException`` 70 | """ 71 | product_ids = get_product_ids(product_ids) 72 | product_ids = get_list_as_string(product_ids) 73 | 74 | request = aliapi.rest.AliexpressAffiliateProductdetailGetRequest() 75 | request.app_signature = self._app_signature 76 | request.fields = get_list_as_string(fields) 77 | request.product_ids = product_ids 78 | request.country = country 79 | request.target_currency = self._currency 80 | request.target_language = self._language 81 | request.tracking_id = self._tracking_id 82 | 83 | response = api_request(request, 'aliexpress_affiliate_productdetail_get_response') 84 | 85 | if response.current_record_count > 0: 86 | response = parse_products(response.products.product) 87 | return response 88 | else: 89 | raise ProductsNotFoudException('No products found with current parameters') 90 | 91 | 92 | def get_affiliate_links(self, 93 | links: Union[str, List[str]], 94 | link_type: models.LinkType = models.LinkType.NORMAL, 95 | **kwargs) -> List[models.AffiliateLink]: 96 | """Converts a list of links in affiliate links. 97 | 98 | Args: 99 | links (``str | list[str]``): One or more links to convert. 100 | link_type (``models.LinkType``): Choose between normal link with standard commission 101 | or hot link with hot product commission. Defaults to NORMAL. 102 | 103 | Returns: 104 | ``list[models.AffiliateLink]``: A list containing the affiliate links. 105 | 106 | Raises: 107 | ``InvalidArgumentException`` 108 | ``InvalidTrackingIdException`` 109 | ``ProductsNotFoudException`` 110 | ``ApiRequestException`` 111 | ``ApiRequestResponseException`` 112 | """ 113 | if not self._tracking_id: 114 | raise InvalidTrackingIdException('The tracking id is required for affiliate links') 115 | 116 | links = get_list_as_string(links) 117 | 118 | request = aliapi.rest.AliexpressAffiliateLinkGenerateRequest() 119 | request.app_signature = self._app_signature 120 | request.source_values = links 121 | request.promotion_link_type = link_type 122 | request.tracking_id = self._tracking_id 123 | 124 | response = api_request(request, 'aliexpress_affiliate_link_generate_response') 125 | 126 | if response.total_result_count > 0: 127 | return response.promotion_links.promotion_link 128 | else: 129 | raise ProductsNotFoudException('Affiliate links not available') 130 | 131 | 132 | def get_hotproducts(self, 133 | category_ids: Union[str, List[str]] = None, 134 | delivery_days: int = None, 135 | fields: Union[str, List[str]] = None, 136 | keywords: str = None, 137 | max_sale_price: int = None, 138 | min_sale_price: int = None, 139 | page_no: int = None, 140 | page_size: int = None, 141 | platform_product_type: models.ProductType = None, 142 | ship_to_country: str = None, 143 | sort: models.SortBy = None, 144 | **kwargs) -> models.HotProductsResponse: 145 | """Search for affiliated products with high commission. 146 | 147 | Args: 148 | category_ids (``str | list[str]``): One or more category IDs. 149 | delivery_days (``int``): Estimated delivery days. 150 | fields (``str | list[str]``): The fields to include in the results list. Defaults to all. 151 | keywords (``str``): Search products based on keywords. 152 | max_sale_price (``int``): Filters products with price below the specified value. 153 | Prices appear in lowest currency denomination. So $31.41 should be 3141. 154 | min_sale_price (``int``): Filters products with price above the specified value. 155 | Prices appear in lowest currency denomination. So $31.41 should be 3141. 156 | page_no (``int``): 157 | page_size (``int``): Products on each page. Should be between 1 and 50. 158 | platform_product_type (``models.ProductType``): Specify platform product type. 159 | ship_to_country (``str``): Filter products that can be sent to that country. 160 | Returns the price according to the country's tax rate policy. 161 | sort (``models.SortBy``): Specifies the sort method. 162 | 163 | Returns: 164 | ``models.HotProductsResponse``: Contains response information and the list of products. 165 | 166 | Raises: 167 | ``ProductsNotFoudException`` 168 | ``ApiRequestException`` 169 | ``ApiRequestResponseException`` 170 | """ 171 | request = aliapi.rest.AliexpressAffiliateHotproductQueryRequest() 172 | request.app_signature = self._app_signature 173 | request.category_ids = get_list_as_string(category_ids) 174 | request.delivery_days = str(delivery_days) 175 | request.fields = get_list_as_string(fields) 176 | request.keywords = keywords 177 | request.max_sale_price = max_sale_price 178 | request.min_sale_price = min_sale_price 179 | request.page_no = page_no 180 | request.page_size = page_size 181 | request.platform_product_type = platform_product_type 182 | request.ship_to_country = ship_to_country 183 | request.sort = sort 184 | request.target_currency = self._currency 185 | request.target_language = self._language 186 | request.tracking_id = self._tracking_id 187 | 188 | response = api_request(request, 'aliexpress_affiliate_hotproduct_query_response') 189 | 190 | if response.current_record_count > 0: 191 | response.products = parse_products(response.products.product) 192 | return response 193 | else: 194 | raise ProductsNotFoudException('No products found with current parameters') 195 | 196 | 197 | def get_products(self, 198 | category_ids: Union[str, List[str]] = None, 199 | delivery_days: int = None, 200 | fields: Union[str, List[str]] = None, 201 | keywords: str = None, 202 | max_sale_price: int = None, 203 | min_sale_price: int = None, 204 | page_no: int = None, 205 | page_size: int = None, 206 | platform_product_type: models.ProductType = None, 207 | ship_to_country: str = None, 208 | sort: models.SortBy = None, 209 | **kwargs) -> models.ProductsResponse: 210 | """Search for affiliated products. 211 | 212 | Args: 213 | category_ids (``str | list[str]``): One or more category IDs. 214 | delivery_days (``int``): Estimated delivery days. 215 | fields (``str | list[str]``): The fields to include in the results list. Defaults to all. 216 | keywords (``str``): Search products based on keywords. 217 | max_sale_price (``int``): Filters products with price below the specified value. 218 | Prices appear in lowest currency denomination. So $31.41 should be 3141. 219 | min_sale_price (``int``): Filters products with price above the specified value. 220 | Prices appear in lowest currency denomination. So $31.41 should be 3141. 221 | page_no (``int``): 222 | page_size (``int``): Products on each page. Should be between 1 and 50. 223 | platform_product_type (``models.ProductType``): Specify platform product type. 224 | ship_to_country (``str``): Filter products that can be sent to that country. 225 | Returns the price according to the country's tax rate policy. 226 | sort (``models.SortBy``): Specifies the sort method. 227 | 228 | Returns: 229 | ``models.ProductsResponse``: Contains response information and the list of products. 230 | 231 | Raises: 232 | ``ProductsNotFoudException`` 233 | ``ApiRequestException`` 234 | ``ApiRequestResponseException`` 235 | """ 236 | request = aliapi.rest.AliexpressAffiliateProductQueryRequest() 237 | request.app_signature = self._app_signature 238 | request.category_ids = get_list_as_string(category_ids) 239 | request.delivery_days = str(delivery_days) 240 | request.fields = get_list_as_string(fields) 241 | request.keywords = keywords 242 | request.max_sale_price = max_sale_price 243 | request.min_sale_price = min_sale_price 244 | request.page_no = page_no 245 | request.page_size = page_size 246 | request.platform_product_type = platform_product_type 247 | request.ship_to_country = ship_to_country 248 | request.sort = sort 249 | request.target_currency = self._currency 250 | request.target_language = self._language 251 | request.tracking_id = self._tracking_id 252 | 253 | response = api_request(request, 'aliexpress_affiliate_product_query_response') 254 | 255 | if response.current_record_count > 0: 256 | response.products = parse_products(response.products.product) 257 | return response 258 | else: 259 | raise ProductsNotFoudException('No products found with current parameters') 260 | 261 | 262 | def get_categories(self, **kwargs) -> List[Union[models.Category, ChildCategory]]: 263 | """Get all available categories, both parent and child. 264 | 265 | Returns: 266 | ``list[models.Category | models.ChildCategory]``: A list of categories. 267 | 268 | Raises: 269 | ``CategoriesNotFoudException`` 270 | ``ApiRequestException`` 271 | ``ApiRequestResponseException`` 272 | """ 273 | request = aliapi.rest.AliexpressAffiliateCategoryGetRequest() 274 | request.app_signature = self._app_signature 275 | 276 | response = api_request(request, 'aliexpress_affiliate_category_get_response') 277 | 278 | if response.total_result_count > 0: 279 | self.categories = response.categories.category 280 | return self.categories 281 | else: 282 | raise CategoriesNotFoudException('No categories found') 283 | 284 | 285 | def get_parent_categories(self, use_cache=True, **kwargs) -> List[models.Category]: 286 | """Get all available parent categories. 287 | 288 | Args: 289 | use_cache (``bool``): Uses cached categories to reduce API requests. 290 | 291 | Returns: 292 | ``list[models.Category]``: A list of parent categories. 293 | 294 | Raises: 295 | ``CategoriesNotFoudException`` 296 | ``ApiRequestException`` 297 | ``ApiRequestResponseException`` 298 | """ 299 | if not use_cache or not self.categories: 300 | self.get_categories() 301 | return filter_parent_categories(self.categories) 302 | 303 | 304 | def get_child_categories(self, parent_category_id: int, use_cache=True, **kwargs) -> List[models.ChildCategory]: 305 | """Get all available child categories for a specific parent category. 306 | 307 | Args: 308 | parent_category_id (``int``): The parent category id. 309 | use_cache (``bool``): Uses cached categories to reduce API requests. 310 | 311 | Returns: 312 | ``list[models.ChildCategory]``: A list of child categories. 313 | 314 | Raises: 315 | ``CategoriesNotFoudException`` 316 | ``ApiRequestException`` 317 | ``ApiRequestResponseException`` 318 | """ 319 | if not use_cache or not self.categories: 320 | self.get_categories() 321 | return filter_child_categories(self.categories, parent_category_id) 322 | 323 | 324 | def smart_match_product(self, 325 | device_id: str, 326 | app: str = None, 327 | country: str = None, 328 | device: str = None, 329 | fields: Union[str, List[str]] = None, 330 | keywords: str = None, 331 | page_no: int = None, 332 | product_id: str = None, 333 | site: str = None, 334 | target_currency: str = None, 335 | target_language: str = None, 336 | tracking_id: str = None, 337 | user: str = None, 338 | **kwargs) -> models.HotProductsResponse: 339 | """ 340 | Get affiliated products using smart match based on keyword and device information. 341 | 342 | Args: 343 | country (``str``): Country code for target location. 344 | device (``str``): Device type for targeting (e.g., "mobile", "desktop"). 345 | device_id (``str``): Unique device ID. 346 | fields (``str | list[str]``): Fields to include in the results list. Defaults to all. 347 | keywords (``str``): Search products based on keywords. 348 | page_no (``int``): Page number of results to fetch. 349 | product_id (``str``): Specific product ID to match (optional). 350 | site (``str``): Site information for product targeting. 351 | target_currency (``str``): Currency code for prices (default is EUR). 352 | target_language (``str``): Language code for results (default is ES). 353 | tracking_id (``str``): Affiliate tracking ID for results. 354 | user (``str``): User identifier for additional targeting (optional). 355 | 356 | Returns: 357 | ``models.ProductSmartmatchResponse``: Contains response information and the list of products. 358 | 359 | Raises: 360 | ``ProductsNotFoundException`` 361 | ``ApiRequestException`` 362 | ``ApiRequestResponseException`` 363 | """ 364 | request = aliapi.rest.AliexpressAffiliateProductSmartmatchRequest() 365 | request.app = app, 366 | request.app_signature = self._app_signature 367 | request.country = country 368 | request.device = device 369 | request.device_id = device_id 370 | request.fields = get_list_as_string(fields) 371 | request.keywords = keywords 372 | request.page_no = page_no 373 | request.product_id = product_id 374 | request.site = site 375 | request.target_currency = target_currency 376 | request.target_language = target_language 377 | request.tracking_id = tracking_id 378 | request.user = user 379 | 380 | response = api_request(request, 'aliexpress_affiliate_product_smartmatch_response') 381 | 382 | if hasattr(response, 'products') and response.products: 383 | response.products = parse_products(response.products.product) 384 | return response 385 | else: 386 | raise ProductsNotFoudException('No products found with current parameters') 387 | 388 | def get_order_list(self, 389 | status: str, 390 | start_time: str, 391 | end_time: str, 392 | fields: Union[str, List[str]] = None, 393 | locale_site: str = None, 394 | page_no: int = None, 395 | page_size: int = None, 396 | **kwargs) -> models.OrderListResponse: 397 | """ 398 | Retrieve a list of affiliate orders from AliExpress. 399 | 400 | Args: 401 | start_time (str): Start time in format 'YYYY-MM-DD HH:MM:SS'. 402 | end_time (str): End time in format 'YYYY-MM-DD HH:MM:SS'. 403 | fields (str | list[str]): The fields to include in the results list. 404 | locale_site (str): Locale site, such as 'ru_site' for the Russian site. 405 | page_no (int): Page number to fetch. 406 | page_size (int): Number of records per page, up to 50. 407 | status (str): Status filter for the orders, e.g., 'Payment Completed'. 408 | 409 | Returns: 410 | OrderListResponse: Contains response information and the list of orders. 411 | 412 | Raises: 413 | ProductsNotFoundException: If no orders are found for the specified parameters. 414 | ApiRequestException: If the API request fails. 415 | """ 416 | request = aliapi.rest.AliexpressAffiliateOrderListRequest() 417 | request.app_signature = self._app_signature 418 | request.start_time = start_time 419 | request.end_time = end_time 420 | request.fields = ','.join(fields) if isinstance(fields, list) else fields 421 | request.locale_site = locale_site 422 | request.page_no = page_no 423 | request.page_size = page_size 424 | request.status = status 425 | 426 | response = api_request(request, 'aliexpress_affiliate_order_list_response') 427 | 428 | if response.current_record_count > 0: 429 | return response 430 | else: 431 | raise OrdersNotFoundException("No orders found for the specified parameters") 432 | 433 | 434 | -------------------------------------------------------------------------------- /aliexpress_api/errors/__init__.py: -------------------------------------------------------------------------------- 1 | from .exceptions import * 2 | -------------------------------------------------------------------------------- /aliexpress_api/errors/exceptions.py: -------------------------------------------------------------------------------- 1 | """Custom exceptions module""" 2 | 3 | 4 | class AliexpressException(Exception): 5 | """Common base class for all AliExpress API exceptions.""" 6 | def __init__(self, reason: str): 7 | super().__init__() 8 | self.reason = reason 9 | 10 | def __str__(self) -> str: 11 | return '%s' % self.reason 12 | 13 | 14 | class InvalidArgumentException(AliexpressException): 15 | """Raised when arguments are not correct.""" 16 | pass 17 | 18 | 19 | class ProductIdNotFoundException(AliexpressException): 20 | """Raised if the product ID is not found.""" 21 | pass 22 | 23 | class ApiRequestException(AliexpressException): 24 | """Raised if the request to AliExpress API fails""" 25 | pass 26 | 27 | class ApiRequestResponseException(AliexpressException): 28 | """Raised if the request response is not valid""" 29 | pass 30 | 31 | class ProductsNotFoudException(AliexpressException): 32 | """Raised if no products are found""" 33 | pass 34 | 35 | class CategoriesNotFoudException(AliexpressException): 36 | """Raised if no categories are found""" 37 | pass 38 | 39 | class InvalidTrackingIdException(AliexpressException): 40 | """Raised if the tracking ID is not present or invalid""" 41 | pass 42 | 43 | class OrdersNotFoundException(AliexpressException): 44 | """Raised if no orders are found""" 45 | pass 46 | 47 | -------------------------------------------------------------------------------- /aliexpress_api/helpers/__init__.py: -------------------------------------------------------------------------------- 1 | from .requests import api_request 2 | from .arguments import get_list_as_string, get_product_ids 3 | from .products import parse_products 4 | from .categories import filter_parent_categories, filter_child_categories 5 | -------------------------------------------------------------------------------- /aliexpress_api/helpers/arguments.py: -------------------------------------------------------------------------------- 1 | from ..tools.get_product_id import get_product_id 2 | from ..errors.exceptions import InvalidArgumentException 3 | 4 | 5 | def get_list_as_string(value): 6 | if value is None: 7 | return None 8 | 9 | if isinstance(value, str): 10 | return value 11 | 12 | elif isinstance(value, list): 13 | return ','.join(value) 14 | 15 | else: 16 | raise InvalidArgumentException('Argument should be a list or string: ' + str(value)) 17 | 18 | 19 | def get_product_ids(values): 20 | if isinstance(values, str): 21 | values = values.split(',') 22 | 23 | elif not isinstance(values, list): 24 | raise InvalidArgumentException('Argument product_ids should be a list or string') 25 | 26 | product_ids = [] 27 | for value in values: 28 | product_ids.append(get_product_id(value)) 29 | 30 | return product_ids 31 | -------------------------------------------------------------------------------- /aliexpress_api/helpers/categories.py: -------------------------------------------------------------------------------- 1 | from typing import List, Union 2 | from .. import models 3 | 4 | 5 | def filter_parent_categories(categories: List[Union[models.Category, models.ChildCategory]]) -> List[models.Category]: 6 | filtered_categories = [] 7 | 8 | for category in categories: 9 | if not hasattr(category, 'parent_category_id'): 10 | filtered_categories.append(category) 11 | 12 | return filtered_categories 13 | 14 | 15 | def filter_child_categories(categories: List[Union[models.Category, models.ChildCategory]], 16 | parent_category_id: int) -> List[models.ChildCategory]: 17 | filtered_categories = [] 18 | 19 | for category in categories: 20 | if hasattr(category, 'parent_category_id') and category.parent_category_id == parent_category_id: 21 | filtered_categories.append(category) 22 | 23 | return filtered_categories 24 | -------------------------------------------------------------------------------- /aliexpress_api/helpers/products.py: -------------------------------------------------------------------------------- 1 | def parse_product(product): 2 | product.product_small_image_urls = product.product_small_image_urls.string 3 | return product 4 | 5 | 6 | def parse_products(products): 7 | new_products = [] 8 | 9 | for product in products: 10 | new_products.append(parse_product(product)) 11 | 12 | return new_products 13 | -------------------------------------------------------------------------------- /aliexpress_api/helpers/requests.py: -------------------------------------------------------------------------------- 1 | from types import SimpleNamespace 2 | import json 3 | 4 | from ..errors import ApiRequestException, ApiRequestResponseException 5 | 6 | 7 | def api_request(request, response_name): 8 | try: 9 | response = request.getResponse() 10 | except Exception as error: 11 | if hasattr(error, 'message'): 12 | raise ApiRequestException(error.message) from error 13 | raise ApiRequestException(error) from error 14 | 15 | try: 16 | response = response[response_name]['resp_result'] 17 | response = json.dumps(response) 18 | response = json.loads(response, object_hook=lambda d: SimpleNamespace(**d)) 19 | except Exception as error: 20 | raise ApiRequestResponseException(error) from error 21 | 22 | if response.resp_code == 200: 23 | return response.result 24 | else: 25 | raise ApiRequestResponseException(f'Response code {response.resp_code} - {response.resp_msg}') 26 | -------------------------------------------------------------------------------- /aliexpress_api/models/__init__.py: -------------------------------------------------------------------------------- 1 | from .languages import Language 2 | from .currencies import Currency 3 | from .request_parameters import ProductType, SortBy, LinkType 4 | from .affiliate_link import AffiliateLink 5 | from .hotproducts import HotProductsResponse 6 | from .product import Product, ProductsResponse 7 | from .category import Category, ChildCategory 8 | from .order import Order 9 | from .orderlist import OrderListResponse 10 | -------------------------------------------------------------------------------- /aliexpress_api/models/affiliate_link.py: -------------------------------------------------------------------------------- 1 | class AffiliateLink: 2 | promotion_link: str 3 | source_value: str 4 | -------------------------------------------------------------------------------- /aliexpress_api/models/category.py: -------------------------------------------------------------------------------- 1 | class Category: 2 | category_id: int 3 | category_name: str 4 | 5 | 6 | class ChildCategory(Category): 7 | parent_category_id: int 8 | -------------------------------------------------------------------------------- /aliexpress_api/models/currencies.py: -------------------------------------------------------------------------------- 1 | class Currency: 2 | USD = 'USD' 3 | GBP = 'GBP' 4 | CAD = 'CAD' 5 | EUR = 'EUR' 6 | UAH = 'UAH' 7 | MXN = 'MXN' 8 | TRY = 'TRY' 9 | RUB = 'RUB' 10 | BRL = 'BRL' 11 | AUD = 'AUD' 12 | INR = 'INR' 13 | JPY = 'JPY' 14 | IDR = 'IDR' 15 | SEK = 'SEK' 16 | KRW = 'KRW' 17 | -------------------------------------------------------------------------------- /aliexpress_api/models/hotproducts.py: -------------------------------------------------------------------------------- 1 | from .product import Product 2 | from typing import List 3 | 4 | 5 | class HotProductsResponse: 6 | current_page_no: int 7 | current_record_count: int 8 | total_record_count: int 9 | products: List[Product] 10 | -------------------------------------------------------------------------------- /aliexpress_api/models/languages.py: -------------------------------------------------------------------------------- 1 | class Language: 2 | EN = 'EN' 3 | RU = 'RU' 4 | PT = 'PT' 5 | ES = 'ES' 6 | FR = 'FR' 7 | ID = 'ID' 8 | IT = 'IT' 9 | TH = 'TH' 10 | JA = 'JA' 11 | AR = 'AR' 12 | VI = 'VI' 13 | TR = 'TR' 14 | DE = 'DE' 15 | HE = 'HE' 16 | KO = 'KO' 17 | NL = 'NL' 18 | PL = 'PL' 19 | MX = 'MX' 20 | CL = 'CL' 21 | IW = 'IW' 22 | IN = 'IN' 23 | -------------------------------------------------------------------------------- /aliexpress_api/models/order.py: -------------------------------------------------------------------------------- 1 | class Order: 2 | estimated_finished_commission: str 3 | product_detail_url: str 4 | estimated_paid_commission: str 5 | product_count: int 6 | order_number: str 7 | is_hot_product: str 8 | parent_order_number: str 9 | product_main_image_url: str 10 | order_status: str 11 | category_id: int 12 | settled_currency: str 13 | product_id: int 14 | order_type: str 15 | tracking_id: str 16 | created_time: str 17 | finished_time: str 18 | completed_settlement_time: str 19 | paid_time: str 20 | is_new_buyer: str 21 | sub_order_id: str 22 | custom_parameters: str 23 | ship_to_country: str 24 | product_title: str 25 | incentive_commission_rate: str 26 | new_buyer_bonus_commission: str 27 | estimated_incentive_paid_commission: str 28 | is_affiliate_product: str 29 | paid_amount: str 30 | effect_detail_status: str 31 | estimated_incentive_finished_commission: str 32 | commission_rate: str 33 | finished_amount: str 34 | order_platform: str 35 | order_id: str 36 | -------------------------------------------------------------------------------- /aliexpress_api/models/orderlist.py: -------------------------------------------------------------------------------- 1 | from .order import Order 2 | from typing import List 3 | 4 | class OrderListResponse: 5 | total_record_count: int 6 | current_record_count: int 7 | total_page_no: int 8 | current_page_no: int 9 | orders: List[Order] -------------------------------------------------------------------------------- /aliexpress_api/models/product.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Product: 5 | app_sale_price: str 6 | app_sale_price_currency: str 7 | commission_rate: str 8 | discount: str 9 | evaluate_rate: str 10 | first_level_category_id: int 11 | first_level_category_name: str 12 | lastest_volume: int 13 | hot_product_commission_rate: str 14 | lastest_volume: int 15 | original_price: str 16 | original_price_currency: str 17 | product_detail_url: str 18 | product_id: int 19 | product_main_image_url: str 20 | product_small_image_urls: List[str] 21 | product_title: str 22 | product_video_url: str 23 | promotion_link: str 24 | relevant_market_commission_rate: str 25 | sale_price: str 26 | sale_price_currency: str 27 | second_level_category_id: int 28 | second_level_category_name: str 29 | shop_id: int 30 | shop_url: str 31 | target_app_sale_price: str 32 | target_app_sale_price_currency: str 33 | target_original_price: str 34 | target_original_price_currency: str 35 | target_sale_price: str 36 | target_sale_price_currency: str 37 | 38 | 39 | class ProductsResponse: 40 | current_page_no: int 41 | current_record_count: int 42 | total_record_count: int 43 | products: List[Product] 44 | -------------------------------------------------------------------------------- /aliexpress_api/models/request_parameters.py: -------------------------------------------------------------------------------- 1 | class ProductType: 2 | ALL = 'ALL' 3 | PLAZA = 'PLAZA' 4 | TMALL = 'TMALL' 5 | 6 | class SortBy: 7 | SALE_PRICE_ASC = 'SALE_PRICE_ASC' 8 | SALE_PRICE_DESC = 'SALE_PRICE_DESC' 9 | LAST_VOLUME_ASC = 'LAST_VOLUME_ASC' 10 | LAST_VOLUME_DESC = 'LAST_VOLUME_DESC' 11 | 12 | class LinkType: 13 | NORMAL = 0 14 | HOTLINK = 2 15 | -------------------------------------------------------------------------------- /aliexpress_api/skd/__init__.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Created on 2012-6-29 3 | 4 | @author: lihao 5 | ''' 6 | from .api.base import sign 7 | 8 | 9 | 10 | class appinfo(object): 11 | def __init__(self,appkey,secret): 12 | self.appkey = appkey 13 | self.secret = secret 14 | 15 | def getDefaultAppInfo(): 16 | pass 17 | 18 | 19 | def setDefaultAppInfo(appkey,secret): 20 | default = appinfo(appkey,secret) 21 | global getDefaultAppInfo 22 | getDefaultAppInfo = lambda: default 23 | -------------------------------------------------------------------------------- /aliexpress_api/skd/api/__init__.py: -------------------------------------------------------------------------------- 1 | from .rest import * 2 | from .base import FileItem 3 | -------------------------------------------------------------------------------- /aliexpress_api/skd/api/base.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2012-7-3 4 | 5 | @author: lihao 6 | """ 7 | 8 | 9 | import hashlib 10 | import http.client as httplib 11 | import itertools 12 | import json 13 | import mimetypes 14 | import time 15 | import urllib 16 | 17 | """ 18 | 定义一些系统变量 19 | """ 20 | 21 | SYSTEM_GENERATE_VERSION = "taobao-sdk-python-20200924" 22 | 23 | P_APPKEY = "app_key" 24 | P_API = "method" 25 | P_SESSION = "session" 26 | P_ACCESS_TOKEN = "access_token" 27 | P_VERSION = "v" 28 | P_FORMAT = "format" 29 | P_TIMESTAMP = "timestamp" 30 | P_SIGN = "sign" 31 | P_SIGN_METHOD = "sign_method" 32 | P_PARTNER_ID = "partner_id" 33 | 34 | P_CODE = "code" 35 | P_SUB_CODE = "sub_code" 36 | P_MSG = "msg" 37 | P_SUB_MSG = "sub_msg" 38 | 39 | 40 | N_REST = "/sync" 41 | 42 | 43 | def sign(secret, parameters): 44 | # =========================================================================== 45 | # '''签名方法 46 | # @param secret: 签名需要的密钥 47 | # @param parameters: 支持字典和string两种 48 | # ''' 49 | # =========================================================================== 50 | # 如果parameters 是字典类的话 51 | if hasattr(parameters, "items"): 52 | keys = parameters.keys() 53 | keys = list(keys) 54 | keys.sort() 55 | 56 | parameters = "%s%s%s" % ( 57 | secret, 58 | str().join("%s%s" % (key, parameters[key]) for key in keys), 59 | secret, 60 | ) 61 | parameters = parameters.encode("utf-8") 62 | sign = hashlib.md5(parameters).hexdigest().upper() 63 | return sign 64 | 65 | 66 | def mixStr(pstr): 67 | if isinstance(pstr, str): 68 | return pstr 69 | elif isinstance(pstr, str): 70 | return pstr.encode("utf-8") 71 | else: 72 | return str(pstr) 73 | 74 | 75 | class FileItem(object): 76 | def __init__(self, filename=None, content=None): 77 | self.filename = filename 78 | self.content = content 79 | 80 | 81 | class MultiPartForm(object): 82 | """Accumulate the data to be used when posting a form.""" 83 | 84 | def __init__(self): 85 | self.form_fields = [] 86 | self.files = [] 87 | self.boundary = "PYTHON_SDK_BOUNDARY" 88 | return 89 | 90 | def get_content_type(self): 91 | return "multipart/form-data; boundary=%s" % self.boundary 92 | 93 | def add_field(self, name, value): 94 | """Add a simple field to the form data.""" 95 | self.form_fields.append((name, str(value))) 96 | return 97 | 98 | def add_file(self, fieldname, filename, fileHandle, mimetype=None): 99 | """Add a file to be uploaded.""" 100 | body = fileHandle.read() 101 | if mimetype is None: 102 | mimetype = mimetypes.guess_type(filename)[0] or "application/octet-stream" 103 | self.files.append( 104 | (mixStr(fieldname), mixStr(filename), mixStr(mimetype), mixStr(body)) 105 | ) 106 | return 107 | 108 | def __str__(self): 109 | """Return a string representing the form data, including attached files.""" 110 | # Build a list of lists, each containing "lines" of the 111 | # request. Each part is separated by a boundary string. 112 | # Once the list is built, return a string where each 113 | # line is separated by '\r\n'. 114 | parts = [] 115 | part_boundary = "--" + self.boundary 116 | 117 | # Add the form fields 118 | parts.extend( 119 | [ 120 | part_boundary, 121 | 'Content-Disposition: form-data; name="%s"' % name, 122 | "Content-Type: text/plain; charset=UTF-8", 123 | "", 124 | value, 125 | ] 126 | for name, value in self.form_fields 127 | ) 128 | 129 | # Add the files to upload 130 | parts.extend( 131 | [ 132 | part_boundary, 133 | 'Content-Disposition: file; name="%s"; filename="%s"' 134 | % (field_name, filename), 135 | "Content-Type: %s" % content_type, 136 | "Content-Transfer-Encoding: binary", 137 | "", 138 | body, 139 | ] 140 | for field_name, filename, content_type, body in self.files 141 | ) 142 | 143 | # Flatten the list and add closing boundary marker, 144 | # then return CR+LF separated data 145 | flattened = list(itertools.chain(*parts)) 146 | flattened.append("--" + self.boundary + "--") 147 | flattened.append("") 148 | return "\r\n".join(flattened) 149 | 150 | 151 | class TopException(Exception): 152 | # =========================================================================== 153 | # 业务异常类 154 | # =========================================================================== 155 | def __init__(self): 156 | self.errorcode = None 157 | self.message = None 158 | self.subcode = None 159 | self.submsg = None 160 | self.application_host = None 161 | self.service_host = None 162 | 163 | def __str__(self, *args, **kwargs): 164 | sb = ( 165 | "errorcode=" 166 | + mixStr(self.errorcode) 167 | + " message=" 168 | + mixStr(self.message) 169 | + " subcode=" 170 | + mixStr(self.subcode) 171 | + " submsg=" 172 | + mixStr(self.submsg) 173 | + " application_host=" 174 | + mixStr(self.application_host) 175 | + " service_host=" 176 | + mixStr(self.service_host) 177 | ) 178 | return sb 179 | 180 | 181 | class RequestException(Exception): 182 | # =========================================================================== 183 | # 请求连接异常类 184 | # =========================================================================== 185 | pass 186 | 187 | 188 | class RestApi(object): 189 | # =========================================================================== 190 | # Rest api的基类 191 | # =========================================================================== 192 | 193 | def __init__(self, domain="api-sg.aliexpress.com", port=80): 194 | # ======================================================================= 195 | # 初始化基类 196 | # Args @param domain: 请求的域名或者ip 197 | # @param port: 请求的端口 198 | # ======================================================================= 199 | self.__domain = domain 200 | self.__port = port 201 | self.__httpmethod = "POST" 202 | from .. import getDefaultAppInfo 203 | 204 | if getDefaultAppInfo(): 205 | self.__app_key = getDefaultAppInfo().appkey 206 | self.__secret = getDefaultAppInfo().secret 207 | 208 | def get_request_header(self): 209 | return { 210 | "Content-type": "application/x-www-form-urlencoded;charset=UTF-8", 211 | "Cache-Control": "no-cache", 212 | "Connection": "Keep-Alive", 213 | } 214 | 215 | def set_app_info(self, appinfo): 216 | # ======================================================================= 217 | # 设置请求的app信息 218 | # @param appinfo: import top 219 | # appinfo aliexpress.top.appinfo(appkey,secret) 220 | # ======================================================================= 221 | self.__app_key = appinfo.appkey 222 | self.__secret = appinfo.secret 223 | 224 | def getapiname(self): 225 | return "" 226 | 227 | def getMultipartParas(self): 228 | return [] 229 | 230 | def getTranslateParas(self): 231 | return {} 232 | 233 | def _check_requst(self): 234 | pass 235 | 236 | def getResponse(self, authrize=None, timeout=30): 237 | # ======================================================================= 238 | # 获取response结果 239 | # ======================================================================= 240 | if self.__port == 443: 241 | connection = httplib.HTTPSConnection( 242 | self.__domain, self.__port, timeout=timeout 243 | ) 244 | else: 245 | connection = httplib.HTTPConnection( 246 | self.__domain, self.__port, timeout=timeout 247 | ) 248 | timestamp_temp = "%.2f" % (float(time.time())) 249 | timestamp_temp = str(int(float(timestamp_temp) * 1000)) 250 | 251 | sys_parameters = { 252 | P_FORMAT: "json", 253 | P_APPKEY: self.__app_key, 254 | P_SIGN_METHOD: "md5", 255 | P_VERSION: "2.0", 256 | P_TIMESTAMP: timestamp_temp, 257 | P_PARTNER_ID: SYSTEM_GENERATE_VERSION, 258 | P_API: self.getapiname(), 259 | } 260 | if authrize is not None: 261 | sys_parameters[P_SESSION] = authrize 262 | application_parameter = self.getApplicationParameters() 263 | sign_parameter = sys_parameters.copy() 264 | sign_parameter.update(application_parameter) 265 | sys_parameters[P_SIGN] = sign(self.__secret, sign_parameter) 266 | connection.connect() 267 | 268 | header = self.get_request_header() 269 | if self.getMultipartParas(): 270 | form = MultiPartForm() 271 | for key, value in application_parameter.items(): 272 | form.add_field(key, value) 273 | for key in self.getMultipartParas(): 274 | fileitem = getattr(self, key) 275 | if fileitem and isinstance(fileitem, FileItem): 276 | form.add_file(key, fileitem.filename, fileitem.content) 277 | body = str(form) 278 | header["Content-type"] = form.get_content_type() 279 | else: 280 | body = urllib.parse.urlencode(application_parameter) 281 | 282 | url = N_REST + "?" + urllib.parse.urlencode(sys_parameters) 283 | connection.request(self.__httpmethod, url, body=body, headers=header) 284 | response = connection.getresponse() 285 | if response.status != 200: 286 | raise RequestException( 287 | "invalid http status " 288 | + str(response.status) 289 | + ",detail body:" 290 | + response.read() 291 | ) 292 | result = response.read() 293 | jsonobj = json.loads(result) 294 | if "error_response" in jsonobj: 295 | error = TopException() 296 | if P_CODE in jsonobj["error_response"]: 297 | error.errorcode = jsonobj["error_response"][P_CODE] 298 | if P_MSG in jsonobj["error_response"]: 299 | error.message = jsonobj["error_response"][P_MSG] 300 | if P_SUB_CODE in jsonobj["error_response"]: 301 | error.subcode = jsonobj["error_response"][P_SUB_CODE] 302 | if P_SUB_MSG in jsonobj["error_response"]: 303 | error.submsg = jsonobj["error_response"][P_SUB_MSG] 304 | error.application_host = response.getheader("Application-Host", "") 305 | error.service_host = response.getheader("Location-Host", "") 306 | raise error 307 | return jsonobj 308 | 309 | def getApplicationParameters(self): 310 | application_parameter = {} 311 | for key in self.__dict__: 312 | value = self.__dict__[key] 313 | if ( 314 | not key.startswith("__") 315 | and not key in self.getMultipartParas() 316 | and not key.startswith("_RestApi__") 317 | and value is not None 318 | ): 319 | if key.startswith("_"): 320 | application_parameter[key[1:]] = value 321 | else: 322 | application_parameter[key] = value 323 | # 查询翻译字典来规避一些关键字属性 324 | translate_parameter = self.getTranslateParas() 325 | for key in application_parameter: 326 | value = application_parameter[key] 327 | if key in translate_parameter: 328 | application_parameter[translate_parameter[key]] = application_parameter[ 329 | key 330 | ] 331 | del application_parameter[key] 332 | return application_parameter 333 | -------------------------------------------------------------------------------- /aliexpress_api/skd/api/rest/AliexpressAffiliateCategoryGetRequest.py: -------------------------------------------------------------------------------- 1 | """ 2 | Created by auto_sdk on 2020.03.09 3 | """ 4 | from ..base import RestApi 5 | 6 | 7 | class AliexpressAffiliateCategoryGetRequest(RestApi): 8 | def __init__(self, domain="api-sg.aliexpress.com", port=80): 9 | RestApi.__init__(self, domain, port) 10 | self.app_signature = None 11 | 12 | def getapiname(self): 13 | return "aliexpress.affiliate.category.get" 14 | -------------------------------------------------------------------------------- /aliexpress_api/skd/api/rest/AliexpressAffiliateFeaturedpromoGetRequest.py: -------------------------------------------------------------------------------- 1 | """ 2 | Created by auto_sdk on 2020.09.25 3 | """ 4 | from ..base import RestApi 5 | 6 | 7 | class AliexpressAffiliateFeaturedpromoGetRequest(RestApi): 8 | def __init__(self, domain="api-sg.aliexpress.com", port=80): 9 | RestApi.__init__(self, domain, port) 10 | self.app_signature = None 11 | self.fields = None 12 | 13 | def getapiname(self): 14 | return "aliexpress.affiliate.featuredpromo.get" 15 | -------------------------------------------------------------------------------- /aliexpress_api/skd/api/rest/AliexpressAffiliateFeaturedpromoProductsGetRequest.py: -------------------------------------------------------------------------------- 1 | """ 2 | Created by auto_sdk on 2021.05.17 3 | """ 4 | from ..base import RestApi 5 | 6 | 7 | class AliexpressAffiliateFeaturedpromoProductsGetRequest(RestApi): 8 | def __init__(self, domain="api-sg.aliexpress.com", port=80): 9 | RestApi.__init__(self, domain, port) 10 | self.app_signature = None 11 | self.category_id = None 12 | self.country = None 13 | self.fields = None 14 | self.page_no = None 15 | self.page_size = None 16 | self.promotion_end_time = None 17 | self.promotion_name = None 18 | self.promotion_start_time = None 19 | self.sort = None 20 | self.target_currency = None 21 | self.target_language = None 22 | self.tracking_id = None 23 | 24 | def getapiname(self): 25 | return "aliexpress.affiliate.featuredpromo.products.get" 26 | -------------------------------------------------------------------------------- /aliexpress_api/skd/api/rest/AliexpressAffiliateHotproductDownloadRequest.py: -------------------------------------------------------------------------------- 1 | """ 2 | Created by auto_sdk on 2021.05.12 3 | """ 4 | from ..base import RestApi 5 | 6 | 7 | class AliexpressAffiliateHotproductDownloadRequest(RestApi): 8 | def __init__(self, domain="api-sg.aliexpress.com", port=80): 9 | RestApi.__init__(self, domain, port) 10 | self.app_signature = None 11 | self.category_id = None 12 | self.country = None 13 | self.fields = None 14 | self.locale_site = None 15 | self.page_no = None 16 | self.page_size = None 17 | self.target_currency = None 18 | self.target_language = None 19 | self.tracking_id = None 20 | 21 | def getapiname(self): 22 | return "aliexpress.affiliate.hotproduct.download" 23 | -------------------------------------------------------------------------------- /aliexpress_api/skd/api/rest/AliexpressAffiliateHotproductQueryRequest.py: -------------------------------------------------------------------------------- 1 | """ 2 | Created by auto_sdk on 2021.05.20 3 | """ 4 | from ..base import RestApi 5 | 6 | 7 | class AliexpressAffiliateHotproductQueryRequest(RestApi): 8 | def __init__(self, domain="api-sg.aliexpress.com", port=80): 9 | RestApi.__init__(self, domain, port) 10 | self.app_signature = None 11 | self.category_ids = None 12 | self.delivery_days = None 13 | self.fields = None 14 | self.keywords = None 15 | self.max_sale_price = None 16 | self.min_sale_price = None 17 | self.page_no = None 18 | self.page_size = None 19 | self.platform_product_type = None 20 | self.ship_to_country = None 21 | self.sort = None 22 | self.target_currency = None 23 | self.target_language = None 24 | self.tracking_id = None 25 | 26 | def getapiname(self): 27 | return "aliexpress.affiliate.hotproduct.query" 28 | -------------------------------------------------------------------------------- /aliexpress_api/skd/api/rest/AliexpressAffiliateLinkGenerateRequest.py: -------------------------------------------------------------------------------- 1 | """ 2 | Created by auto_sdk on 2020.03.09 3 | """ 4 | from ..base import RestApi 5 | 6 | 7 | class AliexpressAffiliateLinkGenerateRequest(RestApi): 8 | def __init__(self, domain="api-sg.aliexpress.com", port=80): 9 | RestApi.__init__(self, domain, port) 10 | self.app_signature = None 11 | self.promotion_link_type = None 12 | self.source_values = None 13 | self.tracking_id = None 14 | 15 | def getapiname(self): 16 | return "aliexpress.affiliate.link.generate" 17 | -------------------------------------------------------------------------------- /aliexpress_api/skd/api/rest/AliexpressAffiliateOrderGetRequest.py: -------------------------------------------------------------------------------- 1 | """ 2 | Created by auto_sdk on 2021.03.05 3 | """ 4 | from ..base import RestApi 5 | 6 | 7 | class AliexpressAffiliateOrderGetRequest(RestApi): 8 | def __init__(self, domain="api-sg.aliexpress.com", port=80): 9 | RestApi.__init__(self, domain, port) 10 | self.app_signature = None 11 | self.fields = None 12 | self.order_ids = None 13 | 14 | def getapiname(self): 15 | return "aliexpress.affiliate.order.get" 16 | -------------------------------------------------------------------------------- /aliexpress_api/skd/api/rest/AliexpressAffiliateOrderListRequest.py: -------------------------------------------------------------------------------- 1 | """ 2 | Created by auto_sdk on 2021.06.02 3 | """ 4 | from ..base import RestApi 5 | 6 | 7 | class AliexpressAffiliateOrderListRequest(RestApi): 8 | def __init__(self, domain="api-sg.aliexpress.com", port=80): 9 | RestApi.__init__(self, domain, port) 10 | self.app_signature = None 11 | self.end_time = None 12 | self.fields = None 13 | self.locale_site = None 14 | self.page_no = None 15 | self.page_size = None 16 | self.start_time = None 17 | self.status = None 18 | 19 | def getapiname(self): 20 | return "aliexpress.affiliate.order.list" 21 | -------------------------------------------------------------------------------- /aliexpress_api/skd/api/rest/AliexpressAffiliateOrderListbyindexRequest.py: -------------------------------------------------------------------------------- 1 | """ 2 | Created by auto_sdk on 2021.05.10 3 | """ 4 | from ..base import RestApi 5 | 6 | 7 | class AliexpressAffiliateOrderListbyindexRequest(RestApi): 8 | def __init__(self, domain="api-sg.aliexpress.com", port=80): 9 | RestApi.__init__(self, domain, port) 10 | self.app_signature = None 11 | self.end_time = None 12 | self.fields = None 13 | self.page_size = None 14 | self.start_query_index_id = None 15 | self.start_time = None 16 | self.status = None 17 | 18 | def getapiname(self): 19 | return "aliexpress.affiliate.order.listbyindex" 20 | -------------------------------------------------------------------------------- /aliexpress_api/skd/api/rest/AliexpressAffiliateProductQueryRequest.py: -------------------------------------------------------------------------------- 1 | """ 2 | Created by auto_sdk on 2021.05.20 3 | """ 4 | from ..base import RestApi 5 | 6 | 7 | class AliexpressAffiliateProductQueryRequest(RestApi): 8 | def __init__(self, domain="api-sg.aliexpress.com", port=80): 9 | RestApi.__init__(self, domain, port) 10 | self.app_signature = None 11 | self.category_ids = None 12 | self.delivery_days = None 13 | self.fields = None 14 | self.keywords = None 15 | self.max_sale_price = None 16 | self.min_sale_price = None 17 | self.page_no = None 18 | self.page_size = None 19 | self.platform_product_type = None 20 | self.ship_to_country = None 21 | self.sort = None 22 | self.target_currency = None 23 | self.target_language = None 24 | self.tracking_id = None 25 | 26 | def getapiname(self): 27 | return "aliexpress.affiliate.product.query" 28 | -------------------------------------------------------------------------------- /aliexpress_api/skd/api/rest/AliexpressAffiliateProductSmartmatchRequest.py: -------------------------------------------------------------------------------- 1 | """ 2 | Created by auto_sdk on 2021.05.17 3 | """ 4 | from ..base import RestApi 5 | 6 | 7 | class AliexpressAffiliateProductSmartmatchRequest(RestApi): 8 | def __init__(self, domain="api-sg.aliexpress.com", port=80): 9 | RestApi.__init__(self, domain, port) 10 | self.app = None 11 | self.app_signature = None 12 | self.country = None 13 | self.device = None 14 | self.device_id = None 15 | self.fields = None 16 | self.keywords = None 17 | self.page_no = None 18 | self.product_id = None 19 | self.site = None 20 | self.target_currency = None 21 | self.target_language = None 22 | self.tracking_id = None 23 | self.user = None 24 | 25 | def getapiname(self): 26 | return "aliexpress.affiliate.product.smartmatch" 27 | -------------------------------------------------------------------------------- /aliexpress_api/skd/api/rest/AliexpressAffiliateProductdetailGetRequest.py: -------------------------------------------------------------------------------- 1 | """ 2 | Created by auto_sdk on 2021.05.17 3 | """ 4 | from ..base import RestApi 5 | 6 | 7 | class AliexpressAffiliateProductdetailGetRequest(RestApi): 8 | def __init__(self, domain="api-sg.aliexpress.com", port=80): 9 | RestApi.__init__(self, domain, port) 10 | self.app_signature = None 11 | self.country = None 12 | self.fields = None 13 | self.product_ids = None 14 | self.target_currency = None 15 | self.target_language = None 16 | self.tracking_id = None 17 | 18 | def getapiname(self): 19 | return "aliexpress.affiliate.productdetail.get" 20 | -------------------------------------------------------------------------------- /aliexpress_api/skd/api/rest/__init__.py: -------------------------------------------------------------------------------- 1 | from .AliexpressAffiliateProductSmartmatchRequest import AliexpressAffiliateProductSmartmatchRequest 2 | from .AliexpressAffiliateOrderGetRequest import AliexpressAffiliateOrderGetRequest 3 | from .AliexpressAffiliateOrderListRequest import AliexpressAffiliateOrderListRequest 4 | from .AliexpressAffiliateHotproductDownloadRequest import AliexpressAffiliateHotproductDownloadRequest 5 | from .AliexpressAffiliateProductdetailGetRequest import AliexpressAffiliateProductdetailGetRequest 6 | from .AliexpressAffiliateHotproductQueryRequest import AliexpressAffiliateHotproductQueryRequest 7 | from .AliexpressAffiliateFeaturedpromoProductsGetRequest import AliexpressAffiliateFeaturedpromoProductsGetRequest 8 | from .AliexpressAffiliateFeaturedpromoGetRequest import AliexpressAffiliateFeaturedpromoGetRequest 9 | from .AliexpressAffiliateProductQueryRequest import AliexpressAffiliateProductQueryRequest 10 | from .AliexpressAffiliateCategoryGetRequest import AliexpressAffiliateCategoryGetRequest 11 | from .AliexpressAffiliateOrderListbyindexRequest import AliexpressAffiliateOrderListbyindexRequest 12 | from .AliexpressAffiliateLinkGenerateRequest import AliexpressAffiliateLinkGenerateRequest 13 | -------------------------------------------------------------------------------- /aliexpress_api/tools/__init__.py: -------------------------------------------------------------------------------- 1 | from .get_product_id import get_product_id 2 | -------------------------------------------------------------------------------- /aliexpress_api/tools/get_product_id.py: -------------------------------------------------------------------------------- 1 | """Some useful tools.""" 2 | 3 | from ..errors import ProductIdNotFoundException 4 | import re 5 | 6 | 7 | def get_product_id(text: str) -> str: 8 | """Returns the product ID from a given text. Raises ProductIdNotFoundException on fail.""" 9 | # Return if text is a product ID 10 | if re.search(r'^[0-9]*$', text): 11 | return text 12 | 13 | # Extract product ID from URL 14 | asin = re.search(r'(\/)([0-9]*)(\.)', text) 15 | if asin: 16 | return asin.group(2) 17 | else: 18 | raise ProductIdNotFoundException('Product id not found: ' + text) 19 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | 3 | with open('README.md', 'r') as fh: 4 | long_description = fh.read() 5 | 6 | setuptools.setup( 7 | name='python-aliexpress-api', 8 | version='3.1.0', 9 | author='Sergio Abad', 10 | author_email='sergio.abad@bytelix.com', 11 | description='AliExpress API wrapper for Python', 12 | long_description=long_description, 13 | long_description_content_type='text/markdown', 14 | license='MIT', 15 | url='https://github.com/sergioteula/python-aliexpress-api', 16 | packages=setuptools.find_packages(), 17 | install_requires=['setuptools'], 18 | classifiers=[ 19 | 'Programming Language :: Python', 20 | 'License :: OSI Approved :: MIT License', 21 | 'Operating System :: OS Independent', 22 | ], 23 | python_requires='>=3.6', 24 | ) 25 | --------------------------------------------------------------------------------