tianjian-api 0.1.0__tar.gz
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.
- tianjian_api-0.1.0/PKG-INFO +70 -0
- tianjian_api-0.1.0/README.md +61 -0
- tianjian_api-0.1.0/pyproject.toml +15 -0
- tianjian_api-0.1.0/setup.cfg +4 -0
- tianjian_api-0.1.0/src/tianjian_api/__init__.py +17 -0
- tianjian_api-0.1.0/src/tianjian_api/client.py +109 -0
- tianjian_api-0.1.0/src/tianjian_api/exceptions.py +18 -0
- tianjian_api-0.1.0/src/tianjian_api.egg-info/PKG-INFO +70 -0
- tianjian_api-0.1.0/src/tianjian_api.egg-info/SOURCES.txt +10 -0
- tianjian_api-0.1.0/src/tianjian_api.egg-info/dependency_links.txt +1 -0
- tianjian_api-0.1.0/src/tianjian_api.egg-info/requires.txt +1 -0
- tianjian_api-0.1.0/src/tianjian_api.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: tianjian-api
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python SDK for Tianjian API platform
|
|
5
|
+
Author: Tianjian API
|
|
6
|
+
Requires-Python: >=3.8
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
Requires-Dist: requests>=2.28
|
|
9
|
+
|
|
10
|
+
# Tianjian API Python SDK
|
|
11
|
+
|
|
12
|
+
简洁同步版 SDK,适合服务端脚本、业务系统和定时任务接入。它是独立 Python 第三方库,不改变网站现有业务接口。
|
|
13
|
+
|
|
14
|
+
## 安装
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pip install -e .
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## 快速开始
|
|
21
|
+
|
|
22
|
+
```python
|
|
23
|
+
from tianjian_api import TianjianClient
|
|
24
|
+
|
|
25
|
+
client = TianjianClient(
|
|
26
|
+
api_key="你的 API KEY",
|
|
27
|
+
base_url="https://ocr.ikunocr.cn",
|
|
28
|
+
type="api",
|
|
29
|
+
proxy="http://127.0.0.1:7890", # SDK 请求平台时使用的网络代理,可不填
|
|
30
|
+
timeout=10,
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
res = client.call("16hangzhoudxdx", c="xxx", api_proxy="http://user:pass@ip:port/")
|
|
34
|
+
print(res)
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## 常用能力
|
|
38
|
+
|
|
39
|
+
- `client.call(path, **params)` 调用任意产品接口,自动携带 `key`。
|
|
40
|
+
- `client.get(path, **params)` 使用 GET 调用产品接口。
|
|
41
|
+
- `client.post(path, **params)` 使用 POST 调用产品接口。
|
|
42
|
+
- `client.balance()` 查询余额,需要平台提供 API KEY 查询接口后配置 `balance_path`。
|
|
43
|
+
- `client.packages()` 查询当前用户套餐,需要平台提供 API KEY 查询接口后配置 `packages_path`。
|
|
44
|
+
|
|
45
|
+
注意:`proxy` 是 SDK 自己访问平台时使用的网络代理;`api_proxy` 是传给平台产品接口的业务代理参数,未传时不会发送该字段。
|
|
46
|
+
|
|
47
|
+
## 查询余额和套餐
|
|
48
|
+
|
|
49
|
+
如果后续平台开放查询接口,例如:
|
|
50
|
+
|
|
51
|
+
```text
|
|
52
|
+
GET /api/account/balance/get?key=你的密钥
|
|
53
|
+
GET /api/account/packages/get?key=你的密钥
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
SDK 可以这样接入:
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
client = TianjianClient(
|
|
60
|
+
api_key="你的 API KEY",
|
|
61
|
+
base_url="https://ocr.ikunocr.cn",
|
|
62
|
+
balance_path="account/balance",
|
|
63
|
+
packages_path="account/packages",
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
print(client.balance())
|
|
67
|
+
print(client.packages())
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
这样第三方库保持独立,网站什么时候开放查询能力,SDK 就什么时候启用。
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Tianjian API Python SDK
|
|
2
|
+
|
|
3
|
+
简洁同步版 SDK,适合服务端脚本、业务系统和定时任务接入。它是独立 Python 第三方库,不改变网站现有业务接口。
|
|
4
|
+
|
|
5
|
+
## 安装
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install -e .
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## 快速开始
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
from tianjian_api import TianjianClient
|
|
15
|
+
|
|
16
|
+
client = TianjianClient(
|
|
17
|
+
api_key="你的 API KEY",
|
|
18
|
+
base_url="https://ocr.ikunocr.cn",
|
|
19
|
+
type="api",
|
|
20
|
+
proxy="http://127.0.0.1:7890", # SDK 请求平台时使用的网络代理,可不填
|
|
21
|
+
timeout=10,
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
res = client.call("16hangzhoudxdx", c="xxx", api_proxy="http://user:pass@ip:port/")
|
|
25
|
+
print(res)
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## 常用能力
|
|
29
|
+
|
|
30
|
+
- `client.call(path, **params)` 调用任意产品接口,自动携带 `key`。
|
|
31
|
+
- `client.get(path, **params)` 使用 GET 调用产品接口。
|
|
32
|
+
- `client.post(path, **params)` 使用 POST 调用产品接口。
|
|
33
|
+
- `client.balance()` 查询余额,需要平台提供 API KEY 查询接口后配置 `balance_path`。
|
|
34
|
+
- `client.packages()` 查询当前用户套餐,需要平台提供 API KEY 查询接口后配置 `packages_path`。
|
|
35
|
+
|
|
36
|
+
注意:`proxy` 是 SDK 自己访问平台时使用的网络代理;`api_proxy` 是传给平台产品接口的业务代理参数,未传时不会发送该字段。
|
|
37
|
+
|
|
38
|
+
## 查询余额和套餐
|
|
39
|
+
|
|
40
|
+
如果后续平台开放查询接口,例如:
|
|
41
|
+
|
|
42
|
+
```text
|
|
43
|
+
GET /api/account/balance/get?key=你的密钥
|
|
44
|
+
GET /api/account/packages/get?key=你的密钥
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
SDK 可以这样接入:
|
|
48
|
+
|
|
49
|
+
```python
|
|
50
|
+
client = TianjianClient(
|
|
51
|
+
api_key="你的 API KEY",
|
|
52
|
+
base_url="https://ocr.ikunocr.cn",
|
|
53
|
+
balance_path="account/balance",
|
|
54
|
+
packages_path="account/packages",
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
print(client.balance())
|
|
58
|
+
print(client.packages())
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
这样第三方库保持独立,网站什么时候开放查询能力,SDK 就什么时候启用。
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "tianjian-api"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Python SDK for Tianjian API platform"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.8"
|
|
11
|
+
dependencies = ["requests>=2.28"]
|
|
12
|
+
authors = [{ name = "Tianjian API" }]
|
|
13
|
+
|
|
14
|
+
[tool.setuptools.packages.find]
|
|
15
|
+
where = ["src"]
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
from .client import TianjianClient
|
|
2
|
+
from .exceptions import (
|
|
3
|
+
TianjianAPIError,
|
|
4
|
+
TianjianAuthError,
|
|
5
|
+
TianjianHTTPError,
|
|
6
|
+
TianjianNotConfiguredError,
|
|
7
|
+
TianjianResponseError,
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
__all__ = [
|
|
11
|
+
"TianjianClient",
|
|
12
|
+
"TianjianAPIError",
|
|
13
|
+
"TianjianAuthError",
|
|
14
|
+
"TianjianHTTPError",
|
|
15
|
+
"TianjianNotConfiguredError",
|
|
16
|
+
"TianjianResponseError",
|
|
17
|
+
]
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any, Dict, Optional
|
|
4
|
+
from urllib.parse import urljoin
|
|
5
|
+
|
|
6
|
+
import requests
|
|
7
|
+
|
|
8
|
+
from .exceptions import (
|
|
9
|
+
TianjianAuthError,
|
|
10
|
+
TianjianHTTPError,
|
|
11
|
+
TianjianNotConfiguredError,
|
|
12
|
+
TianjianResponseError,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class TianjianClient:
|
|
17
|
+
def __init__(
|
|
18
|
+
self,
|
|
19
|
+
api_key: str,
|
|
20
|
+
base_url: str = "https://ocr.ikunocr.cn",
|
|
21
|
+
type: str = "api",
|
|
22
|
+
proxy: Optional[str] = None,
|
|
23
|
+
timeout: float = 10,
|
|
24
|
+
balance_path: Optional[str] = None,
|
|
25
|
+
packages_path: Optional[str] = None,
|
|
26
|
+
account_path: Optional[str] = None,
|
|
27
|
+
session: Optional[requests.Session] = None,
|
|
28
|
+
) -> None:
|
|
29
|
+
if not api_key:
|
|
30
|
+
raise ValueError("api_key is required")
|
|
31
|
+
self.api_key = api_key
|
|
32
|
+
self.base_url = base_url.rstrip("/") + "/"
|
|
33
|
+
self.type = type
|
|
34
|
+
self.timeout = timeout
|
|
35
|
+
self.balance_path = balance_path
|
|
36
|
+
self.packages_path = packages_path
|
|
37
|
+
self.account_path = account_path
|
|
38
|
+
self.session = session or requests.Session()
|
|
39
|
+
self.proxies = {"http": proxy, "https": proxy} if proxy else None
|
|
40
|
+
|
|
41
|
+
def account(self) -> Dict[str, Any]:
|
|
42
|
+
if not self.account_path:
|
|
43
|
+
raise TianjianNotConfiguredError("account_path is not configured")
|
|
44
|
+
return self.get(self.account_path)
|
|
45
|
+
|
|
46
|
+
def balance(self) -> Any:
|
|
47
|
+
if not self.balance_path:
|
|
48
|
+
raise TianjianNotConfiguredError("balance_path is not configured")
|
|
49
|
+
return self.get(self.balance_path)
|
|
50
|
+
|
|
51
|
+
def packages(self) -> Any:
|
|
52
|
+
if not self.packages_path:
|
|
53
|
+
raise TianjianNotConfiguredError("packages_path is not configured")
|
|
54
|
+
return self.get(self.packages_path)
|
|
55
|
+
|
|
56
|
+
def call(self, path: str, method: str = "GET", api_proxy: Optional[str] = None, **params: Any) -> Any:
|
|
57
|
+
clean_params = {key: value for key, value in params.items() if value is not None and value != ""}
|
|
58
|
+
if api_proxy:
|
|
59
|
+
clean_params["proxy"] = api_proxy
|
|
60
|
+
return self.request(path, method=method, params=clean_params)
|
|
61
|
+
|
|
62
|
+
def get(self, path: str, **params: Any) -> Any:
|
|
63
|
+
return self.call(path, method="GET", **params)
|
|
64
|
+
|
|
65
|
+
def post(self, path: str, **params: Any) -> Any:
|
|
66
|
+
return self.call(path, method="POST", **params)
|
|
67
|
+
|
|
68
|
+
def request(self, path: str, method: str = "GET", params: Optional[Dict[str, Any]] = None) -> Any:
|
|
69
|
+
method = method.upper()
|
|
70
|
+
payload = dict(params or {})
|
|
71
|
+
payload["key"] = self.api_key
|
|
72
|
+
url = self._url(path)
|
|
73
|
+
|
|
74
|
+
if method == "GET":
|
|
75
|
+
response = self.session.get(url, params=payload, timeout=self.timeout, proxies=self.proxies)
|
|
76
|
+
elif method == "POST":
|
|
77
|
+
response = self.session.post(url, data=payload, timeout=self.timeout, proxies=self.proxies)
|
|
78
|
+
else:
|
|
79
|
+
raise ValueError("method must be GET or POST")
|
|
80
|
+
|
|
81
|
+
return self._parse_response(response)
|
|
82
|
+
|
|
83
|
+
def _url(self, path: str) -> str:
|
|
84
|
+
if path.startswith("http://") or path.startswith("https://"):
|
|
85
|
+
return path
|
|
86
|
+
normalized = path.lstrip("/")
|
|
87
|
+
if normalized.startswith("api/") and not normalized.endswith("/get"):
|
|
88
|
+
return urljoin(self.base_url, normalized)
|
|
89
|
+
if normalized.startswith("api/"):
|
|
90
|
+
return urljoin(self.base_url, normalized)
|
|
91
|
+
return urljoin(self.base_url, f"api/{normalized}/get")
|
|
92
|
+
|
|
93
|
+
def _parse_response(self, response: requests.Response) -> Any:
|
|
94
|
+
if response.status_code < 200 or response.status_code >= 300:
|
|
95
|
+
raise TianjianHTTPError(f"HTTP {response.status_code}: {response.text[:200]}")
|
|
96
|
+
|
|
97
|
+
try:
|
|
98
|
+
data = response.json()
|
|
99
|
+
except ValueError:
|
|
100
|
+
return response.text
|
|
101
|
+
|
|
102
|
+
code = data.get("code")
|
|
103
|
+
if code in (200, 0, "200", "0", None):
|
|
104
|
+
return data
|
|
105
|
+
|
|
106
|
+
message = data.get("msg") or data.get("message") or "request failed"
|
|
107
|
+
if str(code) in {"401", "403"}:
|
|
108
|
+
raise TianjianAuthError(message)
|
|
109
|
+
raise TianjianResponseError(message)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
class TianjianAPIError(Exception):
|
|
2
|
+
"""Base exception for Tianjian SDK errors."""
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class TianjianHTTPError(TianjianAPIError):
|
|
6
|
+
"""Raised when the platform returns a non-2xx HTTP response."""
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class TianjianResponseError(TianjianAPIError):
|
|
10
|
+
"""Raised when the platform returns a business error code."""
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class TianjianAuthError(TianjianResponseError):
|
|
14
|
+
"""Raised when the API key is invalid or unauthorized."""
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class TianjianNotConfiguredError(TianjianAPIError):
|
|
18
|
+
"""Raised when an optional SDK endpoint is not configured."""
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: tianjian-api
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python SDK for Tianjian API platform
|
|
5
|
+
Author: Tianjian API
|
|
6
|
+
Requires-Python: >=3.8
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
Requires-Dist: requests>=2.28
|
|
9
|
+
|
|
10
|
+
# Tianjian API Python SDK
|
|
11
|
+
|
|
12
|
+
简洁同步版 SDK,适合服务端脚本、业务系统和定时任务接入。它是独立 Python 第三方库,不改变网站现有业务接口。
|
|
13
|
+
|
|
14
|
+
## 安装
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pip install -e .
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## 快速开始
|
|
21
|
+
|
|
22
|
+
```python
|
|
23
|
+
from tianjian_api import TianjianClient
|
|
24
|
+
|
|
25
|
+
client = TianjianClient(
|
|
26
|
+
api_key="你的 API KEY",
|
|
27
|
+
base_url="https://ocr.ikunocr.cn",
|
|
28
|
+
type="api",
|
|
29
|
+
proxy="http://127.0.0.1:7890", # SDK 请求平台时使用的网络代理,可不填
|
|
30
|
+
timeout=10,
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
res = client.call("16hangzhoudxdx", c="xxx", api_proxy="http://user:pass@ip:port/")
|
|
34
|
+
print(res)
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## 常用能力
|
|
38
|
+
|
|
39
|
+
- `client.call(path, **params)` 调用任意产品接口,自动携带 `key`。
|
|
40
|
+
- `client.get(path, **params)` 使用 GET 调用产品接口。
|
|
41
|
+
- `client.post(path, **params)` 使用 POST 调用产品接口。
|
|
42
|
+
- `client.balance()` 查询余额,需要平台提供 API KEY 查询接口后配置 `balance_path`。
|
|
43
|
+
- `client.packages()` 查询当前用户套餐,需要平台提供 API KEY 查询接口后配置 `packages_path`。
|
|
44
|
+
|
|
45
|
+
注意:`proxy` 是 SDK 自己访问平台时使用的网络代理;`api_proxy` 是传给平台产品接口的业务代理参数,未传时不会发送该字段。
|
|
46
|
+
|
|
47
|
+
## 查询余额和套餐
|
|
48
|
+
|
|
49
|
+
如果后续平台开放查询接口,例如:
|
|
50
|
+
|
|
51
|
+
```text
|
|
52
|
+
GET /api/account/balance/get?key=你的密钥
|
|
53
|
+
GET /api/account/packages/get?key=你的密钥
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
SDK 可以这样接入:
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
client = TianjianClient(
|
|
60
|
+
api_key="你的 API KEY",
|
|
61
|
+
base_url="https://ocr.ikunocr.cn",
|
|
62
|
+
balance_path="account/balance",
|
|
63
|
+
packages_path="account/packages",
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
print(client.balance())
|
|
67
|
+
print(client.packages())
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
这样第三方库保持独立,网站什么时候开放查询能力,SDK 就什么时候启用。
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
src/tianjian_api/__init__.py
|
|
4
|
+
src/tianjian_api/client.py
|
|
5
|
+
src/tianjian_api/exceptions.py
|
|
6
|
+
src/tianjian_api.egg-info/PKG-INFO
|
|
7
|
+
src/tianjian_api.egg-info/SOURCES.txt
|
|
8
|
+
src/tianjian_api.egg-info/dependency_links.txt
|
|
9
|
+
src/tianjian_api.egg-info/requires.txt
|
|
10
|
+
src/tianjian_api.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
requests>=2.28
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
tianjian_api
|