lingxingapi 1.1.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- lingxingapi/__init__.py +7 -0
- lingxingapi/ads/__init__.py +0 -0
- lingxingapi/ads/api.py +5946 -0
- lingxingapi/ads/param.py +192 -0
- lingxingapi/ads/route.py +134 -0
- lingxingapi/ads/schema.py +2615 -0
- lingxingapi/api.py +557 -0
- lingxingapi/base/__init__.py +0 -0
- lingxingapi/base/api.py +568 -0
- lingxingapi/base/param.py +59 -0
- lingxingapi/base/route.py +11 -0
- lingxingapi/base/schema.py +198 -0
- lingxingapi/basic/__init__.py +0 -0
- lingxingapi/basic/api.py +466 -0
- lingxingapi/basic/param.py +72 -0
- lingxingapi/basic/route.py +20 -0
- lingxingapi/basic/schema.py +218 -0
- lingxingapi/errors.py +152 -0
- lingxingapi/fba/__init__.py +0 -0
- lingxingapi/fba/api.py +1691 -0
- lingxingapi/fba/param.py +250 -0
- lingxingapi/fba/route.py +30 -0
- lingxingapi/fba/schema.py +987 -0
- lingxingapi/fields.py +50 -0
- lingxingapi/finance/__init__.py +0 -0
- lingxingapi/finance/api.py +3091 -0
- lingxingapi/finance/param.py +616 -0
- lingxingapi/finance/route.py +44 -0
- lingxingapi/finance/schema.py +1243 -0
- lingxingapi/product/__init__.py +0 -0
- lingxingapi/product/api.py +2643 -0
- lingxingapi/product/param.py +934 -0
- lingxingapi/product/route.py +49 -0
- lingxingapi/product/schema.py +1004 -0
- lingxingapi/purchase/__init__.py +0 -0
- lingxingapi/purchase/api.py +496 -0
- lingxingapi/purchase/param.py +126 -0
- lingxingapi/purchase/route.py +11 -0
- lingxingapi/purchase/schema.py +215 -0
- lingxingapi/sales/__init__.py +0 -0
- lingxingapi/sales/api.py +3200 -0
- lingxingapi/sales/param.py +723 -0
- lingxingapi/sales/route.py +70 -0
- lingxingapi/sales/schema.py +1718 -0
- lingxingapi/source/__init__.py +0 -0
- lingxingapi/source/api.py +1799 -0
- lingxingapi/source/param.py +176 -0
- lingxingapi/source/route.py +38 -0
- lingxingapi/source/schema.py +1011 -0
- lingxingapi/tools/__init__.py +0 -0
- lingxingapi/tools/api.py +291 -0
- lingxingapi/tools/param.py +73 -0
- lingxingapi/tools/route.py +8 -0
- lingxingapi/tools/schema.py +169 -0
- lingxingapi/utils.py +456 -0
- lingxingapi/warehourse/__init__.py +0 -0
- lingxingapi/warehourse/api.py +1778 -0
- lingxingapi/warehourse/param.py +506 -0
- lingxingapi/warehourse/route.py +28 -0
- lingxingapi/warehourse/schema.py +926 -0
- lingxingapi-1.1.4.dist-info/METADATA +73 -0
- lingxingapi-1.1.4.dist-info/RECORD +65 -0
- lingxingapi-1.1.4.dist-info/WHEEL +5 -0
- lingxingapi-1.1.4.dist-info/licenses/LICENSE +22 -0
- lingxingapi-1.1.4.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
from pydantic import Field, field_validator
|
|
3
|
+
from lingxingapi import utils
|
|
4
|
+
from lingxingapi.base.param import Parameter
|
|
5
|
+
from lingxingapi.fields import NonEmptyStr, CountryCode, CurrencyCode, NonNegativeInt
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
# 基础数据 -----------------------------------------------------------------------------------------------------------------------
|
|
9
|
+
# . Country Code
|
|
10
|
+
class CountryCode(Parameter):
|
|
11
|
+
# 国家代码, 如: "US", "CA"
|
|
12
|
+
country_code: CountryCode
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
# . Rename Sellers
|
|
16
|
+
class RenameSeller(Parameter):
|
|
17
|
+
# 领星店铺ID (Seller.sid)
|
|
18
|
+
sid: NonNegativeInt
|
|
19
|
+
# 新的店铺名称
|
|
20
|
+
name: NonEmptyStr
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class RenameSellers(Parameter):
|
|
24
|
+
# 修改店铺名称参数列表
|
|
25
|
+
renames: list = Field(alias="sid_name_list")
|
|
26
|
+
|
|
27
|
+
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
28
|
+
@field_validator("renames", mode="before")
|
|
29
|
+
@classmethod
|
|
30
|
+
def _validate_renames(cls, v) -> list[dict]:
|
|
31
|
+
if not isinstance(v, (list, tuple)):
|
|
32
|
+
res = [RenameSeller.model_validate_params(v)]
|
|
33
|
+
else:
|
|
34
|
+
res = [RenameSeller.model_validate_params(i) for i in v]
|
|
35
|
+
if len(res) == 0:
|
|
36
|
+
raise ValueError("必须提供至少一个 rename 来修改店铺名称")
|
|
37
|
+
return res
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
# . Excahnge Rate Date
|
|
41
|
+
class ExchangeRateDate(Parameter):
|
|
42
|
+
# 日期, 格式为 "YYYY-MM"
|
|
43
|
+
date: str
|
|
44
|
+
|
|
45
|
+
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
46
|
+
@field_validator("date", mode="before")
|
|
47
|
+
@classmethod
|
|
48
|
+
def _validate_date(cls, v) -> str:
|
|
49
|
+
dt = utils.validate_datetime(v, True, "汇率日期 date")
|
|
50
|
+
return "%04d-%02d" % (dt.year, dt.month)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
# . Edit Exchange Rate
|
|
54
|
+
class EditExchangeRate(Parameter):
|
|
55
|
+
# 汇率日期, 格式为 "YYYY-MM"
|
|
56
|
+
date: str
|
|
57
|
+
# 货币代码, 如 "CNY", "USD", "EUR"
|
|
58
|
+
currency_code: CurrencyCode = Field(alias="code")
|
|
59
|
+
# 用户自定义汇率 (对比人民币, 如: 7.2008000000), 最多支持10位小数
|
|
60
|
+
user_rate: str = Field(alias="my_rate")
|
|
61
|
+
|
|
62
|
+
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
63
|
+
@field_validator("date", mode="before")
|
|
64
|
+
@classmethod
|
|
65
|
+
def _validate_date(cls, v) -> str:
|
|
66
|
+
dt = utils.validate_datetime(v, False, "汇率日期 date")
|
|
67
|
+
return "%04d-%02d" % (dt.year, dt.month)
|
|
68
|
+
|
|
69
|
+
@field_validator("user_rate", mode="before")
|
|
70
|
+
@classmethod
|
|
71
|
+
def _validate_user_rate(cls, v) -> str:
|
|
72
|
+
return str(utils.validate_exchange_rate(v, "用户自定义汇率 user_rate"))
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
# fmt: off
|
|
4
|
+
# 基础数据 -----------------------------------------------------------------------------------------------------------------------
|
|
5
|
+
# https://apidoc.lingxing.com/#/docs/BasicData/AllMarketplace
|
|
6
|
+
MARKETPLACES: str = "/erp/sc/data/seller/allMarketplace"
|
|
7
|
+
# https://apidoc.lingxing.com/#/docs/BasicData/WorldStateLists
|
|
8
|
+
STATES: str = "/erp/sc/data/worldState/lists"
|
|
9
|
+
# https://apidoc.lingxing.com/#/docs/BasicData/SellerLists
|
|
10
|
+
SELLERS: str = "/erp/sc/data/seller/lists"
|
|
11
|
+
# https://apidoc.lingxing.com/#/docs/BasicData/ConceptSellerLists
|
|
12
|
+
CONCEPT_SELLERS: str = "/erp/sc/data/seller/conceptLists"
|
|
13
|
+
# https://apidoc.lingxing.com/#/docs/BasicData/SellerBatchRename
|
|
14
|
+
RENAME_SELLERS: str = "/erp/sc/data/seller/batchEditSellerName"
|
|
15
|
+
# https://apidoc.lingxing.com/#/docs/BasicData/AccoutLists
|
|
16
|
+
ACCOUNTS: str = "/erp/sc/data/account/lists"
|
|
17
|
+
# https://apidoc.lingxing.com/#/docs/BasicData/Currency
|
|
18
|
+
EXCHANGE_RATES: str = "/erp/sc/routing/finance/currency/currencyMonth"
|
|
19
|
+
# https://apidoc.lingxing.com/#/docs/BasicData/ExchangeRateUpdate
|
|
20
|
+
EDIT_EXCHANGE_RATE: str = "/basicOpen/settings/exchangeRate/update"
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
from pydantic import BaseModel, Field, field_validator
|
|
3
|
+
from lingxingapi.fields import IntOrNone2Zero
|
|
4
|
+
from lingxingapi.base.schema import ResponseV1, ResponseResult
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
# 基础数据 -----------------------------------------------------------------------------------------------------------------------
|
|
8
|
+
# . Marketplaces
|
|
9
|
+
class Marketplace(BaseModel):
|
|
10
|
+
"""亚马逊站点."""
|
|
11
|
+
|
|
12
|
+
# 领星站点ID [唯一标识]
|
|
13
|
+
mid: int
|
|
14
|
+
# 站点区域
|
|
15
|
+
region: str
|
|
16
|
+
# 站点亚马逊仓库所属区域 [原字段 'aws_region']
|
|
17
|
+
region_aws: str = Field(validation_alias="aws_region")
|
|
18
|
+
# 站点国家 (中文)
|
|
19
|
+
country: str
|
|
20
|
+
# 站点国家代码 [原字段 'code']
|
|
21
|
+
country_code: str = Field(validation_alias="code")
|
|
22
|
+
# 亚马逊市场ID
|
|
23
|
+
marketplace_id: str
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class Marketplaces(ResponseV1):
|
|
27
|
+
"""亚马逊站点查询结果."""
|
|
28
|
+
|
|
29
|
+
data: list[Marketplace]
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
# . States
|
|
33
|
+
class State(BaseModel):
|
|
34
|
+
"""国家的省/州."""
|
|
35
|
+
|
|
36
|
+
# 国家代码
|
|
37
|
+
country_code: str
|
|
38
|
+
# 省/州名称 [原字段 'state_or_province_name']
|
|
39
|
+
state: str = Field(validation_alias="state_or_province_name")
|
|
40
|
+
# 省/州代码 [原字段 'code']
|
|
41
|
+
state_code: str = Field(validation_alias="code")
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class States(ResponseV1):
|
|
45
|
+
"""国家的省/州查询结果."""
|
|
46
|
+
|
|
47
|
+
data: list[State]
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
# . Sellers
|
|
51
|
+
class Seller(BaseModel):
|
|
52
|
+
"""领星店铺."""
|
|
53
|
+
|
|
54
|
+
# 领星站点ID (Marketplace.mid)
|
|
55
|
+
mid: int
|
|
56
|
+
# 领星店铺ID [唯一标识]
|
|
57
|
+
sid: int
|
|
58
|
+
# 亚马逊卖家ID
|
|
59
|
+
seller_id: str
|
|
60
|
+
# 领星店铺名称 (含国家信息) [原字段 'name']
|
|
61
|
+
seller_name: str = Field(validation_alias="name")
|
|
62
|
+
# 领星店铺帐号ID [原字段 'seller_account_id']
|
|
63
|
+
account_id: int = Field(validation_alias="seller_account_id")
|
|
64
|
+
# 领星店铺帐号名称
|
|
65
|
+
account_name: str
|
|
66
|
+
# 亚马逊市场ID (Marketplace.marketplace_id)
|
|
67
|
+
marketplace_id: str
|
|
68
|
+
# 店铺区域
|
|
69
|
+
region: str
|
|
70
|
+
# 店铺国家 (中文)
|
|
71
|
+
country: str
|
|
72
|
+
# 店铺状态 (0: 停止同步, 1: 正常, 2: 授权异常, 3: 欠费停服)
|
|
73
|
+
status: int
|
|
74
|
+
# 店铺是否授权广告 (0: 否, 1: 是) [原字段 'has_ads_setting']
|
|
75
|
+
ads_authorized: int = Field(validation_alias="has_ads_setting")
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
class Sellers(ResponseV1):
|
|
79
|
+
"""领星店铺查询结果."""
|
|
80
|
+
|
|
81
|
+
data: list[Seller]
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
# . Concept Sellers
|
|
85
|
+
class ConceptSeller(BaseModel):
|
|
86
|
+
"""领星概念店铺."""
|
|
87
|
+
|
|
88
|
+
# 领星概念站点ID [原字段 'mid']
|
|
89
|
+
cmid: int = Field(validation_alias="mid")
|
|
90
|
+
# 领星概念店铺ID [唯一标识, 原字段 'id']
|
|
91
|
+
csid: int = Field(validation_alias="id")
|
|
92
|
+
# 亚马逊卖家ID
|
|
93
|
+
seller_id: str
|
|
94
|
+
# 领星概念店铺名称 (含区域信息) [原字段 'name']
|
|
95
|
+
seller_name: str = Field(validation_alias="name")
|
|
96
|
+
# 领星概念店铺账号ID [原字段 'seller_account_id']
|
|
97
|
+
account_id: int = Field(validation_alias="seller_account_id")
|
|
98
|
+
# 领星概念店铺帐号名称 [原字段 'seller_account_name']
|
|
99
|
+
account_name: str = Field(validation_alias="seller_account_name")
|
|
100
|
+
# 概念店铺区域
|
|
101
|
+
region: str
|
|
102
|
+
# 概念店铺国家, 如: "北美共享", "欧洲共享"
|
|
103
|
+
country: str
|
|
104
|
+
# 概念店铺状态 (1: 启用, 2: 停用)
|
|
105
|
+
status: int
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
class ConceptSellers(ResponseV1):
|
|
109
|
+
"""领星概念店铺查询结果."""
|
|
110
|
+
|
|
111
|
+
data: list[ConceptSeller]
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
# . Rename Sellers
|
|
115
|
+
class RenameSellersFailureDetail(BaseModel):
|
|
116
|
+
"""批量修改店铺名称失败的详情."""
|
|
117
|
+
|
|
118
|
+
# 领星店铺ID (Seller.sid)
|
|
119
|
+
sid: int
|
|
120
|
+
# 新店铺名称
|
|
121
|
+
name: str
|
|
122
|
+
# 失败信息 [原字段 'error']
|
|
123
|
+
message: str = Field(validation_alias="error")
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
class RenameSellers(BaseModel):
|
|
127
|
+
"""批量修改店铺名称的结果."""
|
|
128
|
+
|
|
129
|
+
success: IntOrNone2Zero = Field(validation_alias="success_num")
|
|
130
|
+
# 修改失败数量 [原字段 'failure_num']
|
|
131
|
+
failure: IntOrNone2Zero = Field(validation_alias="failure_num")
|
|
132
|
+
# 修改失败详情
|
|
133
|
+
failure_detail: list[RenameSellersFailureDetail]
|
|
134
|
+
|
|
135
|
+
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
136
|
+
@field_validator("failure_detail", mode="before")
|
|
137
|
+
def _validate_failure_detail(cls, v):
|
|
138
|
+
if v is None:
|
|
139
|
+
return []
|
|
140
|
+
return [RenameSellersFailureDetail.model_validate(i) for i in v]
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
class RenameSellersResult(ResponseResult):
|
|
144
|
+
"""批量修改店铺名称的响应结果."""
|
|
145
|
+
|
|
146
|
+
data: RenameSellers
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
# . Accounts
|
|
150
|
+
class Account(BaseModel):
|
|
151
|
+
"""领星账号."""
|
|
152
|
+
|
|
153
|
+
# 领星账号所从属的ID (如主帐号ID) [原字段 'zid']
|
|
154
|
+
parent_id: int = Field(validation_alias="zid")
|
|
155
|
+
# 领星帐号ID [唯一标识] [原字段 'uid']
|
|
156
|
+
user_id: int = Field(validation_alias="uid")
|
|
157
|
+
# 是否为主账号 (0: 否, 1: 是)
|
|
158
|
+
is_master: int
|
|
159
|
+
# 帐号角色
|
|
160
|
+
role: str
|
|
161
|
+
# 领星帐号显示的姓名 [原字段 'realname']
|
|
162
|
+
display_name: str = Field(validation_alias="realname")
|
|
163
|
+
# 领星帐号登陆用户名
|
|
164
|
+
username: str
|
|
165
|
+
# 领星帐号电子邮箱
|
|
166
|
+
email: str
|
|
167
|
+
# 领星帐号电话号码 [原字段 'mobile']
|
|
168
|
+
phone: str = Field(validation_alias="mobile")
|
|
169
|
+
# 领星帐号创建时间 (北京时间)
|
|
170
|
+
create_time: str
|
|
171
|
+
# 领星帐号最后登录时间 (北京时间)
|
|
172
|
+
last_login_time: str
|
|
173
|
+
# 领星帐号最后登录IP
|
|
174
|
+
last_login_ip: str
|
|
175
|
+
# 领星帐号登录次数 [原字段 'login_num']
|
|
176
|
+
login_count: int = Field(validation_alias="login_num")
|
|
177
|
+
# 领星帐号状态 (0: 禁用, 1: 正常)
|
|
178
|
+
status: int
|
|
179
|
+
# 关联的领星店铺名称, 逗号分隔 [原字段 'seller']
|
|
180
|
+
sellers: str = Field(validation_alias="seller")
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
class Accounts(ResponseV1):
|
|
184
|
+
"""领星账号查询结果."""
|
|
185
|
+
|
|
186
|
+
data: list[Account]
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
# . Exchange Rates
|
|
190
|
+
class ExchangeRate(BaseModel):
|
|
191
|
+
"""货币汇率."""
|
|
192
|
+
|
|
193
|
+
# 汇率日期 (格式: YYYY-MM-DD)
|
|
194
|
+
date: str
|
|
195
|
+
# 货币名称 (中文) [原字段 'name']
|
|
196
|
+
currency: str = Field(validation_alias="name")
|
|
197
|
+
# 货币代码 [原字段 'code']
|
|
198
|
+
currency_code: str = Field(validation_alias="code")
|
|
199
|
+
# 货币符号 [原字段 'icon']
|
|
200
|
+
currency_icon: str = Field(validation_alias="icon")
|
|
201
|
+
# 中国银行官方汇率 (对比人民币, 如: 7.1541) [原字段 'rate_org']
|
|
202
|
+
boc_rate: float = Field(validation_alias="rate_org")
|
|
203
|
+
# 用户汇率 (对比人民币, 如: 7.2008000000) [原字段 'my_rate']
|
|
204
|
+
user_rate: float = Field(validation_alias="my_rate")
|
|
205
|
+
# 用户汇率修改时间 (北京时间)
|
|
206
|
+
update_time: str
|
|
207
|
+
|
|
208
|
+
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
209
|
+
@field_validator("date", mode="after")
|
|
210
|
+
@classmethod
|
|
211
|
+
def _validate_date(cls, v: str) -> str:
|
|
212
|
+
return v + "-01"
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
class ExchangeRates(ResponseV1):
|
|
216
|
+
"""货币汇率查询结果."""
|
|
217
|
+
|
|
218
|
+
data: list[ExchangeRate]
|
lingxingapi/errors.py
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
# Base errors -----------------------------------------------------------------------------------------------------------
|
|
6
|
+
class BaseApiError(Exception):
|
|
7
|
+
"""The base class for all API errors."""
|
|
8
|
+
|
|
9
|
+
def __init__(
|
|
10
|
+
self,
|
|
11
|
+
msg: object,
|
|
12
|
+
url: str | None = None,
|
|
13
|
+
data: Any | None = None,
|
|
14
|
+
err_code: int | None = None,
|
|
15
|
+
):
|
|
16
|
+
if not isinstance(msg, str):
|
|
17
|
+
msg = str(msg)
|
|
18
|
+
if url is not None:
|
|
19
|
+
msg += "\n请求路径: %s" % url
|
|
20
|
+
if data is not None:
|
|
21
|
+
if isinstance(data, dict):
|
|
22
|
+
data = {k: v for k, v in data.items() if v is not None}
|
|
23
|
+
msg += "\n数据信息: %r" % data
|
|
24
|
+
if err_code is not None:
|
|
25
|
+
msg += "\n错误代码: %r" % err_code
|
|
26
|
+
super().__init__(msg)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
# API Settings errors ---------------------------------------------------------------------------------------------------
|
|
30
|
+
class ApiSettingsError(BaseApiError):
|
|
31
|
+
"""Raised when there is an error with the API settings."""
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
# Request errors --------------------------------------------------------------------------------------------------------
|
|
35
|
+
class RequestError(BaseApiError):
|
|
36
|
+
"""Raised when a request to the API fails."""
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
# Internet Error
|
|
40
|
+
class InternetConnectionError(RequestError):
|
|
41
|
+
"""Raised when there is an internet connectivity issue."""
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
# Timeout
|
|
45
|
+
class ApiTimeoutError(RequestError, TimeoutError):
|
|
46
|
+
"""Raise when the API request times out."""
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
# Server
|
|
50
|
+
class ServerError(RequestError):
|
|
51
|
+
"""Raised when the API server deos not return proper response."""
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class InternalServerError(ServerError):
|
|
55
|
+
"""Raised when the API server returns a 500 error."""
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
# Authrization
|
|
59
|
+
class AuthorizationError(RequestError):
|
|
60
|
+
"""Raised when the API server returns a 4xx error related to authorization."""
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class UnauthorizedApiError(AuthorizationError):
|
|
64
|
+
"""Raised when the API is not authorized for the app ID or secret."""
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class UnauthorizedRequestIpError(AuthorizationError):
|
|
68
|
+
"""Raised when the IP address is not whitelisted for API access."""
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
# Token
|
|
72
|
+
class TokenError(RequestError):
|
|
73
|
+
"""Raised when the access token has expired."""
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
class TokenExpiredError(TokenError):
|
|
77
|
+
"""Raised when the access token has expired."""
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
class AccessTokenExpiredError(TokenExpiredError):
|
|
81
|
+
"""Raised when the access token has expired."""
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class RefreshTokenExpiredError(TokenExpiredError):
|
|
85
|
+
"""Raised when the refresh token has expired."""
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
class InvalidTokenError(TokenError):
|
|
89
|
+
"""Raised when the token is invalid or malformed."""
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
class InvalidAccessTokenError(InvalidTokenError):
|
|
93
|
+
"""Raised when the access token is invalid."""
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
class InvalidRefreshTokenError(InvalidTokenError):
|
|
97
|
+
"""Raised when the refresh token is invalid."""
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
# App ID or Secret
|
|
101
|
+
class AppIdOrSecretError(RequestError):
|
|
102
|
+
"""Raised when the app ID or secret is invalid or missing."""
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
# Signature errors
|
|
106
|
+
class SignatureError(RequestError):
|
|
107
|
+
"""Raised when the signature is invalid or missing."""
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
class SignatureExpiredError(SignatureError):
|
|
111
|
+
"""Raised when the signature has expired."""
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
class InvalidSignatureError(SignatureError):
|
|
115
|
+
"""Raised when the signature is invalid."""
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
# Parameter
|
|
119
|
+
class ParametersError(RequestError):
|
|
120
|
+
"""Raised when the request parameters are invalid or missing."""
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
class InvalidApiUrlError(ParametersError):
|
|
124
|
+
"""Raised when the API server returns an error response."""
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
class InvalidParametersError(ParametersError):
|
|
128
|
+
"""Raised when a required parameter is missing."""
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
# API Limit
|
|
132
|
+
class ApiLimitError(RequestError):
|
|
133
|
+
"""Raised when the API limit has been reached."""
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
class TooManyRequestsError(ApiLimitError):
|
|
137
|
+
"""Raised when too many requests have been made to the API."""
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
# Unknown
|
|
141
|
+
class UnknownRequestError(RequestError):
|
|
142
|
+
"""Raised when an unknown error occurs during the request."""
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
# Response errors -------------------------------------------------------------------------------------------------------
|
|
146
|
+
class ReponseError(BaseApiError):
|
|
147
|
+
"""Raised when the data returned by the API is invalid or malformed."""
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
# Response data
|
|
151
|
+
class ResponseDataError(ReponseError):
|
|
152
|
+
"""Raised when the response data is not in the expected format."""
|
|
File without changes
|