beso-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.
- beso_sdk_python-0.1.1.dist-info/METADATA +103 -0
- beso_sdk_python-0.1.1.dist-info/RECORD +19 -0
- beso_sdk_python-0.1.1.dist-info/WHEEL +5 -0
- beso_sdk_python-0.1.1.dist-info/top_level.txt +5 -0
- common/JsonUtil.py +21 -0
- common/OpenClient.py +121 -0
- common/RequestType.py +8 -0
- common/RequestTypes.py +6 -0
- common/SignUtil.py +103 -0
- common/__init__.py +0 -0
- model/AuthorizedUrlGetModel.py +13 -0
- model/__init__.py +0 -0
- request/AuthorizedUrlGetRequest.py +20 -0
- request/BaseRequest.py +53 -0
- request/__init__.py +0 -0
- response/BaseResponse.py +23 -0
- response/__init__.py +0 -0
- test/__init__.py +0 -0
- test/test.py +65 -0
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: beso-sdk-python
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: beso aop python api sdk.
|
|
5
|
+
Home-page: https://github.com/yourname/your_package
|
|
6
|
+
Author: even
|
|
7
|
+
Author-email: ywc@besodata.com
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Requires-Python: >=3.10
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
Dynamic: author
|
|
14
|
+
Dynamic: author-email
|
|
15
|
+
Dynamic: classifier
|
|
16
|
+
Dynamic: description
|
|
17
|
+
Dynamic: description-content-type
|
|
18
|
+
Dynamic: home-page
|
|
19
|
+
Dynamic: requires-python
|
|
20
|
+
Dynamic: summary
|
|
21
|
+
|
|
22
|
+
# sdk-python
|
|
23
|
+
|
|
24
|
+
安装必要插件
|
|
25
|
+
|
|
26
|
+
`pip install requests`
|
|
27
|
+
|
|
28
|
+
`pip install rsa`
|
|
29
|
+
|
|
30
|
+
- 调用方式
|
|
31
|
+
|
|
32
|
+
```python
|
|
33
|
+
import unittest
|
|
34
|
+
|
|
35
|
+
from model.AuthorizedUrlGetModel import AuthorizedUrlGetModel
|
|
36
|
+
from request.AuthorizedUrlGetRequest import AuthorizedUrlGetRequest
|
|
37
|
+
from common.OpenClient import OpenClient
|
|
38
|
+
|
|
39
|
+
class MyTestCase(unittest.TestCase):
|
|
40
|
+
# 应用id
|
|
41
|
+
app_id = '20220425968193236755546111'
|
|
42
|
+
# 应用私钥
|
|
43
|
+
private_key = 'MIIEpAIBAAKCAQEAozDnMRJ56noTJ3A6ftfkm+Orqm7jL8A46b4IaShx01p2c+ev3vbvvn6h2/wGn9DEdOVIALeYD1/vj3BbteixrsHNppW9BgoECKCbtyz5JGKlPKFs6duvYvSYQ3uiyXaOtqhk7HKQtl+pKLl8HgxUrsCS1JnCVEf4BSqDV5kkvB39T0NBsSIhE5cvtZ1NNzTRbj/9JrJaxmR88Y042NxwpqXTU1maqJ6V7Tfbg+oOwRjxyUPkNvktUW18f0GesU4x/kSetx4yqK6BN2RdRCBmQbHInqFlkHp4tAmTCT8LjsAkINLAcSrxnCAgaLWXNAWlwbqRt2koP4nezRJBlaZIxQIDAQABAoIBAD+3NE0gnaFDEH9xfiVQPd3vwnLE4McgEhiRLc+BDxAqXd1bNHulhm2mG6Q8fomfhVTuwHInPKOkHXCvud8If3dwC89i326gMnr72lBmqs/eBA3sKQ4VzCCix2BxwVlPhOEkVmNLR90s9GsGIMPKpLWmUq3XatxlTR0XQDjPflxD5noFhvLH24qOiDB2p3LwsXhLIKuSksb3XlJBvFlxe0+MsRfSAA9xpxA9DEWcivyi9paxt9RY0CkXegxoXeL/a0csN9QDL46QUWlx80lMycrtyVbr2cxFrQkbkMe7V6yhF704yTEjs365LkNg4HEKdgtLIceIdlGtlE1M7hzmXHECgYEA+ZMmjweznyi+xyQQJkhz5QXa78TSVGX9Pc/BpBDEYDyh9j+JozFrjA/6hEIj0tECB3Njx4LMzLI2cso3YpdsCkjY6FgMehiRqOiLBRtEaP9Mc+9OsatPXdOeGw9vaw1FVC435sbRuroQRhppAnj+A0frEBRXX3/pOYwf0I6sxG8CgYEAp2RuU5L+O0zUnoYeGdSetA0vnhpovtj/lcvf2DiwP3dC4v67RzVkMk3kLIfCTmoqz/yM7YqB5Hb1siW1aX0d651Vocymg9c6Lc95xbLNobMDSDtgdkPbp5hCjPPjFQAr5EEJUWHdlxBbW7iOu9mI/AUvI/doFgsamlb8LAQ/qAsCgYEAvcWHl1Cq44YO8svYP9Pt1CLMpG7L5AMdOegE/SUGvYq9OMp9dQq6FWl8+x5zsPTejx3NrEIoSinkvwpGbQBo1bUowhtZeWm/MGmKdBqUvSYLU0iPVQfHNLgZy8fD1+niYq02MpPRnCOpBjVEze2EcKg59CMTgPl5NRn4gxRKCJ8CgYBIMDigFClNm5GqF77NdvNGRNV/QnZfr6dxi22qiq//fsg6qo5LZEwkoZDAX3+9X229KnYATxY7V84XmMmGh62qmbx/PYmmG+B8NxiV2MlzbYcB1JGCDzugKDqzHM6WlO9YzW9eSG1Oo4AyqwHrIyI/RWESCrU5pGpBmze/J8noBwKBgQDS2IQkk4B2kh+1ianciEZXua02IJPWBgIY9cztRC0oVlmpsmkpEkaHMphtd0HDst6FTY6+NLMdJobgQ6/HGqCErUaMvNx0fFKZft5RNJtnBTlgS3KHPuT6c2nIBpoilI8ufysHIcJFUNu9p3DZDkg74K1c9tkggv3LKYAVvlO87g=='
|
|
44
|
+
# 请求URL
|
|
45
|
+
url = 'https://besodata.com/geteway'
|
|
46
|
+
# 创建请求客户端
|
|
47
|
+
client = OpenClient(app_id, private_key, url)
|
|
48
|
+
|
|
49
|
+
def test_api(self):
|
|
50
|
+
# 创建请求
|
|
51
|
+
request = AuthorizedUrlGetRequest()
|
|
52
|
+
# 请求参数
|
|
53
|
+
model = AuthorizedUrlGetModel()
|
|
54
|
+
model.callbackUrl = 'https://www.baidu.com/api/callback'
|
|
55
|
+
model.orderSn = 'D187880489922123123'
|
|
56
|
+
model.creditCode = '912101243132454713'
|
|
57
|
+
model.returnUrl = 'https://juejin.cn/'
|
|
58
|
+
model.tenantCode = 'gzsyb'
|
|
59
|
+
model.userAccount = 'apiUser'
|
|
60
|
+
model.areaName = '辽宁'
|
|
61
|
+
# model.entName = '沈阳兴佳农业开发有限公司'
|
|
62
|
+
# 添加请求参数
|
|
63
|
+
request.biz_model = model
|
|
64
|
+
|
|
65
|
+
# 添加上传文件
|
|
66
|
+
# files = {
|
|
67
|
+
# 'file1': open('aa.txt', 'rb'),
|
|
68
|
+
# 'file2': open('bb.txt', 'rb')
|
|
69
|
+
# }
|
|
70
|
+
# request.files = files
|
|
71
|
+
|
|
72
|
+
# 调用请求
|
|
73
|
+
response = self.client.execute(request)
|
|
74
|
+
|
|
75
|
+
# 关闭文件
|
|
76
|
+
# for f in files.values():
|
|
77
|
+
# f.close()
|
|
78
|
+
|
|
79
|
+
if response.get('code') == '10000':
|
|
80
|
+
print('请求成功=>response: ', response)
|
|
81
|
+
else:
|
|
82
|
+
print('请求失败=>response: ', response)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
if __name__ == '__main__':
|
|
86
|
+
unittest.main()
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
代码规范:
|
|
90
|
+
|
|
91
|
+
| Type | Public | Internal |
|
|
92
|
+
| -------------------------- | ------------------ | ----------------------------------------------------------------- |
|
|
93
|
+
| Modules | lower_with_under | _lower_with_under |
|
|
94
|
+
| Packages | lower_with_under | |
|
|
95
|
+
| Classes | CapWords | _CapWords |
|
|
96
|
+
| Exceptions | CapWords | |
|
|
97
|
+
| Functions | lower_with_under() | _lower_with_under() |
|
|
98
|
+
| Global/Class Constants | CAPS_WITH_UNDER | _CAPS_WITH_UNDER |
|
|
99
|
+
| Global/Class Variables | lower_with_under | _lower_with_under |
|
|
100
|
+
| Instance Variables | lower_with_under | _lower_with_under (protected) or __lower_with_under (private) |
|
|
101
|
+
| Method Names | lower_with_under() | _lower_with_under() (protected) or __lower_with_under() (private) |
|
|
102
|
+
| Function/Method Parameters | lower_with_under | |
|
|
103
|
+
| Local Variables | lower_with_under |
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
common/JsonUtil.py,sha256=uuG7eSUA70u90eW2cbziM8URTIhjcJm9IaI1NQ9_hy8,355
|
|
2
|
+
common/OpenClient.py,sha256=G2i6TH4ED0VGQcYinsXjdvjaKmn-mbYllSN-vbivlkM,3835
|
|
3
|
+
common/RequestType.py,sha256=i6P6pPrH7tZOj6y0pmyUMoEL0-Soj_DBjKaLioyBV4k,101
|
|
4
|
+
common/RequestTypes.py,sha256=_wgg1xLvu8dqP_SJapXBV08QoLQQMH0fJA6x7A1gIR4,144
|
|
5
|
+
common/SignUtil.py,sha256=147j1A2lL__Ojmlg6-brmhrRlM3ePv78Oq9iTtk5z5Q,2953
|
|
6
|
+
common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
|
+
model/AuthorizedUrlGetModel.py,sha256=xB50t4rt2JFaxrfxXY9oi6UtPX0SyfAfLPp0SGBL5ac,251
|
|
8
|
+
model/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
|
+
request/AuthorizedUrlGetRequest.py,sha256=9SiooZODWT3ti8ob9PGZhzqzDIYbRhf0ydvy6InnCbY,469
|
|
10
|
+
request/BaseRequest.py,sha256=flFkGn6j_NSCIA0EZsv7gz5x1bTV1jz71teVnVivCEA,1192
|
|
11
|
+
request/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
12
|
+
response/BaseResponse.py,sha256=kA9lllFOPR_7sxsMmvQke_POB7Cd6BfNU87K7NE9Go4,466
|
|
13
|
+
response/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
14
|
+
test/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
|
+
test/test.py,sha256=rcYT7EWIUxbgVSCDQKt89WT7hjwr6mOE42VYotGIYao,3569
|
|
16
|
+
beso_sdk_python-0.1.1.dist-info/METADATA,sha256=PXAFKhWteVFMFTWC6-y_81pnjMJUhshXsxxrZagYBac,5552
|
|
17
|
+
beso_sdk_python-0.1.1.dist-info/WHEEL,sha256=YLJXdYXQ2FQ0Uqn2J-6iEIC-3iOey8lH3xCtvFLkd8Q,91
|
|
18
|
+
beso_sdk_python-0.1.1.dist-info/top_level.txt,sha256=DM_jJFoWryHTsSuiwjMzIRJ2IDT49pV_T6Exn20OrTw,35
|
|
19
|
+
beso_sdk_python-0.1.1.dist-info/RECORD,,
|
common/JsonUtil.py
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#!/usr/bin/python
|
|
2
|
+
# -*- coding: UTF-8 -*-
|
|
3
|
+
|
|
4
|
+
import json
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def to_json_string(obj):
|
|
8
|
+
"""将对象转换成json字符串
|
|
9
|
+
|
|
10
|
+
:param obj: 对象
|
|
11
|
+
:type obj: object
|
|
12
|
+
|
|
13
|
+
:return: 返回json
|
|
14
|
+
:rtype: str
|
|
15
|
+
"""
|
|
16
|
+
if isinstance(obj, dict):
|
|
17
|
+
param = obj
|
|
18
|
+
else:
|
|
19
|
+
param = obj.__dict__
|
|
20
|
+
return json.dumps(param, ensure_ascii=False)
|
|
21
|
+
|
common/OpenClient.py
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
#!/usr/bin/python
|
|
2
|
+
# -*- coding: UTF-8 -*-
|
|
3
|
+
|
|
4
|
+
import json
|
|
5
|
+
import time
|
|
6
|
+
|
|
7
|
+
import requests
|
|
8
|
+
|
|
9
|
+
from common import SignUtil, RequestTypes
|
|
10
|
+
from common.RequestType import RequestType
|
|
11
|
+
|
|
12
|
+
_headers = {'Accept-Encoding': 'identity'}
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class OpenClient:
|
|
16
|
+
"""调用客户端"""
|
|
17
|
+
__app_id = ''
|
|
18
|
+
__private_key = ''
|
|
19
|
+
__url = ''
|
|
20
|
+
|
|
21
|
+
def __init__(self, app_id, private_key, url):
|
|
22
|
+
"""客户端
|
|
23
|
+
|
|
24
|
+
:param app_id: 应用ID
|
|
25
|
+
:type app_id: str
|
|
26
|
+
|
|
27
|
+
:param private_key: 应用私钥
|
|
28
|
+
:type private_key: str
|
|
29
|
+
|
|
30
|
+
:param url: 请求URL
|
|
31
|
+
:type url: str
|
|
32
|
+
"""
|
|
33
|
+
self.__app_id = app_id
|
|
34
|
+
self.__private_key = private_key
|
|
35
|
+
self.__url = url
|
|
36
|
+
|
|
37
|
+
def execute(self, request, token=None):
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
:param request: 请求对象,BaseRequest的子类
|
|
41
|
+
|
|
42
|
+
:param token: (Optional) token
|
|
43
|
+
:type token: str
|
|
44
|
+
|
|
45
|
+
:return: 返回请求结果
|
|
46
|
+
:rtype: BaseResponse
|
|
47
|
+
"""
|
|
48
|
+
biz_model = request.biz_model
|
|
49
|
+
request_type = request.get_request_type()
|
|
50
|
+
if not isinstance(request_type, RequestType):
|
|
51
|
+
raise Exception('get_request_type返回错误类型,正确方式:RequestTypes.XX')
|
|
52
|
+
|
|
53
|
+
params = biz_model.__dict__
|
|
54
|
+
if request.files is not None:
|
|
55
|
+
response = self._post_file(request, params, token)
|
|
56
|
+
elif request_type == RequestTypes.GET:
|
|
57
|
+
response = self._get(request, params, token)
|
|
58
|
+
elif request_type == RequestTypes.POST_FORM:
|
|
59
|
+
response = self._post_form(request, params, token)
|
|
60
|
+
elif request_type == RequestTypes.POST_JSON:
|
|
61
|
+
response = self._post_json(request, params, token)
|
|
62
|
+
elif request_type == RequestTypes.POST_UPLOAD:
|
|
63
|
+
response = self._post_file(request, params, token)
|
|
64
|
+
else:
|
|
65
|
+
raise Exception('get_request_type设置错误')
|
|
66
|
+
|
|
67
|
+
return self._parse_response(response, request)
|
|
68
|
+
|
|
69
|
+
def _get(self, request, params, token):
|
|
70
|
+
all_params = self._build_params(request, params, token)
|
|
71
|
+
return requests.get(self.__url, all_params, headers=_headers).text
|
|
72
|
+
|
|
73
|
+
def _post_form(self, request, params, token):
|
|
74
|
+
all_params = self._build_params(request, params, token)
|
|
75
|
+
return requests.post(self.__url, data=all_params, headers=_headers).text
|
|
76
|
+
|
|
77
|
+
def _post_json(self, request, params, token):
|
|
78
|
+
all_params = self._build_params(request, params, token)
|
|
79
|
+
return requests.post(self.__url, json=all_params, headers=_headers).text
|
|
80
|
+
|
|
81
|
+
def _post_file(self, request, params, token):
|
|
82
|
+
all_params = self._build_params(request, params, token)
|
|
83
|
+
return requests.request('POST', self.__url, data=all_params, files=request.files, headers=_headers).text
|
|
84
|
+
|
|
85
|
+
def _build_params(self, request, params, token):
|
|
86
|
+
"""构建所有的请求参数
|
|
87
|
+
|
|
88
|
+
:param request: 请求对象
|
|
89
|
+
:type request: request.BaseRequest
|
|
90
|
+
|
|
91
|
+
:param params: 业务请求参数
|
|
92
|
+
:type params: dict
|
|
93
|
+
|
|
94
|
+
:param token: token
|
|
95
|
+
:type token: str
|
|
96
|
+
|
|
97
|
+
:return: 返回请求参数
|
|
98
|
+
:rtype: str
|
|
99
|
+
"""
|
|
100
|
+
all_params = {
|
|
101
|
+
'app_id': self.__app_id,
|
|
102
|
+
'method': request.get_method(),
|
|
103
|
+
'charset': 'UTF-8',
|
|
104
|
+
'format': 'json',
|
|
105
|
+
'sign_type': 'RSA2',
|
|
106
|
+
'timestamp': time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()),
|
|
107
|
+
'version': request.get_version(),
|
|
108
|
+
'biz_content': json.dumps(params)
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if token is not None:
|
|
112
|
+
all_params['access_token'] = token
|
|
113
|
+
|
|
114
|
+
# 构建sign
|
|
115
|
+
sign = SignUtil.create_sign(all_params, self.__private_key, 'RSA2')
|
|
116
|
+
all_params['sign'] = sign
|
|
117
|
+
return all_params
|
|
118
|
+
|
|
119
|
+
def _parse_response(self, resp, request):
|
|
120
|
+
response_dict = json.loads(resp)
|
|
121
|
+
return request.parse_response(response_dict)
|
common/RequestType.py
ADDED
common/RequestTypes.py
ADDED
common/SignUtil.py
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
#!/usr/bin/python
|
|
2
|
+
# -*- coding: UTF-8 -*-
|
|
3
|
+
import rsa
|
|
4
|
+
import base64
|
|
5
|
+
|
|
6
|
+
__pem_begin = '-----BEGIN RSA PRIVATE KEY-----\n'
|
|
7
|
+
__pem_end = '\n-----END RSA PRIVATE KEY-----'
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def create_sign(all_params, private_key, sign_type):
|
|
11
|
+
"""创建签名
|
|
12
|
+
|
|
13
|
+
:param all_params: 参数
|
|
14
|
+
:type all_params: dict
|
|
15
|
+
|
|
16
|
+
:param private_key: 私钥字符串
|
|
17
|
+
:type private_key: str
|
|
18
|
+
|
|
19
|
+
:param sign_type: 签名类型,'RSA', 'RSA2'二选一
|
|
20
|
+
:type sign_type: str
|
|
21
|
+
|
|
22
|
+
:return: 返回签名内容
|
|
23
|
+
:rtype: str
|
|
24
|
+
"""
|
|
25
|
+
sign_content = get_sign_content(all_params)
|
|
26
|
+
private_key = _format_private_key(private_key)
|
|
27
|
+
return sign(sign_content, private_key, sign_type)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def _format_private_key(private_key):
|
|
31
|
+
if not private_key.startswith(__pem_begin):
|
|
32
|
+
private_key = __pem_begin + private_key
|
|
33
|
+
if not private_key.endswith(__pem_end):
|
|
34
|
+
private_key = private_key + __pem_end
|
|
35
|
+
return private_key
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def get_sign_content(params):
|
|
39
|
+
"""构建签名内容
|
|
40
|
+
|
|
41
|
+
1.筛选并排序
|
|
42
|
+
获取所有请求参数,不包括字节类型参数,如文件、字节流,剔除sign字段,剔除值为空的参数,并按照参数名ASCII码递增排序(字母升序排序),
|
|
43
|
+
如果遇到相同字符则按照第二个字符的键值ASCII码递增排序,以此类推。
|
|
44
|
+
|
|
45
|
+
2.拼接
|
|
46
|
+
将排序后的参数与其对应值,组合成“参数=参数值”的格式,并且把这些参数用&字符连接起来,此时生成的字符串为待签名字符串。
|
|
47
|
+
|
|
48
|
+
:param params: 参数
|
|
49
|
+
:type params: dict
|
|
50
|
+
|
|
51
|
+
:return: 返回签名内容
|
|
52
|
+
:rtype: str
|
|
53
|
+
"""
|
|
54
|
+
result = []
|
|
55
|
+
for key in sorted(params):
|
|
56
|
+
value = str(params.get(key))
|
|
57
|
+
if len(value) > 0:
|
|
58
|
+
result.append(key + '=' + value)
|
|
59
|
+
|
|
60
|
+
return '&'.join(result)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def sign(content, private_key, sign_type):
|
|
64
|
+
"""签名
|
|
65
|
+
|
|
66
|
+
:param content: 签名内容
|
|
67
|
+
:type content: str
|
|
68
|
+
|
|
69
|
+
:param private_key: 私钥字符串
|
|
70
|
+
:type private_key: str
|
|
71
|
+
|
|
72
|
+
:param sign_type: 签名类型,'RSA', 'RSA2'二选一
|
|
73
|
+
:type sign_type: str
|
|
74
|
+
|
|
75
|
+
:return: 返回签名内容
|
|
76
|
+
:rtype: str
|
|
77
|
+
"""
|
|
78
|
+
if sign_type.upper() == 'RSA':
|
|
79
|
+
return rsa_sign(content, private_key, 'SHA-1')
|
|
80
|
+
elif sign_type.upper() == 'RSA2':
|
|
81
|
+
return rsa_sign(content, private_key, 'SHA-256')
|
|
82
|
+
else:
|
|
83
|
+
raise Exception('sign_type错误')
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def rsa_sign(content, private_key, _hash):
|
|
87
|
+
"""SHAWithRSA
|
|
88
|
+
|
|
89
|
+
:param content: 签名内容
|
|
90
|
+
:type content: str
|
|
91
|
+
|
|
92
|
+
:param private_key: 私钥
|
|
93
|
+
:type private_key: str
|
|
94
|
+
|
|
95
|
+
:param _hash: hash算法,如:SHA-1,SHA-256
|
|
96
|
+
:type _hash: str
|
|
97
|
+
|
|
98
|
+
:return: 签名内容
|
|
99
|
+
:rtype: str
|
|
100
|
+
"""
|
|
101
|
+
pri_key = rsa.PrivateKey.load_pkcs1(private_key.encode('utf-8'))
|
|
102
|
+
sign_result = rsa.sign(message=content.encode('utf-8'), priv_key=pri_key, hash_method=_hash)
|
|
103
|
+
return base64.b64encode(sign_result)
|
common/__init__.py
ADDED
|
File without changes
|
model/__init__.py
ADDED
|
File without changes
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#!/usr/bin/python
|
|
2
|
+
# -*- coding: UTF-8 -*-
|
|
3
|
+
from common import RequestTypes
|
|
4
|
+
from request.BaseRequest import BaseRequest
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class AuthorizedUrlGetRequest(BaseRequest):
|
|
8
|
+
"""获取在线授权链接"""
|
|
9
|
+
|
|
10
|
+
def __init__(self):
|
|
11
|
+
BaseRequest.__init__(self)
|
|
12
|
+
|
|
13
|
+
def get_method(self):
|
|
14
|
+
return 'business.getAuthorizedUrl'
|
|
15
|
+
|
|
16
|
+
def get_version(self):
|
|
17
|
+
return '1.0'
|
|
18
|
+
|
|
19
|
+
def get_request_type(self):
|
|
20
|
+
return RequestTypes.POST_FORM
|
request/BaseRequest.py
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
#!/usr/bin/python
|
|
2
|
+
# -*- coding: UTF-8 -*-
|
|
3
|
+
from response.BaseResponse import BaseResponse
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class BaseRequest:
|
|
7
|
+
"""请求类的父类"""
|
|
8
|
+
|
|
9
|
+
biz_model = None
|
|
10
|
+
"""请求参数"""
|
|
11
|
+
|
|
12
|
+
files = None
|
|
13
|
+
"""上传文件"""
|
|
14
|
+
|
|
15
|
+
def __init__(self):
|
|
16
|
+
pass
|
|
17
|
+
|
|
18
|
+
def get_method(self):
|
|
19
|
+
"""返回接口名
|
|
20
|
+
|
|
21
|
+
:return: 返回接口名
|
|
22
|
+
:rtype: str
|
|
23
|
+
"""
|
|
24
|
+
raise Exception('未实现BaseRequest.get_method()方法')
|
|
25
|
+
|
|
26
|
+
def get_version(self):
|
|
27
|
+
"""返回接口版本号
|
|
28
|
+
|
|
29
|
+
:return: 返回版本号,如:1.0
|
|
30
|
+
:rtype: str
|
|
31
|
+
"""
|
|
32
|
+
raise Exception('未实现BaseRequest.get_version()方法')
|
|
33
|
+
|
|
34
|
+
def get_request_type(self):
|
|
35
|
+
"""返回请求类型
|
|
36
|
+
|
|
37
|
+
:return: 返回RequestType类实例
|
|
38
|
+
:rtype: common.RequestType
|
|
39
|
+
"""
|
|
40
|
+
raise Exception('未实现BaseRequest.get_request_type()方法')
|
|
41
|
+
|
|
42
|
+
def parse_response(self, response_dict):
|
|
43
|
+
response_data = response_dict.get('error_response')
|
|
44
|
+
if response_data is None:
|
|
45
|
+
data_name = self.get_method().replace('.', '_') + '_response'
|
|
46
|
+
response_data = response_dict.get(data_name)
|
|
47
|
+
return response_data
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
|
request/__init__.py
ADDED
|
File without changes
|
response/BaseResponse.py
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
#!/usr/bin/python
|
|
2
|
+
# -*- coding: UTF-8 -*-
|
|
3
|
+
from collections import UserDict
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class BaseResponse(UserDict):
|
|
7
|
+
"""返回类"""
|
|
8
|
+
request_id = None
|
|
9
|
+
code = None
|
|
10
|
+
msg = None
|
|
11
|
+
sub_code = None
|
|
12
|
+
sub_msg = None
|
|
13
|
+
|
|
14
|
+
def __init__(self, _dict=None, **kwargs):
|
|
15
|
+
UserDict.__init__(self, _dict, **kwargs)
|
|
16
|
+
|
|
17
|
+
def is_success(self):
|
|
18
|
+
"""是否成功
|
|
19
|
+
|
|
20
|
+
:return: True,成功
|
|
21
|
+
:rtype: bool
|
|
22
|
+
"""
|
|
23
|
+
return self.sub_code is None
|
response/__init__.py
ADDED
|
File without changes
|
test/__init__.py
ADDED
|
File without changes
|
test/test.py
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
#!/usr/bin/python
|
|
2
|
+
# -*- coding: UTF-8 -*-
|
|
3
|
+
import unittest
|
|
4
|
+
|
|
5
|
+
from model.AuthorizedUrlGetModel import AuthorizedUrlGetModel
|
|
6
|
+
from request.AuthorizedUrlGetRequest import AuthorizedUrlGetRequest
|
|
7
|
+
from common.OpenClient import OpenClient
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class MyTestCase(unittest.TestCase):
|
|
11
|
+
# 应用id
|
|
12
|
+
app_id = '20220425968193236755546112'
|
|
13
|
+
# 应用私钥
|
|
14
|
+
private_key = 'MIIEpAIBAAKCAQEAozDnMRJ56noTJ3A6ftfkm+Orqm7jL8A46b4IaShx01p2c+ev3vbvvn6h2/wGn9DEdOVIALeYD1/vj3BbteixrsHNppW9BgoECKCbtyz5JGKlPKFs6duvYvSYQ3uiyXaOtqhk7HKQtl+pKLl8HgxUrsCS1JnCVEf4BSqDV5kkvB39T0NBsSIhE5cvtZ1NNzTRbj/9JrJaxmR88Y042NxwpqXTU1maqJ6V7Tfbg+oOwRjxyUPkNvktUW18f0GesU4x/kSetx4yqK6BN2RdRCBmQbHInqFlkHp4tAmTCT8LjsAkINLAcSrxnCAgaLWXNAWlwbqRt2koP4nezRJBlaZIxQIDAQABAoIBAD+3NE0gnaFDEH9xfiVQPd3vwnLE4McgEhiRLc+BDxAqXd1bNHulhm2mG6Q8fomfhVTuwHInPKOkHXCvud8If3dwC89i326gMnr72lBmqs/eBA3sKQ4VzCCix2BxwVlPhOEkVmNLR90s9GsGIMPKpLWmUq3XatxlTR0XQDjPflxD5noFhvLH24qOiDB2p3LwsXhLIKuSksb3XlJBvFlxe0+MsRfSAA9xpxA9DEWcivyi9paxt9RY0CkXegxoXeL/a0csN9QDL46QUWlx80lMycrtyVbr2cxFrQkbkMe7V6yhF704yTEjs365LkNg4HEKdgtLIceIdlGtlE1M7hzmXHECgYEA+ZMmjweznyi+xyQQJkhz5QXa78TSVGX9Pc/BpBDEYDyh9j+JozFrjA/6hEIj0tECB3Njx4LMzLI2cso3YpdsCkjY6FgMehiRqOiLBRtEaP9Mc+9OsatPXdOeGw9vaw1FVC435sbRuroQRhppAnj+A0frEBRXX3/pOYwf0I6sxG8CgYEAp2RuU5L+O0zUnoYeGdSetA0vnhpovtj/lcvf2DiwP3dC4v67RzVkMk3kLIfCTmoqz/yM7YqB5Hb1siW1aX0d651Vocymg9c6Lc95xbLNobMDSDtgdkPbp5hCjPPjFQAr5EEJUWHdlxBbW7iOu9mI/AUvI/doFgsamlb8LAQ/qAsCgYEAvcWHl1Cq44YO8svYP9Pt1CLMpG7L5AMdOegE/SUGvYq9OMp9dQq6FWl8+x5zsPTejx3NrEIoSinkvwpGbQBo1bUowhtZeWm/MGmKdBqUvSYLU0iPVQfHNLgZy8fD1+niYq02MpPRnCOpBjVEze2EcKg59CMTgPl5NRn4gxRKCJ8CgYBIMDigFClNm5GqF77NdvNGRNV/QnZfr6dxi22qiq//fsg6qo5LZEwkoZDAX3+9X229KnYATxY7V84XmMmGh62qmbx/PYmmG+B8NxiV2MlzbYcB1JGCDzugKDqzHM6WlO9YzW9eSG1Oo4AyqwHrIyI/RWESCrU5pGpBmze/J8noBwKBgQDS2IQkk4B2kh+1ianciEZXua02IJPWBgIY9cztRC0oVlmpsmkpEkaHMphtd0HDst6FTY6+NLMdJobgQ6/HGqCErUaMvNx0fFKZft5RNJtnBTlgS3KHPuT6c2nIBpoilI8ufysHIcJFUNu9p3DZDkg74K1c9tkggv3LKYAVvlO87g=='
|
|
15
|
+
# 请求URL
|
|
16
|
+
url = 'https://besodata.com/geteway'
|
|
17
|
+
# 创建请求客户端
|
|
18
|
+
client = OpenClient(app_id, private_key, url)
|
|
19
|
+
|
|
20
|
+
def test_api(self):
|
|
21
|
+
# 创建请求
|
|
22
|
+
request = AuthorizedUrlGetRequest()
|
|
23
|
+
# 请求参数
|
|
24
|
+
model = AuthorizedUrlGetModel()
|
|
25
|
+
model.callbackUrl = 'https://www.baidu.com/api/callback'
|
|
26
|
+
model.orderSn = 'D187880489922123123'
|
|
27
|
+
model.creditCode = '912101243132454713'
|
|
28
|
+
model.returnUrl = 'https://juejin.cn/'
|
|
29
|
+
model.tenantCode = 'gzsyb'
|
|
30
|
+
model.userAccount = 'apiUser'
|
|
31
|
+
model.areaName = '辽宁'
|
|
32
|
+
# model.entName = '沈阳兴佳农业开发有限公司'
|
|
33
|
+
# 添加请求参数
|
|
34
|
+
request.biz_model = model
|
|
35
|
+
|
|
36
|
+
# 添加上传文件
|
|
37
|
+
# files = {
|
|
38
|
+
# 'file1': open('aa.txt', 'rb'),
|
|
39
|
+
# 'file2': open('bb.txt', 'rb')
|
|
40
|
+
# }
|
|
41
|
+
# request.files = files
|
|
42
|
+
|
|
43
|
+
# 调用请求
|
|
44
|
+
response = self.client.execute(request)
|
|
45
|
+
|
|
46
|
+
# 关闭文件
|
|
47
|
+
# for f in files.values():
|
|
48
|
+
# f.close()
|
|
49
|
+
|
|
50
|
+
if response.get('code') == '10000':
|
|
51
|
+
print('请求成功=>response: ', response)
|
|
52
|
+
else:
|
|
53
|
+
print('请求失败=>response: ', response)
|
|
54
|
+
|
|
55
|
+
# def test_to_json_string(self):
|
|
56
|
+
# model = MemberInfoGetModel()
|
|
57
|
+
# model.age = 1
|
|
58
|
+
# model.name = '张三'
|
|
59
|
+
# model.address = 'xx'
|
|
60
|
+
# json_string = JsonUtil.to_json_string(model)
|
|
61
|
+
# print('json:', json_string)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
if __name__ == '__main__':
|
|
65
|
+
unittest.main()
|