uapi-sdk-python 0.1.1__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.
uapi/errors.py ADDED
@@ -0,0 +1,153 @@
1
+ from __future__ import annotations
2
+ from typing import Any, Dict, Optional
3
+ import httpx
4
+
5
+ class UapiError(Exception):
6
+ code: str
7
+ status: int
8
+ message: str
9
+ details: Optional[Dict[str, Any]]
10
+
11
+ def __init__(self, code: str, status: int, message: str, details: Optional[Dict[str, Any]] = None):
12
+ super().__init__(f"[{status}] {code}: {message}")
13
+ self.code = code
14
+ self.status = status
15
+ self.message = message
16
+ self.details = details
17
+
18
+
19
+ class ApiErrorError(UapiError):
20
+ """上游/内部错误 (API_ERROR)"""
21
+ DEFAULT_STATUS = 502
22
+
23
+ class AvatarNotFoundError(UapiError):
24
+ """头像未找到 (AVATAR_NOT_FOUND)"""
25
+ DEFAULT_STATUS = 404
26
+
27
+ class ConversionFailedError(UapiError):
28
+ """转换失败 (CONVERSION_FAILED)"""
29
+ DEFAULT_STATUS = 400
30
+
31
+ class FileOpenErrorError(UapiError):
32
+ """文件打开错误 (FILE_OPEN_ERROR)"""
33
+ DEFAULT_STATUS = 500
34
+
35
+ class FileRequiredError(UapiError):
36
+ """文件必需 (FILE_REQUIRED)"""
37
+ DEFAULT_STATUS = 400
38
+
39
+ class InternalServerErrorError(UapiError):
40
+ """服务器内部错误 (INTERNAL_SERVER_ERROR)"""
41
+ DEFAULT_STATUS = 500
42
+
43
+ class InvalidParameterError(UapiError):
44
+ """请求参数错误 (INVALID_PARAMETER)"""
45
+ DEFAULT_STATUS = 400
46
+
47
+ class InvalidParamsError(UapiError):
48
+ """无效参数 (INVALID_PARAMS)"""
49
+ DEFAULT_STATUS = 400
50
+
51
+ class NotFoundError(UapiError):
52
+ """资源不存在 (NOT_FOUND)"""
53
+ DEFAULT_STATUS = 404
54
+
55
+ class NoMatchError(UapiError):
56
+ """无匹配 (NO_MATCH)"""
57
+ DEFAULT_STATUS = 404
58
+
59
+ class NoTrackingDataError(UapiError):
60
+ """无物流数据 (NO_TRACKING_DATA)"""
61
+ DEFAULT_STATUS = 404
62
+
63
+ class PhoneInfoFailedError(UapiError):
64
+ """手机号信息查询失败 (PHONE_INFO_FAILED)"""
65
+ DEFAULT_STATUS = 500
66
+
67
+ class RecognitionFailedError(UapiError):
68
+ """识别失败 (RECOGNITION_FAILED)"""
69
+ DEFAULT_STATUS = 404
70
+
71
+ class RequestEntityTooLargeError(UapiError):
72
+ """错误 (REQUEST_ENTITY_TOO_LARGE)"""
73
+ DEFAULT_STATUS = 413
74
+
75
+ class ServiceBusyError(UapiError):
76
+ """请求过于频繁 (SERVICE_BUSY)"""
77
+ DEFAULT_STATUS = 429
78
+
79
+ class TimezoneNotFoundError(UapiError):
80
+ """时区未找到 (TIMEZONE_NOT_FOUND)"""
81
+ DEFAULT_STATUS = 404
82
+
83
+ class UnauthorizedError(UapiError):
84
+ """请求未授权 (UNAUTHORIZED)"""
85
+ DEFAULT_STATUS = 401
86
+
87
+ class UnsupportedCarrierError(UapiError):
88
+ """不支持的承运商 (UNSUPPORTED_CARRIER)"""
89
+ DEFAULT_STATUS = 404
90
+
91
+ class UnsupportedFormatError(UapiError):
92
+ """格式不支持 (UNSUPPORTED_FORMAT)"""
93
+ DEFAULT_STATUS = 400
94
+
95
+
96
+ def map_error(r: httpx.Response) -> UapiError:
97
+ code = None
98
+ msg = r.text
99
+ try:
100
+ data = r.json()
101
+ code = data.get("code") or data.get("error") or data.get("errCode") or "API_ERROR"
102
+ msg = data.get("message") or data.get("errMsg") or msg
103
+ details = data.get("details")
104
+ except Exception:
105
+ details = None
106
+ status = r.status_code
107
+ cls = _class_by_code(code, status)
108
+ return cls(code, status, msg, details)
109
+
110
+ def _class_by_code(code: str, status: int):
111
+ c = (code or "").upper()
112
+ mapping = {
113
+
114
+ "API_ERROR": ApiErrorError,
115
+
116
+ "AVATAR_NOT_FOUND": AvatarNotFoundError,
117
+
118
+ "CONVERSION_FAILED": ConversionFailedError,
119
+
120
+ "FILE_OPEN_ERROR": FileOpenErrorError,
121
+
122
+ "FILE_REQUIRED": FileRequiredError,
123
+
124
+ "INTERNAL_SERVER_ERROR": InternalServerErrorError,
125
+
126
+ "INVALID_PARAMETER": InvalidParameterError,
127
+
128
+ "INVALID_PARAMS": InvalidParamsError,
129
+
130
+ "NOT_FOUND": NotFoundError,
131
+
132
+ "NO_MATCH": NoMatchError,
133
+
134
+ "NO_TRACKING_DATA": NoTrackingDataError,
135
+
136
+ "PHONE_INFO_FAILED": PhoneInfoFailedError,
137
+
138
+ "RECOGNITION_FAILED": RecognitionFailedError,
139
+
140
+ "REQUEST_ENTITY_TOO_LARGE": RequestEntityTooLargeError,
141
+
142
+ "SERVICE_BUSY": ServiceBusyError,
143
+
144
+ "TIMEZONE_NOT_FOUND": TimezoneNotFoundError,
145
+
146
+ "UNAUTHORIZED": UnauthorizedError,
147
+
148
+ "UNSUPPORTED_CARRIER": UnsupportedCarrierError,
149
+
150
+ "UNSUPPORTED_FORMAT": UnsupportedFormatError,
151
+
152
+ }
153
+ return mapping.get(c) or ( {400: InvalidParameterError, 401: UnauthorizedError, 404: NotFoundError, 429: ServiceBusyError, 500: InternalServerError}.get(status) or UapiError )
@@ -0,0 +1,82 @@
1
+ Metadata-Version: 2.4
2
+ Name: uapi-sdk-python
3
+ Version: 0.1.1
4
+ Summary: Idiomatic UAPI SDK for Python
5
+ Author-email: UAPI <dev@uapis.cn>
6
+ Requires-Python: >=3.9
7
+ Description-Content-Type: text/markdown
8
+ Requires-Dist: httpx>=0.24.1
9
+ Provides-Extra: dev
10
+ Requires-Dist: pytest; extra == "dev"
11
+ Requires-Dist: mypy; extra == "dev"
12
+ Requires-Dist: black; extra == "dev"
13
+ Requires-Dist: isort; extra == "dev"
14
+
15
+ # uapi-sdk-python
16
+
17
+ ![Banner](https://raw.githubusercontent.com/AxT-Team/uapi-sdk-python/main/banner.png)
18
+
19
+ [![Python](https://img.shields.io/badge/Python-3.9+-3776AB?style=flat-square&logo=python&logoColor=white)](https://www.python.org/)
20
+ [![Docs](https://img.shields.io/badge/Docs-uapis.cn-2EAE5D?style=flat-square)](https://uapis.cn/)
21
+ [![PyPI](https://img.shields.io/pypi/v/uapi-sdk-python?style=flat-square&logo=pypi&logoColor=white)](https://pypi.org/project/uapi-sdk-python/)
22
+
23
+ > [!NOTE]
24
+ > 所有接口的 Python 示例都可以在 [UApi](https://uapis.cn/docs/introduction) 的接口文档页面,向下滚动至 **快速启动** 区块后直接复制。
25
+
26
+ ## 快速开始
27
+
28
+ ```bash
29
+ pip install uapi-sdk-python
30
+ ```
31
+
32
+ ```python
33
+ from uapi import UapiClient
34
+
35
+ client = UapiClient("https://uapis.cn/api/v1")
36
+ result = client.social.get_social_qq_userinfo(qq="10001")
37
+ print(result)
38
+ ```
39
+
40
+ ## 特性
41
+
42
+ 现在你不再需要反反复复的查阅文档了。
43
+
44
+ 只需在 IDE 中键入 `client.`,所有核心模块——如 `social`、`game`、`image`——即刻同步展现。进一步输入即可直接定位到 `get_social_qq_userinfo` 这样的具体方法,其名称与文档的 `operationId` 严格保持一致,确保了开发过程的直观与高效。
45
+
46
+ 所有方法签名只接受真实且必需的参数。当你在构建请求时,IDE 会即时提示 `qq`、`username` 等键名,这彻底杜绝了在 `dict`/关键字参数中因拼写错误而导致的运行时错误。
47
+
48
+ 针对 401、404、429 等标准 HTTP 响应,SDK 已将其统一映射为具名的异常类型。这些异常均附带 `code`、`status`、`details` 等关键上下文信息,确保你在日志中能第一时间准确、快速地诊断问题。
49
+
50
+ `UapiClient(base_url, token, timeout)` 默认使用 `httpx` 并自动追加 `Authorization` 头;需要切换环境或调整超时时,只要改一次构造参数即可。
51
+
52
+ 如果你需要查看字段细节或内部逻辑,仓库中的 `./internal` 目录同步保留了由 `openapi-generator` 生成的完整结构体,随时可供参考。
53
+
54
+ ## 错误模型概览
55
+
56
+ | HTTP 状态码 | SDK 错误类型 | 附加信息 |
57
+ |-------------|----------------------------------------------|------------------------------------------------------------------------------------|
58
+ | 401/403 | `UnauthorizedError` | `code`、`status` |
59
+ | 404 | `NotFoundError` / `NoMatchError` | `code`、`status` |
60
+ | 400 | `InvalidParameterError` / `InvalidParamsError` | `code`、`status`、`details` |
61
+ | 429 | `ServiceBusyError` | `code`、`status`、`retry_after_seconds`(用于决定何时重试) |
62
+ | 5xx | `InternalServerErrorError` / `ApiErrorError` | `code`、`status`、`details` |
63
+ | 其他 4xx | `UapiError` | `code`、`status`、`details` |
64
+
65
+ ## 其他 SDK
66
+
67
+ | 语言 | 仓库地址 |
68
+ |-------------|--------------------------------------------------------------|
69
+ | Go | https://github.com/AxT-Team/uapi-go-sdk |
70
+ | Python(当前) | https://github.com/AxT-Team/uapi-python-sdk |
71
+ | TypeScript| https://github.com/AxT-Team/uapi-typescript-sdk |
72
+ | Browser (TypeScript/JavaScript)| https://github.com/AxT-Team/uapi-browser-sdk |
73
+ | Java | https://github.com/AxT-Team/uapi-java-sdk |
74
+ | PHP | https://github.com/AxT-Team/uapi-php-sdk |
75
+ | C# | https://github.com/AxT-Team/uapi-csharp-sdk |
76
+ | C++ | https://github.com/AxT-Team/uapi-cpp-sdk |
77
+ | Rust | https://github.com/AxT-Team/uapi-rust-sdk |
78
+
79
+ ## 文档
80
+
81
+ 访问 [UApi文档首页](https://uapis.cn/docs/introduction) 并选择任意接口,向下滚动到 **快速启动** 区块即可看到最新的 Python 示例代码。
82
+
@@ -0,0 +1,7 @@
1
+ uapi/__init__.py,sha256=3dluUZfyWYYGTWzDBFip0d5YZej6waZiq2ayvJ0RI9o,86
2
+ uapi/client.py,sha256=yaOdgDNUvUnw3bXQPTJyO6paT3KnuPzkv-77Nk9eUPU,88187
3
+ uapi/errors.py,sha256=npeo8-u6-j0IZ4-H50rBuCWAB4kLG6pqpq0rlLX2ANw,4390
4
+ uapi_sdk_python-0.1.1.dist-info/METADATA,sha256=sjyeezSTjL8ybi4-S0605wpiGswlFynsaOthpHYanEY,4801
5
+ uapi_sdk_python-0.1.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
6
+ uapi_sdk_python-0.1.1.dist-info/top_level.txt,sha256=0TrPOLLMqin88fxqxR9T5piS4dSoyju9HFiPu1oPEUU,5
7
+ uapi_sdk_python-0.1.1.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.9.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1 @@
1
+ uapi