py-tiehu 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.
py_tiehu-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 郭磊
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.
@@ -0,0 +1,277 @@
1
+ Metadata-Version: 2.4
2
+ Name: py-tiehu
3
+ Version: 0.1.0
4
+ Summary: PyTiehu 是铁虎停车场管理系统的 Python SDK,提供同步和异步两种调用方式,实现完整的请求签名机制,用于与铁虎停车场管理系统进行 API 交互。
5
+ Author-email: Guolei <174000902@qq.com>
6
+ License: MIT License
7
+
8
+ Copyright (c) 2026 郭磊
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ Project-URL: Homepage, https://gitee.com/guolei19850528/py_tiehu
29
+ Project-URL: Repository, https://gitee.com/guolei19850528/py_tiehu.git
30
+ Keywords: tiehu,python,client,api,铁虎,停车场
31
+ Classifier: License :: OSI Approved :: MIT License
32
+ Classifier: Development Status :: 4 - Beta
33
+ Classifier: Intended Audience :: Developers
34
+ Classifier: Programming Language :: Python :: 3
35
+ Classifier: Programming Language :: Python :: 3.10
36
+ Classifier: Programming Language :: Python :: 3.11
37
+ Classifier: Programming Language :: Python :: 3.12
38
+ Classifier: Programming Language :: Python :: 3.13
39
+ Classifier: Operating System :: OS Independent
40
+ Requires-Python: >=3.10
41
+ Description-Content-Type: text/markdown
42
+ License-File: LICENSE
43
+ Requires-Dist: httpx>=0.27.0
44
+ Requires-Dist: pydantic>=2.0
45
+ Requires-Dist: jsonpath-ng>=1.5.3
46
+ Requires-Dist: jsonschema>=4.21.0
47
+ Provides-Extra: dev
48
+ Requires-Dist: pytest>=7.0; extra == "dev"
49
+ Requires-Dist: pytest-cov>=4.0; extra == "dev"
50
+ Requires-Dist: setuptools>=61.0; extra == "dev"
51
+ Requires-Dist: twine>=4.0; extra == "dev"
52
+ Dynamic: license-file
53
+
54
+ # PyTiehu - 铁虎停车场 API Python SDK
55
+
56
+ [![Python Version](https://img.shields.io/badge/python-3.8%2B-blue.svg)](https://python.org)
57
+ [![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
58
+
59
+ PyTiehu 是铁虎停车场管理系统的 Python SDK,提供同步和异步两种调用方式,实现完整的请求签名机制,用于与铁虎停车场管理系统进行
60
+ API 交互。
61
+
62
+ ## 功能特性
63
+
64
+ - ✅ 自动生成请求签名(MD5 算法)
65
+ - ✅ 支持同步/异步 HTTP 请求
66
+ - ✅ 自动添加公共请求参数(parkingId、timestamp、sign)
67
+ - ✅ 灵活的客户端配置选项
68
+ - ✅ Pydantic 响应模型支持
69
+
70
+ ## 安装
71
+
72
+ ```bash
73
+ pip install py_tiehu
74
+ ```
75
+
76
+ ## 快速开始
77
+
78
+ ### 同步客户端
79
+
80
+ ```python
81
+ from py_tiehu import Pklot
82
+
83
+ # 初始化客户端
84
+ client = Pklot(
85
+ base_url="https://isc.example.com",
86
+ parking_id="park001",
87
+ app_key="your_app_secret"
88
+ )
89
+
90
+ # 发送请求
91
+ response = client.request(
92
+ url="/api/v1/parking/query",
93
+ json={"plateNo": "京A12345"}
94
+ )
95
+
96
+ # 处理响应
97
+ print(response.json())
98
+ ```
99
+
100
+ ### 异步客户端
101
+
102
+ ```python
103
+ import asyncio
104
+ from py_tiehu import Pklot
105
+
106
+ # 初始化客户端
107
+ client = Pklot(
108
+ base_url="https://isc.example.com",
109
+ parking_id="park001",
110
+ app_key="your_app_secret"
111
+ )
112
+
113
+
114
+ # 异步发送请求
115
+ async def main():
116
+ response = await client.async_request(
117
+ url="/api/v1/parking/query",
118
+ json={"plateNo": "京A12345"}
119
+ )
120
+ print(response.json())
121
+
122
+
123
+ asyncio.run(main())
124
+ ```
125
+
126
+ ## API 文档
127
+
128
+ ### Pklot 类
129
+
130
+ #### 初始化参数
131
+
132
+ | 参数 | 类型 | 必填 | 说明 |
133
+ |-----------------|------|----|--------------------------|
134
+ | `base_url` | str | 是 | 停车场管理系统服务器基础 URL |
135
+ | `parking_id` | str | 是 | 停车场 ID |
136
+ | `app_key` | str | 是 | 应用密钥,用于生成请求签名 |
137
+ | `client_kwargs` | dict | 否 | 传递给 httpx.Client 的额外配置参数 |
138
+
139
+ #### 方法
140
+
141
+ | 方法 | 说明 | 返回值 |
142
+ |---------------------------|---------------|---------------------|
143
+ | `client()` | 创建同步 HTTP 客户端 | `httpx.Client` |
144
+ | `async_client()` | 创建异步 HTTP 客户端 | `httpx.AsyncClient` |
145
+ | `signature(data)` | 生成请求签名 | `str` |
146
+ | `request(**kwargs)` | 发送同步请求 | `httpx.Response` |
147
+ | `async_request(**kwargs)` | 发送异步请求 | `httpx.Response` |
148
+
149
+ ### 签名算法
150
+
151
+ 签名生成步骤:
152
+
153
+ 1. 排除数据中的 `appKey` 字段
154
+ 2. 对剩余字段按键名进行升序排序
155
+ 3. 将排序后的字段以 `key=value` 格式用 `&` 连接
156
+ 4. 尾部拼接 `appKey` 的 MD5 值(大写)
157
+ 5. 对拼接后的完整字符串进行 MD5 计算并转为大写
158
+
159
+ ### 工具函数
160
+
161
+ #### `timestamp()`
162
+
163
+ 生成当前时间戳(毫秒)
164
+
165
+ ```python
166
+ from py_tiehu.utils import timestamp
167
+
168
+ ts = timestamp() # 输出示例: 1630000000000
169
+ ```
170
+
171
+ #### `json_find_first(expression, data)`
172
+
173
+ 使用 JSONPath 表达式从数据中查找第一个匹配项
174
+
175
+ ```python
176
+ from py_tiehu.utils import json_find_first
177
+
178
+ result = json_find_first("$.data[0].name", response.json())
179
+ ```
180
+
181
+ #### `convert_to_status_eq_1(response)`
182
+
183
+ 将 HTTP 响应或字典转换为 STATUS_EQ_1 模型对象
184
+
185
+ ```python
186
+ from py_tiehu.utils import convert_to_status_eq_1
187
+
188
+ result = convert_to_status_eq_1(response)
189
+ print(result.status) # 1
190
+ print(result.Data) # 响应数据
191
+ ```
192
+
193
+ ## 响应模型
194
+
195
+ ### Base
196
+
197
+ 所有 API 响应的基类:
198
+
199
+ ```python
200
+ class Base(BaseModel):
201
+ status: Union[int, str] # 错误码,1表示成功,非1表示失败
202
+ message: Optional[str] # 错误信息描述
203
+ ```
204
+
205
+ ### STATUS_EQ_1
206
+
207
+ 成功响应模型:
208
+
209
+ ```python
210
+ class STATUS_EQ_1(Base):
211
+ status: Literal[1, "1"] # 成功,值为1
212
+ Data: Any # 成功响应数据
213
+ ```
214
+
215
+ ## 配置说明
216
+
217
+ ### 默认配置
218
+
219
+ ```python
220
+ {
221
+ "base_url": "<your_base_url>",
222
+ "verify": False, # 禁用 SSL 证书验证
223
+ "timeout": 120 # 超时时间 120 秒
224
+ }
225
+ ```
226
+
227
+ ### 自定义配置
228
+
229
+ ```python
230
+ client = Pklot(
231
+ base_url="https://isc.example.com",
232
+ parking_id="park001",
233
+ app_key="your_app_secret",
234
+ client_kwargs={
235
+ "timeout": 60,
236
+ "verify": True,
237
+ "headers": {"X-Custom": "value"}
238
+ }
239
+ )
240
+ ```
241
+
242
+ ## 示例
243
+
244
+ ### 查询车辆信息
245
+
246
+ ```python
247
+ response = client.request(
248
+ url="/api/v1/vehicle/query",
249
+ json={
250
+ "plateNo": "京A12345",
251
+ "parkingId": "park001"
252
+ }
253
+ )
254
+ ```
255
+
256
+ ### 批量查询
257
+
258
+ ```python
259
+ response = client.request(
260
+ url="/api/v1/vehicle/batch",
261
+ json={
262
+ "plateNos": ["京A12345", "京B67890"],
263
+ "pageIndex": 1,
264
+ "pageSize": 20
265
+ }
266
+ )
267
+ ```
268
+
269
+ ## 主页
270
+
271
+ [https://gitee.com/guolei19850528/py_tiehu](https://gitee.com/guolei19850528/py_tiehu)
272
+
273
+ ## 许可证
274
+
275
+ MIT License
276
+
277
+ ## 开发
@@ -0,0 +1,224 @@
1
+ # PyTiehu - 铁虎停车场 API Python SDK
2
+
3
+ [![Python Version](https://img.shields.io/badge/python-3.8%2B-blue.svg)](https://python.org)
4
+ [![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
5
+
6
+ PyTiehu 是铁虎停车场管理系统的 Python SDK,提供同步和异步两种调用方式,实现完整的请求签名机制,用于与铁虎停车场管理系统进行
7
+ API 交互。
8
+
9
+ ## 功能特性
10
+
11
+ - ✅ 自动生成请求签名(MD5 算法)
12
+ - ✅ 支持同步/异步 HTTP 请求
13
+ - ✅ 自动添加公共请求参数(parkingId、timestamp、sign)
14
+ - ✅ 灵活的客户端配置选项
15
+ - ✅ Pydantic 响应模型支持
16
+
17
+ ## 安装
18
+
19
+ ```bash
20
+ pip install py_tiehu
21
+ ```
22
+
23
+ ## 快速开始
24
+
25
+ ### 同步客户端
26
+
27
+ ```python
28
+ from py_tiehu import Pklot
29
+
30
+ # 初始化客户端
31
+ client = Pklot(
32
+ base_url="https://isc.example.com",
33
+ parking_id="park001",
34
+ app_key="your_app_secret"
35
+ )
36
+
37
+ # 发送请求
38
+ response = client.request(
39
+ url="/api/v1/parking/query",
40
+ json={"plateNo": "京A12345"}
41
+ )
42
+
43
+ # 处理响应
44
+ print(response.json())
45
+ ```
46
+
47
+ ### 异步客户端
48
+
49
+ ```python
50
+ import asyncio
51
+ from py_tiehu import Pklot
52
+
53
+ # 初始化客户端
54
+ client = Pklot(
55
+ base_url="https://isc.example.com",
56
+ parking_id="park001",
57
+ app_key="your_app_secret"
58
+ )
59
+
60
+
61
+ # 异步发送请求
62
+ async def main():
63
+ response = await client.async_request(
64
+ url="/api/v1/parking/query",
65
+ json={"plateNo": "京A12345"}
66
+ )
67
+ print(response.json())
68
+
69
+
70
+ asyncio.run(main())
71
+ ```
72
+
73
+ ## API 文档
74
+
75
+ ### Pklot 类
76
+
77
+ #### 初始化参数
78
+
79
+ | 参数 | 类型 | 必填 | 说明 |
80
+ |-----------------|------|----|--------------------------|
81
+ | `base_url` | str | 是 | 停车场管理系统服务器基础 URL |
82
+ | `parking_id` | str | 是 | 停车场 ID |
83
+ | `app_key` | str | 是 | 应用密钥,用于生成请求签名 |
84
+ | `client_kwargs` | dict | 否 | 传递给 httpx.Client 的额外配置参数 |
85
+
86
+ #### 方法
87
+
88
+ | 方法 | 说明 | 返回值 |
89
+ |---------------------------|---------------|---------------------|
90
+ | `client()` | 创建同步 HTTP 客户端 | `httpx.Client` |
91
+ | `async_client()` | 创建异步 HTTP 客户端 | `httpx.AsyncClient` |
92
+ | `signature(data)` | 生成请求签名 | `str` |
93
+ | `request(**kwargs)` | 发送同步请求 | `httpx.Response` |
94
+ | `async_request(**kwargs)` | 发送异步请求 | `httpx.Response` |
95
+
96
+ ### 签名算法
97
+
98
+ 签名生成步骤:
99
+
100
+ 1. 排除数据中的 `appKey` 字段
101
+ 2. 对剩余字段按键名进行升序排序
102
+ 3. 将排序后的字段以 `key=value` 格式用 `&` 连接
103
+ 4. 尾部拼接 `appKey` 的 MD5 值(大写)
104
+ 5. 对拼接后的完整字符串进行 MD5 计算并转为大写
105
+
106
+ ### 工具函数
107
+
108
+ #### `timestamp()`
109
+
110
+ 生成当前时间戳(毫秒)
111
+
112
+ ```python
113
+ from py_tiehu.utils import timestamp
114
+
115
+ ts = timestamp() # 输出示例: 1630000000000
116
+ ```
117
+
118
+ #### `json_find_first(expression, data)`
119
+
120
+ 使用 JSONPath 表达式从数据中查找第一个匹配项
121
+
122
+ ```python
123
+ from py_tiehu.utils import json_find_first
124
+
125
+ result = json_find_first("$.data[0].name", response.json())
126
+ ```
127
+
128
+ #### `convert_to_status_eq_1(response)`
129
+
130
+ 将 HTTP 响应或字典转换为 STATUS_EQ_1 模型对象
131
+
132
+ ```python
133
+ from py_tiehu.utils import convert_to_status_eq_1
134
+
135
+ result = convert_to_status_eq_1(response)
136
+ print(result.status) # 1
137
+ print(result.Data) # 响应数据
138
+ ```
139
+
140
+ ## 响应模型
141
+
142
+ ### Base
143
+
144
+ 所有 API 响应的基类:
145
+
146
+ ```python
147
+ class Base(BaseModel):
148
+ status: Union[int, str] # 错误码,1表示成功,非1表示失败
149
+ message: Optional[str] # 错误信息描述
150
+ ```
151
+
152
+ ### STATUS_EQ_1
153
+
154
+ 成功响应模型:
155
+
156
+ ```python
157
+ class STATUS_EQ_1(Base):
158
+ status: Literal[1, "1"] # 成功,值为1
159
+ Data: Any # 成功响应数据
160
+ ```
161
+
162
+ ## 配置说明
163
+
164
+ ### 默认配置
165
+
166
+ ```python
167
+ {
168
+ "base_url": "<your_base_url>",
169
+ "verify": False, # 禁用 SSL 证书验证
170
+ "timeout": 120 # 超时时间 120 秒
171
+ }
172
+ ```
173
+
174
+ ### 自定义配置
175
+
176
+ ```python
177
+ client = Pklot(
178
+ base_url="https://isc.example.com",
179
+ parking_id="park001",
180
+ app_key="your_app_secret",
181
+ client_kwargs={
182
+ "timeout": 60,
183
+ "verify": True,
184
+ "headers": {"X-Custom": "value"}
185
+ }
186
+ )
187
+ ```
188
+
189
+ ## 示例
190
+
191
+ ### 查询车辆信息
192
+
193
+ ```python
194
+ response = client.request(
195
+ url="/api/v1/vehicle/query",
196
+ json={
197
+ "plateNo": "京A12345",
198
+ "parkingId": "park001"
199
+ }
200
+ )
201
+ ```
202
+
203
+ ### 批量查询
204
+
205
+ ```python
206
+ response = client.request(
207
+ url="/api/v1/vehicle/batch",
208
+ json={
209
+ "plateNos": ["京A12345", "京B67890"],
210
+ "pageIndex": 1,
211
+ "pageSize": 20
212
+ }
213
+ )
214
+ ```
215
+
216
+ ## 主页
217
+
218
+ [https://gitee.com/guolei19850528/py_tiehu](https://gitee.com/guolei19850528/py_tiehu)
219
+
220
+ ## 许可证
221
+
222
+ MIT License
223
+
224
+ ## 开发
@@ -0,0 +1,45 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+ [project]
5
+ name = "py-tiehu"
6
+ version = "0.1.0"
7
+ requires-python = ">=3.10"
8
+ authors = [
9
+ { name = "Guolei", email = "174000902@qq.com" }
10
+ ]
11
+ description = "PyTiehu 是铁虎停车场管理系统的 Python SDK,提供同步和异步两种调用方式,实现完整的请求签名机制,用于与铁虎停车场管理系统进行 API 交互。"
12
+ keywords = ["tiehu", "python", "client", "api", "铁虎", "停车场"]
13
+ license = { file = "LICENSE" }
14
+ readme = "README.md"
15
+ classifiers = [
16
+ "License :: OSI Approved :: MIT License",
17
+ "Development Status :: 4 - Beta",
18
+ "Intended Audience :: Developers",
19
+ "Programming Language :: Python :: 3",
20
+ "Programming Language :: Python :: 3.10",
21
+ "Programming Language :: Python :: 3.11",
22
+ "Programming Language :: Python :: 3.12",
23
+ "Programming Language :: Python :: 3.13",
24
+ "Operating System :: OS Independent",
25
+ ]
26
+ dependencies = [
27
+ "httpx>=0.27.0",
28
+ "pydantic>=2.0",
29
+ "jsonpath-ng>=1.5.3",
30
+ "jsonschema>=4.21.0",
31
+ ]
32
+ [project.optional-dependencies]
33
+ dev = [
34
+ "pytest>=7.0",
35
+ "pytest-cov>=4.0",
36
+ "setuptools>=61.0",
37
+ "twine>=4.0",
38
+ ]
39
+
40
+ [project.urls]
41
+ "Homepage" = "https://gitee.com/guolei19850528/py_tiehu"
42
+ "Repository" = "https://gitee.com/guolei19850528/py_tiehu.git"
43
+
44
+ [tool.setuptools.packages.find]
45
+ where = ["src"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,234 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: UTF-8 -*-
3
+ """
4
+ 铁虎 停车场 API Python SDK
5
+
6
+ 提供同步和异步两种调用方式,实现完整的请求签名机制,
7
+ 用于与铁虎停车场管理系统进行 API 交互。
8
+
9
+ 主要功能:
10
+ - 自动生成请求签名(MD5算法)
11
+ - 支持同步/异步 HTTP 请求
12
+ - 自动添加公共请求参数(parkingId、timestamp、sign)
13
+ - 灵活的客户端配置选项
14
+ """
15
+
16
+ import hashlib
17
+ from typing import Optional
18
+
19
+ import httpx
20
+
21
+ from .utils import timestamp
22
+
23
+
24
+ class Pklot:
25
+ """
26
+ 铁虎停车场 API 客户端类
27
+
28
+ 提供与铁虎 停车场管理系统交互的核心功能,
29
+ 支持同步和异步两种请求模式,自动处理请求签名和公共参数。
30
+
31
+ Attributes:
32
+ base_url (str): 停车场管理系统 服务器基础 URL
33
+ parking_id (str): 停车场 ID,用于标识目标停车场
34
+ app_key (str): 应用密钥,用于生成请求签名
35
+ client_kwargs (dict): HTTP 客户端配置参数
36
+
37
+ Example:
38
+ # 同步客户端
39
+ sync_client = Pklot(
40
+ base_url="https://isc.example.com",
41
+ parking_id="park001",
42
+ app_key="your_app_secret"
43
+ )
44
+
45
+ # 异步客户端
46
+ async_client = Pklot(
47
+ base_url="https://isc.example.com",
48
+ parking_id="park001",
49
+ app_key="your_app_secret",
50
+ use_async_client=True
51
+ )
52
+ """
53
+
54
+ def __init__(
55
+ self,
56
+ base_url: Optional[str] = None,
57
+ parking_id: Optional[str] = None,
58
+ app_key: Optional[str] = None,
59
+ client_kwargs: Optional[dict] = None
60
+ ):
61
+ """
62
+ 初始化 Pklot 客户端
63
+
64
+ Args:
65
+ base_url: 停车场管理系统 服务器基础 URL,如 "https://isc.example.com"
66
+ parking_id: 停车场 ID,由停车场 系统分配
67
+ app_key: 应用密钥,用于请求签名生成
68
+ client_kwargs: 传递给 httpx.Client 的额外配置参数
69
+
70
+ Note:
71
+ - base_url 末尾的斜杠会被自动移除
72
+ - client_kwargs 支持 httpx 客户端的所有配置选项
73
+ - 默认超时时间为 120 秒
74
+ - 默认禁用 SSL 证书验证(verify=False)
75
+ """
76
+ # 处理基础 URL,移除末尾斜杠
77
+ self.base_url = base_url or ""
78
+ self.base_url = self.base_url[:-1] if self.base_url.endswith("/") else self.base_url
79
+
80
+ # 存储核心配置参数
81
+ self.parking_id = parking_id or ""
82
+ self.app_key = app_key or ""
83
+ self.client_kwargs = client_kwargs or {}
84
+
85
+ self.client_kwargs = {
86
+ **{
87
+ "base_url": self.base_url,
88
+ "verify": False,
89
+ "timeout": 120,
90
+ },
91
+ **self.client_kwargs,
92
+ }
93
+
94
+ def client(self) -> httpx.Client:
95
+ """
96
+ 创建并返回同步HTTP客户端
97
+
98
+ Returns:
99
+ httpx.Client: 配置好的同步HTTP客户端实例
100
+ """
101
+ return httpx.Client(**self.client_kwargs)
102
+
103
+ def async_client(self) -> httpx.AsyncClient:
104
+ """
105
+ 创建并返回异步HTTP客户端
106
+
107
+ Returns:
108
+ httpx.AsyncClient: 配置好的异步HTTP客户端实例
109
+ """
110
+ return httpx.AsyncClient(**self.client_kwargs)
111
+
112
+ def signature(self, data: Optional[dict] = None) -> str:
113
+ """
114
+ 生成请求签名,用于验证 API 请求的合法性和完整性
115
+
116
+ Args:
117
+ data: 需要签名的数据字典,包含 API 请求的参数
118
+
119
+ Returns:
120
+ str: 生成的 MD5 签名字符串(大写),用于 API 请求的 sign 参数
121
+
122
+ 签名算法说明:
123
+ 1. 排除数据中的 appKey 字段
124
+ 2. 对剩余字段按键名进行升序排序
125
+ 3. 将排序后的字段以 "key=value" 格式用 "&" 连接
126
+ 4. 尾部拼接 appKey 的 MD5 值(大写)
127
+ 5. 对拼接后的完整字符串进行 MD5 计算并转为大写
128
+
129
+ Example:
130
+ >>> client = Parking(parking_id="123", app_key="secret")
131
+ >>> sign = client.signature({"parkingId": "123", "timestamp": 1234567890})
132
+ >>> print(sign) # 输出类似: A1B2C3D4E5F67890ABCDEF1234567890
133
+ """
134
+ # 确保 data 是字典类型,避免后续操作出错
135
+ data = data or {}
136
+ temp_string = ""
137
+
138
+ # 如果有数据需要签名
139
+ if len(data.keys()):
140
+ # 对字典键进行排序,确保签名的一致性(升序排列)
141
+ data_sorted = sorted(data.keys())
142
+ if isinstance(data_sorted, list):
143
+ # 构建待签名字符串,排除 appKey 字段
144
+ temp_string = "&".join([
145
+ f"{i}={data[i]}"
146
+ for i in data_sorted if i != "appKey" # 排除 appKey 字段,避免重复签名
147
+ ]) + f"{hashlib.md5(self.app_key.encode('utf-8')).hexdigest().upper()}"
148
+
149
+ # 生成最终的 MD5 签名并转换为大写格式
150
+ return hashlib.md5(temp_string.encode('utf-8')).hexdigest().upper()
151
+
152
+ def request(self, client: Optional[httpx.Client] = None, **kwargs):
153
+ """
154
+ 同步请求方法
155
+
156
+ 自动添加公共请求参数(parkingId、timestamp、sign),
157
+ 并生成请求签名,然后发送同步 HTTP 请求。
158
+
159
+ Args:
160
+ client: 可选的同步客户端实例,若不提供则使用内置客户端
161
+ **kwargs: 传递给 client.request 的额外参数,支持所有 httpx 参数
162
+
163
+ Returns:
164
+ httpx.Response: HTTP 响应对象
165
+
166
+ Example:
167
+ >>> client = Parking(base_url="https://isc.example.com", ...)
168
+ >>> response = client.request(url="/api/v1/parking/query", json={"plateNo": "京A12345"})
169
+ >>> print(response.json())
170
+ """
171
+ ts = timestamp()
172
+ kwargs = kwargs or {}
173
+ kwargs = {
174
+ **{
175
+ "method": "POST",
176
+ "json": {
177
+ "parkingId": self.parking_id, # 停车场 ID,必填公共参数
178
+ "timestamp": ts, # 时间戳,用于防止请求重放
179
+ "sign": self.signature({ # 生成请求签名
180
+ "parkingId": self.parking_id,
181
+ "timestamp": ts,
182
+ })
183
+ },
184
+ },
185
+ **kwargs
186
+ }
187
+ if isinstance(client, httpx.Client):
188
+ response = client.request(**kwargs)
189
+ else:
190
+ with self.client() as _client:
191
+ response = _client.request(**kwargs)
192
+ return response
193
+
194
+ async def async_request(self, client: Optional[httpx.AsyncClient] = None, **kwargs) -> httpx.Response:
195
+ """
196
+ 异步请求方法
197
+
198
+ 自动添加公共请求参数(parkingId、timestamp、sign),
199
+ 并生成请求签名,然后发送异步 HTTP 请求。
200
+
201
+ Args:
202
+ client: 可选的异步客户端实例,若不提供则使用内置客户端
203
+ **kwargs: 传递给 client.request 的额外参数,支持所有 httpx 参数
204
+
205
+ Returns:
206
+ httpx.Response: HTTP 响应对象
207
+
208
+ Example:
209
+ >>> client = Parking(base_url="https://isc.example.com", use_async_client=True, ...)
210
+ >>> response = await client.async_request(url="/api/v1/parking/query", json={"plateNo": "京A12345"})
211
+ >>> print(response.json())
212
+ """
213
+ ts = timestamp()
214
+ kwargs = kwargs or {}
215
+ kwargs = {
216
+ **{
217
+ "method": "POST",
218
+ "json": {
219
+ "parkingId": self.parking_id, # 停车场 ID,必填公共参数
220
+ "timestamp": ts, # 时间戳,用于防止请求重放
221
+ "sign": self.signature({ # 生成请求签名
222
+ "parkingId": self.parking_id,
223
+ "timestamp": ts,
224
+ })
225
+ },
226
+ },
227
+ **kwargs
228
+ }
229
+ if isinstance(client, httpx.AsyncClient):
230
+ response = await client.request(**kwargs)
231
+ else:
232
+ async with self.async_client() as _client:
233
+ response = await _client.request(**kwargs)
234
+ return response
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: UTF-8 -*-
3
+ from pydantic import BaseModel
4
+ from pydantic import Field
5
+ from typing import Literal, Union, Any, Optional
6
+
7
+
8
+ class Base(BaseModel):
9
+ """
10
+ iSecure Center响应基类
11
+
12
+ 所有API响应都包含错误码和错误信息字段
13
+ """
14
+ status: Union[int, str] = Field(..., title="错误码", description="错误码,1表示成功,非1表示失败")
15
+ message: Optional[str] = Field(default=None, title="错误信息", description="错误信息描述")
16
+
17
+ model_config = {
18
+ "extra": "allow" # 允许额外动态字段
19
+ }
20
+
21
+
22
+ class STATUS_EQ_1(Base):
23
+ """
24
+ 成功响应模型
25
+
26
+ 继承自Base,用于成功接口的响应
27
+ """
28
+ status: Literal[1, "1"] = Field(..., title="错误码", description="成功,值为1")
29
+ Data: Any = Field(title="数据", description="成功响应数据")
@@ -0,0 +1,103 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: UTF-8 -*-
3
+ from datetime import datetime
4
+ from typing import Any, Optional, Union
5
+
6
+ import httpx
7
+ from jsonpath_ng import parse
8
+ from jsonschema.validators import Draft202012Validator
9
+
10
+ from .responses import STATUS_EQ_1
11
+
12
+
13
+ def json_find_first(expression: str, data: Any) -> Any:
14
+ """
15
+ 使用 JSONPath 表达式从数据中查找第一个匹配项
16
+
17
+ Args:
18
+ expression: JSONPath 表达式,用于指定要查找的数据路径
19
+ data: 待查询的 JSON 数据
20
+
21
+ Returns:
22
+ Any: 第一个匹配的值,如果没有匹配项则返回 None
23
+ """
24
+ results = [i.value for i in parse(expression).find(data)]
25
+ if isinstance(results, list) and len(results) > 0:
26
+ return results[0]
27
+ return None
28
+
29
+
30
+ def json_is_valid(schema: Optional[dict], data: Any) -> bool:
31
+ """
32
+ 校验 JSON 数据是否符合指定的 JSON Schema
33
+
34
+ Args:
35
+ schema: JSON Schema 字典
36
+ data: 待校验的 JSON 数据
37
+
38
+ Returns:
39
+ bool: 校验是否成功
40
+ """
41
+ return Draft202012Validator(schema).is_valid(data)
42
+
43
+
44
+ def timestamp() -> int:
45
+ """
46
+ 生成当前时间戳(毫秒)
47
+
48
+ 返回:
49
+ int: 当前时间戳(毫秒),用于请求的时效性验证
50
+
51
+ 示例:
52
+ >>> ts = utils.timestamp()
53
+ >>> print(ts) # 输出示例: 1630000000000
54
+ """
55
+ return int((datetime.now().timestamp() * 1000))
56
+
57
+
58
+ def convert_to_status_eq_1(response: Union[httpx.Response, dict]) -> STATUS_EQ_1:
59
+ """
60
+ 将 HTTP 响应或字典转换为 STATUS_EQ_1 模型对象
61
+
62
+ 统一处理 httpx.Response 对象和字典,将其转换为标准化的 STATUS_EQ_1 响应模型。
63
+
64
+ 参数:
65
+ response (Union[httpx.Response, dict]): HTTP 响应对象或字典数据
66
+
67
+ 返回:
68
+ STATUS_EQ_1: 标准化的响应模型对象,包含 status、message 和 Data 字段
69
+
70
+ 处理逻辑:
71
+ - 如果输入是 httpx.Response 对象,先调用 json() 方法解析响应体
72
+ - 如果输入是字典,直接传入 STATUS_EQ_1 构造函数
73
+ """
74
+ if isinstance(response, httpx.Response):
75
+ return STATUS_EQ_1(**response.json())
76
+ return STATUS_EQ_1(**response)
77
+
78
+
79
+ def status_eq_1_validator(
80
+ response: Union[httpx.Response, dict] = None,
81
+ schema: dict = {
82
+ "type": "object",
83
+ "properties": {
84
+ "status": {
85
+ "oneOf": [
86
+ {"type": "integer", "const": 1},
87
+ {"type": "string", "const": "1"}
88
+ ]
89
+ },
90
+ },
91
+ "required": ["status"]
92
+ }
93
+ ):
94
+ """
95
+ 校验 HTTP 响应或字典是否符合指定的 JSON Schema
96
+
97
+ :param response: HTTP 响应对象或字典数据
98
+ :param schema: JSON Schema 字典
99
+ :return: 校验是否成功
100
+ """
101
+ if isinstance(response, httpx.Response):
102
+ return json_is_valid(schema, response.json())
103
+ return json_is_valid(schema, response)
@@ -0,0 +1,277 @@
1
+ Metadata-Version: 2.4
2
+ Name: py-tiehu
3
+ Version: 0.1.0
4
+ Summary: PyTiehu 是铁虎停车场管理系统的 Python SDK,提供同步和异步两种调用方式,实现完整的请求签名机制,用于与铁虎停车场管理系统进行 API 交互。
5
+ Author-email: Guolei <174000902@qq.com>
6
+ License: MIT License
7
+
8
+ Copyright (c) 2026 郭磊
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ Project-URL: Homepage, https://gitee.com/guolei19850528/py_tiehu
29
+ Project-URL: Repository, https://gitee.com/guolei19850528/py_tiehu.git
30
+ Keywords: tiehu,python,client,api,铁虎,停车场
31
+ Classifier: License :: OSI Approved :: MIT License
32
+ Classifier: Development Status :: 4 - Beta
33
+ Classifier: Intended Audience :: Developers
34
+ Classifier: Programming Language :: Python :: 3
35
+ Classifier: Programming Language :: Python :: 3.10
36
+ Classifier: Programming Language :: Python :: 3.11
37
+ Classifier: Programming Language :: Python :: 3.12
38
+ Classifier: Programming Language :: Python :: 3.13
39
+ Classifier: Operating System :: OS Independent
40
+ Requires-Python: >=3.10
41
+ Description-Content-Type: text/markdown
42
+ License-File: LICENSE
43
+ Requires-Dist: httpx>=0.27.0
44
+ Requires-Dist: pydantic>=2.0
45
+ Requires-Dist: jsonpath-ng>=1.5.3
46
+ Requires-Dist: jsonschema>=4.21.0
47
+ Provides-Extra: dev
48
+ Requires-Dist: pytest>=7.0; extra == "dev"
49
+ Requires-Dist: pytest-cov>=4.0; extra == "dev"
50
+ Requires-Dist: setuptools>=61.0; extra == "dev"
51
+ Requires-Dist: twine>=4.0; extra == "dev"
52
+ Dynamic: license-file
53
+
54
+ # PyTiehu - 铁虎停车场 API Python SDK
55
+
56
+ [![Python Version](https://img.shields.io/badge/python-3.8%2B-blue.svg)](https://python.org)
57
+ [![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
58
+
59
+ PyTiehu 是铁虎停车场管理系统的 Python SDK,提供同步和异步两种调用方式,实现完整的请求签名机制,用于与铁虎停车场管理系统进行
60
+ API 交互。
61
+
62
+ ## 功能特性
63
+
64
+ - ✅ 自动生成请求签名(MD5 算法)
65
+ - ✅ 支持同步/异步 HTTP 请求
66
+ - ✅ 自动添加公共请求参数(parkingId、timestamp、sign)
67
+ - ✅ 灵活的客户端配置选项
68
+ - ✅ Pydantic 响应模型支持
69
+
70
+ ## 安装
71
+
72
+ ```bash
73
+ pip install py_tiehu
74
+ ```
75
+
76
+ ## 快速开始
77
+
78
+ ### 同步客户端
79
+
80
+ ```python
81
+ from py_tiehu import Pklot
82
+
83
+ # 初始化客户端
84
+ client = Pklot(
85
+ base_url="https://isc.example.com",
86
+ parking_id="park001",
87
+ app_key="your_app_secret"
88
+ )
89
+
90
+ # 发送请求
91
+ response = client.request(
92
+ url="/api/v1/parking/query",
93
+ json={"plateNo": "京A12345"}
94
+ )
95
+
96
+ # 处理响应
97
+ print(response.json())
98
+ ```
99
+
100
+ ### 异步客户端
101
+
102
+ ```python
103
+ import asyncio
104
+ from py_tiehu import Pklot
105
+
106
+ # 初始化客户端
107
+ client = Pklot(
108
+ base_url="https://isc.example.com",
109
+ parking_id="park001",
110
+ app_key="your_app_secret"
111
+ )
112
+
113
+
114
+ # 异步发送请求
115
+ async def main():
116
+ response = await client.async_request(
117
+ url="/api/v1/parking/query",
118
+ json={"plateNo": "京A12345"}
119
+ )
120
+ print(response.json())
121
+
122
+
123
+ asyncio.run(main())
124
+ ```
125
+
126
+ ## API 文档
127
+
128
+ ### Pklot 类
129
+
130
+ #### 初始化参数
131
+
132
+ | 参数 | 类型 | 必填 | 说明 |
133
+ |-----------------|------|----|--------------------------|
134
+ | `base_url` | str | 是 | 停车场管理系统服务器基础 URL |
135
+ | `parking_id` | str | 是 | 停车场 ID |
136
+ | `app_key` | str | 是 | 应用密钥,用于生成请求签名 |
137
+ | `client_kwargs` | dict | 否 | 传递给 httpx.Client 的额外配置参数 |
138
+
139
+ #### 方法
140
+
141
+ | 方法 | 说明 | 返回值 |
142
+ |---------------------------|---------------|---------------------|
143
+ | `client()` | 创建同步 HTTP 客户端 | `httpx.Client` |
144
+ | `async_client()` | 创建异步 HTTP 客户端 | `httpx.AsyncClient` |
145
+ | `signature(data)` | 生成请求签名 | `str` |
146
+ | `request(**kwargs)` | 发送同步请求 | `httpx.Response` |
147
+ | `async_request(**kwargs)` | 发送异步请求 | `httpx.Response` |
148
+
149
+ ### 签名算法
150
+
151
+ 签名生成步骤:
152
+
153
+ 1. 排除数据中的 `appKey` 字段
154
+ 2. 对剩余字段按键名进行升序排序
155
+ 3. 将排序后的字段以 `key=value` 格式用 `&` 连接
156
+ 4. 尾部拼接 `appKey` 的 MD5 值(大写)
157
+ 5. 对拼接后的完整字符串进行 MD5 计算并转为大写
158
+
159
+ ### 工具函数
160
+
161
+ #### `timestamp()`
162
+
163
+ 生成当前时间戳(毫秒)
164
+
165
+ ```python
166
+ from py_tiehu.utils import timestamp
167
+
168
+ ts = timestamp() # 输出示例: 1630000000000
169
+ ```
170
+
171
+ #### `json_find_first(expression, data)`
172
+
173
+ 使用 JSONPath 表达式从数据中查找第一个匹配项
174
+
175
+ ```python
176
+ from py_tiehu.utils import json_find_first
177
+
178
+ result = json_find_first("$.data[0].name", response.json())
179
+ ```
180
+
181
+ #### `convert_to_status_eq_1(response)`
182
+
183
+ 将 HTTP 响应或字典转换为 STATUS_EQ_1 模型对象
184
+
185
+ ```python
186
+ from py_tiehu.utils import convert_to_status_eq_1
187
+
188
+ result = convert_to_status_eq_1(response)
189
+ print(result.status) # 1
190
+ print(result.Data) # 响应数据
191
+ ```
192
+
193
+ ## 响应模型
194
+
195
+ ### Base
196
+
197
+ 所有 API 响应的基类:
198
+
199
+ ```python
200
+ class Base(BaseModel):
201
+ status: Union[int, str] # 错误码,1表示成功,非1表示失败
202
+ message: Optional[str] # 错误信息描述
203
+ ```
204
+
205
+ ### STATUS_EQ_1
206
+
207
+ 成功响应模型:
208
+
209
+ ```python
210
+ class STATUS_EQ_1(Base):
211
+ status: Literal[1, "1"] # 成功,值为1
212
+ Data: Any # 成功响应数据
213
+ ```
214
+
215
+ ## 配置说明
216
+
217
+ ### 默认配置
218
+
219
+ ```python
220
+ {
221
+ "base_url": "<your_base_url>",
222
+ "verify": False, # 禁用 SSL 证书验证
223
+ "timeout": 120 # 超时时间 120 秒
224
+ }
225
+ ```
226
+
227
+ ### 自定义配置
228
+
229
+ ```python
230
+ client = Pklot(
231
+ base_url="https://isc.example.com",
232
+ parking_id="park001",
233
+ app_key="your_app_secret",
234
+ client_kwargs={
235
+ "timeout": 60,
236
+ "verify": True,
237
+ "headers": {"X-Custom": "value"}
238
+ }
239
+ )
240
+ ```
241
+
242
+ ## 示例
243
+
244
+ ### 查询车辆信息
245
+
246
+ ```python
247
+ response = client.request(
248
+ url="/api/v1/vehicle/query",
249
+ json={
250
+ "plateNo": "京A12345",
251
+ "parkingId": "park001"
252
+ }
253
+ )
254
+ ```
255
+
256
+ ### 批量查询
257
+
258
+ ```python
259
+ response = client.request(
260
+ url="/api/v1/vehicle/batch",
261
+ json={
262
+ "plateNos": ["京A12345", "京B67890"],
263
+ "pageIndex": 1,
264
+ "pageSize": 20
265
+ }
266
+ )
267
+ ```
268
+
269
+ ## 主页
270
+
271
+ [https://gitee.com/guolei19850528/py_tiehu](https://gitee.com/guolei19850528/py_tiehu)
272
+
273
+ ## 许可证
274
+
275
+ MIT License
276
+
277
+ ## 开发
@@ -0,0 +1,11 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ src/py_tiehu/__init__.py
5
+ src/py_tiehu/responses.py
6
+ src/py_tiehu/utils.py
7
+ src/py_tiehu.egg-info/PKG-INFO
8
+ src/py_tiehu.egg-info/SOURCES.txt
9
+ src/py_tiehu.egg-info/dependency_links.txt
10
+ src/py_tiehu.egg-info/requires.txt
11
+ src/py_tiehu.egg-info/top_level.txt
@@ -0,0 +1,10 @@
1
+ httpx>=0.27.0
2
+ pydantic>=2.0
3
+ jsonpath-ng>=1.5.3
4
+ jsonschema>=4.21.0
5
+
6
+ [dev]
7
+ pytest>=7.0
8
+ pytest-cov>=4.0
9
+ setuptools>=61.0
10
+ twine>=4.0
@@ -0,0 +1 @@
1
+ py_tiehu