re-common 10.0.22__py3-none-any.whl → 10.0.24__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.
- re_common/baselibrary/__init__.py +4 -4
- re_common/baselibrary/baseabs/__init__.py +6 -6
- re_common/baselibrary/baseabs/baseabs.py +26 -26
- re_common/baselibrary/database/mbuilder.py +132 -132
- re_common/baselibrary/database/moudle.py +93 -93
- re_common/baselibrary/database/msqlite3.py +194 -194
- re_common/baselibrary/database/mysql.py +169 -169
- re_common/baselibrary/database/sql_factory.py +26 -26
- re_common/baselibrary/mthread/MThreadingRun.py +486 -486
- re_common/baselibrary/mthread/MThreadingRunEvent.py +349 -349
- re_common/baselibrary/mthread/__init__.py +2 -2
- re_common/baselibrary/mthread/mythreading.py +695 -695
- re_common/baselibrary/pakge_other/socks.py +404 -404
- re_common/baselibrary/readconfig/config_factory.py +18 -18
- re_common/baselibrary/readconfig/ini_config.py +317 -317
- re_common/baselibrary/readconfig/toml_config.py +49 -49
- re_common/baselibrary/temporary/envdata.py +36 -36
- re_common/baselibrary/tools/all_requests/aiohttp_request.py +118 -118
- re_common/baselibrary/tools/all_requests/httpx_requet.py +102 -102
- re_common/baselibrary/tools/all_requests/mrequest.py +412 -412
- re_common/baselibrary/tools/all_requests/requests_request.py +81 -81
- re_common/baselibrary/tools/batch_compre/bijiao_batch.py +31 -31
- re_common/baselibrary/tools/contrast_db3.py +123 -123
- re_common/baselibrary/tools/copy_file.py +39 -39
- re_common/baselibrary/tools/db3_2_sizedb3.py +102 -102
- re_common/baselibrary/tools/foreachgz.py +39 -39
- re_common/baselibrary/tools/get_attr.py +10 -10
- re_common/baselibrary/tools/image_to_pdf.py +61 -61
- re_common/baselibrary/tools/java_code_deal.py +139 -139
- re_common/baselibrary/tools/javacode.py +79 -79
- re_common/baselibrary/tools/mdb_db3.py +48 -48
- re_common/baselibrary/tools/merge_file.py +171 -171
- re_common/baselibrary/tools/merge_gz_file.py +165 -165
- re_common/baselibrary/tools/mhdfstools/down_hdfs_files.py +42 -42
- re_common/baselibrary/tools/mhdfstools/hdfst.py +42 -42
- re_common/baselibrary/tools/mhdfstools/up_hdfs_files.py +38 -38
- re_common/baselibrary/tools/mongo_tools.py +50 -50
- re_common/baselibrary/tools/move_file.py +170 -170
- re_common/baselibrary/tools/move_mongo/mongo_table_to_file.py +63 -63
- re_common/baselibrary/tools/move_mongo/move_mongo_table.py +354 -354
- re_common/baselibrary/tools/move_mongo/use_mttf.py +18 -18
- re_common/baselibrary/tools/move_mongo/use_mv.py +93 -93
- re_common/baselibrary/tools/mpandas/mpandasreadexcel.py +125 -125
- re_common/baselibrary/tools/mpandas/pandas_visualization.py +7 -7
- re_common/baselibrary/tools/myparsel.py +104 -104
- re_common/baselibrary/tools/rename_dir_file.py +37 -37
- re_common/baselibrary/tools/sequoiadb_utils.py +398 -398
- re_common/baselibrary/tools/split_line_to_many.py +25 -25
- re_common/baselibrary/tools/stringtodicts.py +33 -33
- re_common/baselibrary/tools/workwechant_bot.py +84 -84
- re_common/baselibrary/utils/baseaiohttp.py +296 -296
- re_common/baselibrary/utils/baseaiomysql.py +87 -87
- re_common/baselibrary/utils/baseallstep.py +191 -191
- re_common/baselibrary/utils/baseavro.py +19 -19
- re_common/baselibrary/utils/baseboto3.py +291 -291
- re_common/baselibrary/utils/basecsv.py +32 -32
- re_common/baselibrary/utils/basedict.py +133 -133
- re_common/baselibrary/utils/basedir.py +241 -241
- re_common/baselibrary/utils/baseencode.py +351 -351
- re_common/baselibrary/utils/baseencoding.py +28 -28
- re_common/baselibrary/utils/baseesdsl.py +86 -86
- re_common/baselibrary/utils/baseexcel.py +264 -264
- re_common/baselibrary/utils/baseexcept.py +109 -109
- re_common/baselibrary/utils/basefile.py +654 -654
- re_common/baselibrary/utils/baseftp.py +214 -214
- re_common/baselibrary/utils/basegzip.py +60 -60
- re_common/baselibrary/utils/basehdfs.py +135 -135
- re_common/baselibrary/utils/basehttpx.py +268 -268
- re_common/baselibrary/utils/baseip.py +87 -87
- re_common/baselibrary/utils/basejson.py +2 -2
- re_common/baselibrary/utils/baselist.py +32 -32
- re_common/baselibrary/utils/basemotor.py +190 -190
- re_common/baselibrary/utils/basemssql.py +98 -98
- re_common/baselibrary/utils/baseodbc.py +113 -113
- re_common/baselibrary/utils/basepandas.py +302 -302
- re_common/baselibrary/utils/basepeewee.py +11 -11
- re_common/baselibrary/utils/basepika.py +180 -180
- re_common/baselibrary/utils/basepydash.py +143 -143
- re_common/baselibrary/utils/basepymongo.py +230 -230
- re_common/baselibrary/utils/basequeue.py +22 -22
- re_common/baselibrary/utils/baserar.py +57 -57
- re_common/baselibrary/utils/baserequest.py +279 -279
- re_common/baselibrary/utils/baseset.py +8 -8
- re_common/baselibrary/utils/basesmb.py +403 -403
- re_common/baselibrary/utils/basestring.py +382 -382
- re_common/baselibrary/utils/basetime.py +320 -320
- re_common/baselibrary/utils/baseurl.py +121 -121
- re_common/baselibrary/utils/basezip.py +57 -57
- re_common/baselibrary/utils/core/__init__.py +7 -7
- re_common/baselibrary/utils/core/bottomutils.py +18 -18
- re_common/baselibrary/utils/core/mdeprecated.py +327 -327
- re_common/baselibrary/utils/core/mlamada.py +16 -16
- re_common/baselibrary/utils/core/msginfo.py +25 -25
- re_common/baselibrary/utils/core/requests_core.py +103 -103
- re_common/baselibrary/utils/fateadm.py +429 -429
- re_common/baselibrary/utils/importfun.py +123 -123
- re_common/baselibrary/utils/mfaker.py +57 -57
- re_common/baselibrary/utils/my_abc/__init__.py +3 -3
- re_common/baselibrary/utils/my_abc/better_abc.py +32 -32
- re_common/baselibrary/utils/mylogger.py +414 -414
- re_common/baselibrary/utils/myredisclient.py +861 -861
- re_common/baselibrary/utils/pipupgrade.py +21 -21
- re_common/baselibrary/utils/ringlist.py +85 -85
- re_common/baselibrary/utils/version_compare.py +36 -36
- re_common/baselibrary/utils/ydmhttp.py +126 -126
- re_common/facade/lazy_import.py +11 -11
- re_common/facade/loggerfacade.py +25 -25
- re_common/facade/mysqlfacade.py +467 -467
- re_common/facade/now.py +31 -31
- re_common/facade/sqlite3facade.py +257 -257
- re_common/facade/use/mq_use_facade.py +83 -83
- re_common/facade/use/proxy_use_facade.py +19 -19
- re_common/libtest/base_dict_test.py +19 -19
- re_common/libtest/baseavro_test.py +13 -13
- re_common/libtest/basefile_test.py +14 -14
- re_common/libtest/basemssql_test.py +77 -77
- re_common/libtest/baseodbc_test.py +7 -7
- re_common/libtest/basepandas_test.py +38 -38
- re_common/libtest/get_attr_test/get_attr_test_settings.py +14 -14
- re_common/libtest/get_attr_test/settings.py +54 -54
- re_common/libtest/idencode_test.py +53 -53
- re_common/libtest/iniconfig_test.py +35 -35
- re_common/libtest/ip_test.py +34 -34
- re_common/libtest/merge_file_test.py +20 -20
- re_common/libtest/mfaker_test.py +8 -8
- re_common/libtest/mm3_test.py +31 -31
- re_common/libtest/mylogger_test.py +88 -88
- re_common/libtest/myparsel_test.py +27 -27
- re_common/libtest/mysql_test.py +151 -151
- re_common/libtest/pymongo_test.py +21 -21
- re_common/libtest/split_test.py +11 -11
- re_common/libtest/sqlite3_merge_test.py +5 -5
- re_common/libtest/sqlite3_test.py +34 -34
- re_common/libtest/tomlconfig_test.py +30 -30
- re_common/libtest/use_tools_test/__init__.py +2 -2
- re_common/libtest/user/__init__.py +4 -4
- re_common/studio/__init__.py +4 -4
- re_common/studio/assignment_expressions.py +36 -36
- re_common/studio/mydash/test1.py +18 -18
- re_common/studio/pydashstudio/first.py +9 -9
- re_common/studio/streamlitstudio/first_app.py +65 -65
- re_common/studio/streamlitstudio/uber_pickups.py +23 -23
- re_common/studio/test.py +18 -18
- re_common/v2/baselibrary/business_utils/BusinessStringUtil.py +195 -0
- re_common/v2/baselibrary/business_utils/__init__.py +0 -0
- re_common/v2/baselibrary/business_utils/rel_tools.py +6 -0
- re_common/v2/baselibrary/decorators/utils.py +59 -59
- re_common/v2/baselibrary/s3object/baseboto3.py +230 -230
- re_common/v2/baselibrary/tools/WeChatRobot.py +95 -79
- re_common/v2/baselibrary/tools/ac_ahocorasick.py +75 -75
- re_common/v2/baselibrary/tools/dict_tools.py +37 -37
- re_common/v2/baselibrary/tools/dolphinscheduler.py +187 -187
- re_common/v2/baselibrary/tools/hdfs_data_processer.py +338 -338
- re_common/v2/baselibrary/tools/list_tools.py +65 -65
- re_common/v2/baselibrary/tools/search_hash_tools.py +54 -54
- re_common/v2/baselibrary/tools/text_matcher.py +326 -326
- re_common/v2/baselibrary/tools/unionfind_tools.py +60 -60
- re_common/v2/baselibrary/utils/BusinessStringUtil.py +196 -196
- re_common/v2/baselibrary/utils/author_smi.py +360 -360
- re_common/v2/baselibrary/utils/base_string_similarity.py +158 -158
- re_common/v2/baselibrary/utils/basedict.py +37 -37
- re_common/v2/baselibrary/utils/basehdfs.py +161 -161
- re_common/v2/baselibrary/utils/basepika.py +180 -180
- re_common/v2/baselibrary/utils/basetime.py +77 -77
- re_common/v2/baselibrary/utils/db.py +38 -38
- re_common/v2/baselibrary/utils/json_cls.py +16 -16
- re_common/v2/baselibrary/utils/mq.py +83 -83
- re_common/v2/baselibrary/utils/n_ary_expression_tree.py +243 -243
- re_common/v2/baselibrary/utils/string_bool.py +186 -149
- re_common/v2/baselibrary/utils/string_clear.py +227 -204
- re_common/v2/baselibrary/utils/string_smi.py +18 -18
- re_common/v2/baselibrary/utils/stringutils.py +213 -213
- re_common/vip/base_step_process.py +11 -11
- re_common/vip/baseencodeid.py +90 -90
- re_common/vip/changetaskname.py +28 -28
- re_common/vip/core_var.py +24 -24
- re_common/vip/mmh3Hash.py +89 -89
- re_common/vip/proxy/allproxys.py +127 -127
- re_common/vip/proxy/allproxys_thread.py +159 -159
- re_common/vip/proxy/cnki_proxy.py +153 -153
- re_common/vip/proxy/kuaidaili.py +87 -87
- re_common/vip/proxy/proxy_all.py +113 -113
- re_common/vip/proxy/update_kuaidaili_0.py +42 -42
- re_common/vip/proxy/wanfang_proxy.py +152 -152
- re_common/vip/proxy/wp_proxy_all.py +181 -181
- re_common/vip/read_rawid_to_txt.py +91 -91
- re_common/vip/title/__init__.py +5 -5
- re_common/vip/title/transform/TransformBookTitleToZt.py +125 -125
- re_common/vip/title/transform/TransformConferenceTitleToZt.py +139 -139
- re_common/vip/title/transform/TransformCstadTitleToZt.py +195 -195
- re_common/vip/title/transform/TransformJournalTitleToZt.py +203 -203
- re_common/vip/title/transform/TransformPatentTitleToZt.py +132 -132
- re_common/vip/title/transform/TransformRegulationTitleToZt.py +114 -114
- re_common/vip/title/transform/TransformStandardTitleToZt.py +135 -135
- re_common/vip/title/transform/TransformThesisTitleToZt.py +135 -135
- re_common/vip/title/transform/__init__.py +10 -10
- {re_common-10.0.22.dist-info → re_common-10.0.24.dist-info}/LICENSE +201 -201
- {re_common-10.0.22.dist-info → re_common-10.0.24.dist-info}/METADATA +16 -16
- re_common-10.0.24.dist-info/RECORD +230 -0
- {re_common-10.0.22.dist-info → re_common-10.0.24.dist-info}/WHEEL +1 -1
- re_common-10.0.22.dist-info/RECORD +0 -227
- {re_common-10.0.22.dist-info → re_common-10.0.24.dist-info}/top_level.txt +0 -0
|
@@ -1,296 +1,296 @@
|
|
|
1
|
-
import json
|
|
2
|
-
import zlib
|
|
3
|
-
|
|
4
|
-
import aiofiles
|
|
5
|
-
import aiohttp
|
|
6
|
-
from yarl import URL
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class BaseAiohttp():
|
|
10
|
-
|
|
11
|
-
def __init__(self):
|
|
12
|
-
self.session = aiohttp.ClientSession()
|
|
13
|
-
# 用于传递get的参数
|
|
14
|
-
# params = {'key1': 'value1', 'key2': 'value2'}
|
|
15
|
-
# params = [('key', 'value1'), ('key', 'value2')] 同建多值问题
|
|
16
|
-
# params='key=value+1' 您也可以将str内容作为参数传递,但要注意–内容不是由库编码的。
|
|
17
|
-
# 请注意,+未编码
|
|
18
|
-
self.params = {}
|
|
19
|
-
# post json
|
|
20
|
-
self.json = {}
|
|
21
|
-
# post表单数据 {'key1': 'value1', 'key2': 'value2'}
|
|
22
|
-
self.payload = {}
|
|
23
|
-
# 如果您要发送未经格式编码的数据,可以通过传递a bytes而不是a来完成dict。
|
|
24
|
-
# 这些数据将直接发布,并且默认将内容类型设置为“ application / octet-stream”:
|
|
25
|
-
# =b'\x00Binary-data\x00'
|
|
26
|
-
# 要发送具有适当内容类型的文本,只需使用text属性 data='Тест'
|
|
27
|
-
# 要上传多部分编码的文件,请执行以下操作:
|
|
28
|
-
# files = {'file': open('report.xls', 'rb')}
|
|
29
|
-
# 您可以设置filename和content_type:
|
|
30
|
-
# data = FormData()
|
|
31
|
-
# data.add_field('file',
|
|
32
|
-
# open('report.xls', 'rb'),
|
|
33
|
-
# filename='report.xls',
|
|
34
|
-
# content_type='application/vnd.ms-excel')
|
|
35
|
-
# 如果将文件对象作为数据参数传递,则aiohttp会将其自动流式传输到服务器。
|
|
36
|
-
# 检查StreamReader 支持的格式信息。
|
|
37
|
-
self.data = b''
|
|
38
|
-
# headers可以是单个请求的,也可以是会话的
|
|
39
|
-
self.headers = {}
|
|
40
|
-
# {'cookies_are': 'working'}
|
|
41
|
-
self.cookies = {}
|
|
42
|
-
|
|
43
|
-
async def file_sender(self, file_name=None, size=64):
|
|
44
|
-
"""
|
|
45
|
-
async with session.post('http://httpbin.org/post',
|
|
46
|
-
data=file_sender(file_name='huge_file')) as resp:
|
|
47
|
-
print(await resp.text())
|
|
48
|
-
:param file_name:
|
|
49
|
-
:param size:
|
|
50
|
-
:return:
|
|
51
|
-
"""
|
|
52
|
-
async with aiofiles.open(file_name, 'rb') as f:
|
|
53
|
-
chunk = await f.read(size * 1024)
|
|
54
|
-
while chunk:
|
|
55
|
-
yield chunk
|
|
56
|
-
chunk = await f.read(size * 1024)
|
|
57
|
-
|
|
58
|
-
def get_and_send(self):
|
|
59
|
-
"""
|
|
60
|
-
从版本3.1开始不推荐使用:aiohttp仍然支持aiohttp.streamer装饰器,
|
|
61
|
-
但是不推荐使用此方法,而支持异步生成器,如上所示。
|
|
62
|
-
Python 3.5没有对异步生成器的本机支持,请使用 async_generator库作为解决方法。
|
|
63
|
-
因为该content属性是 StreamReader(提供异步迭代器协议),所以您可以将获取和发布请求链接在一起:
|
|
64
|
-
resp = await session.get('http://python.org')
|
|
65
|
-
await session.post('http://httpbin.org/post',
|
|
66
|
-
data=resp.content)
|
|
67
|
-
:return:
|
|
68
|
-
"""
|
|
69
|
-
pass
|
|
70
|
-
|
|
71
|
-
def web_sockets(self, url):
|
|
72
|
-
"""
|
|
73
|
-
|
|
74
|
-
:return:
|
|
75
|
-
"""
|
|
76
|
-
async with self.session.ws_connect(url) as ws:
|
|
77
|
-
async for msg in ws:
|
|
78
|
-
if msg.type == aiohttp.WSMsgType.TEXT:
|
|
79
|
-
if msg.data == 'close cmd':
|
|
80
|
-
await ws.close()
|
|
81
|
-
break
|
|
82
|
-
else:
|
|
83
|
-
await ws.send_str(msg.data + '/answer')
|
|
84
|
-
elif msg.type == aiohttp.WSMsgType.ERROR:
|
|
85
|
-
break
|
|
86
|
-
|
|
87
|
-
def data_upfile(self, file):
|
|
88
|
-
"""
|
|
89
|
-
|
|
90
|
-
:param file:
|
|
91
|
-
:return:
|
|
92
|
-
"""
|
|
93
|
-
with open(file, 'rb') as f:
|
|
94
|
-
await self.session.post('http://httpbin.org/post', data=f)
|
|
95
|
-
|
|
96
|
-
def init_session(self, json_serialize=json.dumps, headers=None,
|
|
97
|
-
cookies=None, cookie_jar=None, connector=None):
|
|
98
|
-
"""
|
|
99
|
-
|
|
100
|
-
:param json_serialize: 默认使用json.dumps 这里可以使用 ujson.dumps
|
|
101
|
-
ujson库比标准库快,json但是有点不兼容。
|
|
102
|
-
:param headers:
|
|
103
|
-
:param cookies:
|
|
104
|
-
:param cookie_jar:默认情况下ClientSession使用的严格版本 aiohttp.CookieJar。RFC 2109明确禁止cookie接受具有IP地址而不是DNS名称的URL(例如 http://127.0.0.1:80/cookie)。
|
|
105
|
-
很好,但有时为了进行测试,我们需要启用对此类Cookie的支持。应该通过将unsafe = True传递给 aiohttp.CookieJar构造函数来完成:
|
|
106
|
-
jar = aiohttp.CookieJar(unsafe=True)
|
|
107
|
-
jar = aiohttp.DummyCookieJar()
|
|
108
|
-
:return:
|
|
109
|
-
"""
|
|
110
|
-
|
|
111
|
-
self.session = aiohttp.ClientSession(json_serialize=json_serialize, headers=headers,
|
|
112
|
-
cookies=cookies, cookie_jar=cookie_jar,
|
|
113
|
-
connector=connector)
|
|
114
|
-
|
|
115
|
-
def deflate_zip(self, data, headers):
|
|
116
|
-
"""
|
|
117
|
-
|
|
118
|
-
:return:
|
|
119
|
-
"""
|
|
120
|
-
headers['Content-Encoding'] = 'deflate'
|
|
121
|
-
return zlib.compress(data), headers
|
|
122
|
-
|
|
123
|
-
async def on_request_start(self,
|
|
124
|
-
session, trace_config_ctx, params):
|
|
125
|
-
print("Starting request")
|
|
126
|
-
|
|
127
|
-
async def on_request_end(self, session, trace_config_ctx, params):
|
|
128
|
-
print("Ending request")
|
|
129
|
-
|
|
130
|
-
def set_trace_config(self):
|
|
131
|
-
"""
|
|
132
|
-
async with aiohttp.ClientSession(
|
|
133
|
-
trace_configs=[trace_config]) as client:
|
|
134
|
-
client.get('http://example.com/some/redirect/')
|
|
135
|
-
async with aiohttp.ClientSession(
|
|
136
|
-
trace_configs=[AuditRequest(), XRay()]) as client:
|
|
137
|
-
client.get('http://example.com/some/redirect/')
|
|
138
|
-
:return:
|
|
139
|
-
"""
|
|
140
|
-
# from mylib.traceconfig import AuditRequest
|
|
141
|
-
# from mylib.traceconfig import XRay
|
|
142
|
-
trace_config = aiohttp.TraceConfig()
|
|
143
|
-
trace_config.on_request_start.append(self.on_request_start)
|
|
144
|
-
trace_config.on_request_end.append(self.on_request_end)
|
|
145
|
-
|
|
146
|
-
def tpc_conn(self, limit=100, limit_per_host=30,
|
|
147
|
-
ttl_dns_cache=300, use_dns_cache=False, resolver=None):
|
|
148
|
-
"""
|
|
149
|
-
默认情况下,会话对象获得连接器的所有权,此外,一旦关闭会话,连接对象也会关闭连接。
|
|
150
|
-
如果您希望通过不同的会话 实例共享同一连接器,
|
|
151
|
-
则必须 为每个会话实例将 connector_owner参数设置为False。
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
:param limit: 要限制同时打开的连接数,您可以将limit 参数传递给连接器:
|
|
155
|
-
如果您明确希望没有限制,请传递0。例如:conn = aiohttp.TCPConnector(limit=0)
|
|
156
|
-
:param limit_per_host: 要限制到同一端点(三重)的同时打开的连接数,可以将limit_per_host 参数传递给connector:(host, port, is_ssl)
|
|
157
|
-
该示例将并行连接的数量限制为30个。
|
|
158
|
-
默认值为0(每个主机没有限制)。
|
|
159
|
-
:param ttl_dns_cache: 要限制到同一端点(三重)的同时打开的连接数,可以将limit_per_host 参数传递给connector:(host, port, is_ssl)
|
|
160
|
-
该示例将并行连接的数量限制为30个。
|
|
161
|
-
默认值为0(每个主机没有限制)。
|
|
162
|
-
:param use_dns_cache:或禁用DNS缓存表的使用,这意味着所有请求最终都会做出DNS解析,如以下示例所示:
|
|
163
|
-
:param resolver: resolver = AsyncResolver(nameservers=["8.8.8.8", "8.8.4.4"])
|
|
164
|
-
:return:
|
|
165
|
-
"""
|
|
166
|
-
connector = aiohttp.TCPConnector(limit=limit, limit_per_host=limit_per_host,
|
|
167
|
-
ttl_dns_cache=ttl_dns_cache, use_dns_cache=use_dns_cache,
|
|
168
|
-
resolver=resolver)
|
|
169
|
-
return connector
|
|
170
|
-
|
|
171
|
-
def unix_conn(self,path):
|
|
172
|
-
conn = aiohttp.UnixConnector(path=path)
|
|
173
|
-
return conn
|
|
174
|
-
|
|
175
|
-
def windows_conn(self,path):
|
|
176
|
-
"""
|
|
177
|
-
它仅适用于ProactorEventLoop
|
|
178
|
-
:param path:
|
|
179
|
-
:return:
|
|
180
|
-
"""
|
|
181
|
-
conn = aiohttp.NamedPipeConnector(path=path)
|
|
182
|
-
return conn
|
|
183
|
-
|
|
184
|
-
def get_cookie_jar(self):
|
|
185
|
-
"""
|
|
186
|
-
session.get(
|
|
187
|
-
'http://httpbin.org/cookies/set?my_cookie=my_value')
|
|
188
|
-
filtered = session.cookie_jar.filter_cookies(
|
|
189
|
-
'http://httpbin.org')
|
|
190
|
-
assert filtered['my_cookie'].value == 'my_value'
|
|
191
|
-
:return:
|
|
192
|
-
"""
|
|
193
|
-
return self.session.cookie_jar
|
|
194
|
-
|
|
195
|
-
def url(self, url, encoded=True):
|
|
196
|
-
"""
|
|
197
|
-
传递参数将覆盖encoded=True,切勿同时使用这两个选项。
|
|
198
|
-
self.params 为 传递参数
|
|
199
|
-
aiohttp在发送请求之前在内部执行URL 规范化。
|
|
200
|
-
册封编码主机通过部分IDNA编解码器和适用 requoting到路径和查询部分。
|
|
201
|
-
例如URL('http://example.com/путь/%30?a=%31')转换为 URL('http://example.com/%D0%BF%D1%83%D1%82%D1%8C/0?a=1')。
|
|
202
|
-
如果服务器接受精确的表示并且不重新引用URL本身,则有时不希望进行规范化。
|
|
203
|
-
:param url:
|
|
204
|
-
:param encoded: 要禁用规范化,请使用encoded=True参数进行URL构建
|
|
205
|
-
:return:
|
|
206
|
-
"""
|
|
207
|
-
return URL(url, encoded=encoded)
|
|
208
|
-
|
|
209
|
-
def get(self):
|
|
210
|
-
"""
|
|
211
|
-
如果您需要设置自定义ssl参数(例如,使用自己的认证文件),则可以创建一个ssl.SSLContext实例并将其传递给适当的ClientSession方法
|
|
212
|
-
sslcontext = ssl.create_default_context(
|
|
213
|
-
cafile='/path/to/ca-bundle.crt')
|
|
214
|
-
如果需要验证自签名证书,则可以执行与上一个示例相同的操作,但是ssl.SSLContext.load_cert_chain()使用密钥对添加另一个调用 :
|
|
215
|
-
sslcontext = ssl.create_default_context(
|
|
216
|
-
cafile='/path/to/ca-bundle.crt')
|
|
217
|
-
sslcontext.load_cert_chain('/path/to/client/public/device.pem',
|
|
218
|
-
'/path/to/client/private/device.key')
|
|
219
|
-
ssl验证失败时存在显式错误
|
|
220
|
-
aiohttp.ClientConnectorSSLError
|
|
221
|
-
ssl=False aiohttp对HTTPS协议使用严格检查。认证检查可以通过设置适当放宽
|
|
222
|
-
:return:
|
|
223
|
-
"""
|
|
224
|
-
pass
|
|
225
|
-
|
|
226
|
-
def post(self):
|
|
227
|
-
pass
|
|
228
|
-
|
|
229
|
-
def put(self):
|
|
230
|
-
pass
|
|
231
|
-
|
|
232
|
-
def delete(self):
|
|
233
|
-
pass
|
|
234
|
-
|
|
235
|
-
def head(self):
|
|
236
|
-
pass
|
|
237
|
-
|
|
238
|
-
def options(self):
|
|
239
|
-
pass
|
|
240
|
-
|
|
241
|
-
def patch(self):
|
|
242
|
-
pass
|
|
243
|
-
|
|
244
|
-
def rsp(self):
|
|
245
|
-
"""
|
|
246
|
-
print(resp.status)
|
|
247
|
-
print(await resp.text())
|
|
248
|
-
aiohttp自动解码服务器中的内容。您可以为该text()方法指定自定义编码:
|
|
249
|
-
await resp.text(encoding='windows-1251')
|
|
250
|
-
对于非文本请求,您还可以字节形式访问响应主体:
|
|
251
|
-
print(await resp.read())
|
|
252
|
-
br编码解码需要:
|
|
253
|
-
https://github.com/python-hyper/brotlipy
|
|
254
|
-
# 如果JSON解码失败,json()将引发异常。可以为json()调用指定自定义编码和解码器功能。
|
|
255
|
-
print(await resp.json())
|
|
256
|
-
# 上面的方法将整个响应主体读入内存。如果您打算读取大量数据,请考虑使用下面记录的流响应方法。
|
|
257
|
-
# 您可以使用该content 属性。它是aiohttp.StreamReader 该类的一个实例。
|
|
258
|
-
# 在gzip和deflate转移编码自动进行解码为您提供:
|
|
259
|
-
with open(filename, 'wb') as fd:
|
|
260
|
-
while True:
|
|
261
|
-
chunk = await resp.content.read(chunk_size)
|
|
262
|
-
if not chunk:
|
|
263
|
-
break
|
|
264
|
-
fd.write(chunk)
|
|
265
|
-
|
|
266
|
-
print(await resp.headers)
|
|
267
|
-
# 但如果服务器使用非标准编码,则有时需要未转换的数据。
|
|
268
|
-
这些标头的格式不正确RFC 7230的 角度来看,可以通过使用
|
|
269
|
-
print(await resp.raw_headers)
|
|
270
|
-
如果响应包含一些HTTP Cookie,则可以快速访问它们:
|
|
271
|
-
响应Cookie仅包含重定向链中最后一个请求的Set-Cookie标头中的值。
|
|
272
|
-
要在所有重定向请求之间收集cookie,请使用aiohttp.ClientSession对象。
|
|
273
|
-
print(await resp.cookies)
|
|
274
|
-
# 如果请求被重定向,则可以使用history属性查看先前的响应:
|
|
275
|
-
如果未发生重定向或将其allow_redirects设置为False,则历史记录将为空序列。
|
|
276
|
-
print(await resp.history)
|
|
277
|
-
显式地传递期望的类型(在这种情况下,检查将是严格的,没有扩展格式的支持,因此custom/xxx+type将不被接受):
|
|
278
|
-
await resp.json(content_type='custom/type')。
|
|
279
|
-
完全禁用检查:
|
|
280
|
-
await resp.json(content_type=None)。
|
|
281
|
-
:return:
|
|
282
|
-
"""
|
|
283
|
-
pass
|
|
284
|
-
|
|
285
|
-
def multipart(self):
|
|
286
|
-
"""
|
|
287
|
-
https://docs.aiohttp.org/en/stable/multipart.html#aiohttp-multipart
|
|
288
|
-
:return:
|
|
289
|
-
"""
|
|
290
|
-
pass
|
|
291
|
-
|
|
292
|
-
def close(self):
|
|
293
|
-
self.session.close()
|
|
294
|
-
|
|
295
|
-
def __del__(self):
|
|
296
|
-
self.close()
|
|
1
|
+
import json
|
|
2
|
+
import zlib
|
|
3
|
+
|
|
4
|
+
import aiofiles
|
|
5
|
+
import aiohttp
|
|
6
|
+
from yarl import URL
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class BaseAiohttp():
|
|
10
|
+
|
|
11
|
+
def __init__(self):
|
|
12
|
+
self.session = aiohttp.ClientSession()
|
|
13
|
+
# 用于传递get的参数
|
|
14
|
+
# params = {'key1': 'value1', 'key2': 'value2'}
|
|
15
|
+
# params = [('key', 'value1'), ('key', 'value2')] 同建多值问题
|
|
16
|
+
# params='key=value+1' 您也可以将str内容作为参数传递,但要注意–内容不是由库编码的。
|
|
17
|
+
# 请注意,+未编码
|
|
18
|
+
self.params = {}
|
|
19
|
+
# post json
|
|
20
|
+
self.json = {}
|
|
21
|
+
# post表单数据 {'key1': 'value1', 'key2': 'value2'}
|
|
22
|
+
self.payload = {}
|
|
23
|
+
# 如果您要发送未经格式编码的数据,可以通过传递a bytes而不是a来完成dict。
|
|
24
|
+
# 这些数据将直接发布,并且默认将内容类型设置为“ application / octet-stream”:
|
|
25
|
+
# =b'\x00Binary-data\x00'
|
|
26
|
+
# 要发送具有适当内容类型的文本,只需使用text属性 data='Тест'
|
|
27
|
+
# 要上传多部分编码的文件,请执行以下操作:
|
|
28
|
+
# files = {'file': open('report.xls', 'rb')}
|
|
29
|
+
# 您可以设置filename和content_type:
|
|
30
|
+
# data = FormData()
|
|
31
|
+
# data.add_field('file',
|
|
32
|
+
# open('report.xls', 'rb'),
|
|
33
|
+
# filename='report.xls',
|
|
34
|
+
# content_type='application/vnd.ms-excel')
|
|
35
|
+
# 如果将文件对象作为数据参数传递,则aiohttp会将其自动流式传输到服务器。
|
|
36
|
+
# 检查StreamReader 支持的格式信息。
|
|
37
|
+
self.data = b''
|
|
38
|
+
# headers可以是单个请求的,也可以是会话的
|
|
39
|
+
self.headers = {}
|
|
40
|
+
# {'cookies_are': 'working'}
|
|
41
|
+
self.cookies = {}
|
|
42
|
+
|
|
43
|
+
async def file_sender(self, file_name=None, size=64):
|
|
44
|
+
"""
|
|
45
|
+
async with session.post('http://httpbin.org/post',
|
|
46
|
+
data=file_sender(file_name='huge_file')) as resp:
|
|
47
|
+
print(await resp.text())
|
|
48
|
+
:param file_name:
|
|
49
|
+
:param size:
|
|
50
|
+
:return:
|
|
51
|
+
"""
|
|
52
|
+
async with aiofiles.open(file_name, 'rb') as f:
|
|
53
|
+
chunk = await f.read(size * 1024)
|
|
54
|
+
while chunk:
|
|
55
|
+
yield chunk
|
|
56
|
+
chunk = await f.read(size * 1024)
|
|
57
|
+
|
|
58
|
+
def get_and_send(self):
|
|
59
|
+
"""
|
|
60
|
+
从版本3.1开始不推荐使用:aiohttp仍然支持aiohttp.streamer装饰器,
|
|
61
|
+
但是不推荐使用此方法,而支持异步生成器,如上所示。
|
|
62
|
+
Python 3.5没有对异步生成器的本机支持,请使用 async_generator库作为解决方法。
|
|
63
|
+
因为该content属性是 StreamReader(提供异步迭代器协议),所以您可以将获取和发布请求链接在一起:
|
|
64
|
+
resp = await session.get('http://python.org')
|
|
65
|
+
await session.post('http://httpbin.org/post',
|
|
66
|
+
data=resp.content)
|
|
67
|
+
:return:
|
|
68
|
+
"""
|
|
69
|
+
pass
|
|
70
|
+
|
|
71
|
+
def web_sockets(self, url):
|
|
72
|
+
"""
|
|
73
|
+
|
|
74
|
+
:return:
|
|
75
|
+
"""
|
|
76
|
+
async with self.session.ws_connect(url) as ws:
|
|
77
|
+
async for msg in ws:
|
|
78
|
+
if msg.type == aiohttp.WSMsgType.TEXT:
|
|
79
|
+
if msg.data == 'close cmd':
|
|
80
|
+
await ws.close()
|
|
81
|
+
break
|
|
82
|
+
else:
|
|
83
|
+
await ws.send_str(msg.data + '/answer')
|
|
84
|
+
elif msg.type == aiohttp.WSMsgType.ERROR:
|
|
85
|
+
break
|
|
86
|
+
|
|
87
|
+
def data_upfile(self, file):
|
|
88
|
+
"""
|
|
89
|
+
|
|
90
|
+
:param file:
|
|
91
|
+
:return:
|
|
92
|
+
"""
|
|
93
|
+
with open(file, 'rb') as f:
|
|
94
|
+
await self.session.post('http://httpbin.org/post', data=f)
|
|
95
|
+
|
|
96
|
+
def init_session(self, json_serialize=json.dumps, headers=None,
|
|
97
|
+
cookies=None, cookie_jar=None, connector=None):
|
|
98
|
+
"""
|
|
99
|
+
|
|
100
|
+
:param json_serialize: 默认使用json.dumps 这里可以使用 ujson.dumps
|
|
101
|
+
ujson库比标准库快,json但是有点不兼容。
|
|
102
|
+
:param headers:
|
|
103
|
+
:param cookies:
|
|
104
|
+
:param cookie_jar:默认情况下ClientSession使用的严格版本 aiohttp.CookieJar。RFC 2109明确禁止cookie接受具有IP地址而不是DNS名称的URL(例如 http://127.0.0.1:80/cookie)。
|
|
105
|
+
很好,但有时为了进行测试,我们需要启用对此类Cookie的支持。应该通过将unsafe = True传递给 aiohttp.CookieJar构造函数来完成:
|
|
106
|
+
jar = aiohttp.CookieJar(unsafe=True)
|
|
107
|
+
jar = aiohttp.DummyCookieJar()
|
|
108
|
+
:return:
|
|
109
|
+
"""
|
|
110
|
+
|
|
111
|
+
self.session = aiohttp.ClientSession(json_serialize=json_serialize, headers=headers,
|
|
112
|
+
cookies=cookies, cookie_jar=cookie_jar,
|
|
113
|
+
connector=connector)
|
|
114
|
+
|
|
115
|
+
def deflate_zip(self, data, headers):
|
|
116
|
+
"""
|
|
117
|
+
|
|
118
|
+
:return:
|
|
119
|
+
"""
|
|
120
|
+
headers['Content-Encoding'] = 'deflate'
|
|
121
|
+
return zlib.compress(data), headers
|
|
122
|
+
|
|
123
|
+
async def on_request_start(self,
|
|
124
|
+
session, trace_config_ctx, params):
|
|
125
|
+
print("Starting request")
|
|
126
|
+
|
|
127
|
+
async def on_request_end(self, session, trace_config_ctx, params):
|
|
128
|
+
print("Ending request")
|
|
129
|
+
|
|
130
|
+
def set_trace_config(self):
|
|
131
|
+
"""
|
|
132
|
+
async with aiohttp.ClientSession(
|
|
133
|
+
trace_configs=[trace_config]) as client:
|
|
134
|
+
client.get('http://example.com/some/redirect/')
|
|
135
|
+
async with aiohttp.ClientSession(
|
|
136
|
+
trace_configs=[AuditRequest(), XRay()]) as client:
|
|
137
|
+
client.get('http://example.com/some/redirect/')
|
|
138
|
+
:return:
|
|
139
|
+
"""
|
|
140
|
+
# from mylib.traceconfig import AuditRequest
|
|
141
|
+
# from mylib.traceconfig import XRay
|
|
142
|
+
trace_config = aiohttp.TraceConfig()
|
|
143
|
+
trace_config.on_request_start.append(self.on_request_start)
|
|
144
|
+
trace_config.on_request_end.append(self.on_request_end)
|
|
145
|
+
|
|
146
|
+
def tpc_conn(self, limit=100, limit_per_host=30,
|
|
147
|
+
ttl_dns_cache=300, use_dns_cache=False, resolver=None):
|
|
148
|
+
"""
|
|
149
|
+
默认情况下,会话对象获得连接器的所有权,此外,一旦关闭会话,连接对象也会关闭连接。
|
|
150
|
+
如果您希望通过不同的会话 实例共享同一连接器,
|
|
151
|
+
则必须 为每个会话实例将 connector_owner参数设置为False。
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
:param limit: 要限制同时打开的连接数,您可以将limit 参数传递给连接器:
|
|
155
|
+
如果您明确希望没有限制,请传递0。例如:conn = aiohttp.TCPConnector(limit=0)
|
|
156
|
+
:param limit_per_host: 要限制到同一端点(三重)的同时打开的连接数,可以将limit_per_host 参数传递给connector:(host, port, is_ssl)
|
|
157
|
+
该示例将并行连接的数量限制为30个。
|
|
158
|
+
默认值为0(每个主机没有限制)。
|
|
159
|
+
:param ttl_dns_cache: 要限制到同一端点(三重)的同时打开的连接数,可以将limit_per_host 参数传递给connector:(host, port, is_ssl)
|
|
160
|
+
该示例将并行连接的数量限制为30个。
|
|
161
|
+
默认值为0(每个主机没有限制)。
|
|
162
|
+
:param use_dns_cache:或禁用DNS缓存表的使用,这意味着所有请求最终都会做出DNS解析,如以下示例所示:
|
|
163
|
+
:param resolver: resolver = AsyncResolver(nameservers=["8.8.8.8", "8.8.4.4"])
|
|
164
|
+
:return:
|
|
165
|
+
"""
|
|
166
|
+
connector = aiohttp.TCPConnector(limit=limit, limit_per_host=limit_per_host,
|
|
167
|
+
ttl_dns_cache=ttl_dns_cache, use_dns_cache=use_dns_cache,
|
|
168
|
+
resolver=resolver)
|
|
169
|
+
return connector
|
|
170
|
+
|
|
171
|
+
def unix_conn(self,path):
|
|
172
|
+
conn = aiohttp.UnixConnector(path=path)
|
|
173
|
+
return conn
|
|
174
|
+
|
|
175
|
+
def windows_conn(self,path):
|
|
176
|
+
"""
|
|
177
|
+
它仅适用于ProactorEventLoop
|
|
178
|
+
:param path:
|
|
179
|
+
:return:
|
|
180
|
+
"""
|
|
181
|
+
conn = aiohttp.NamedPipeConnector(path=path)
|
|
182
|
+
return conn
|
|
183
|
+
|
|
184
|
+
def get_cookie_jar(self):
|
|
185
|
+
"""
|
|
186
|
+
session.get(
|
|
187
|
+
'http://httpbin.org/cookies/set?my_cookie=my_value')
|
|
188
|
+
filtered = session.cookie_jar.filter_cookies(
|
|
189
|
+
'http://httpbin.org')
|
|
190
|
+
assert filtered['my_cookie'].value == 'my_value'
|
|
191
|
+
:return:
|
|
192
|
+
"""
|
|
193
|
+
return self.session.cookie_jar
|
|
194
|
+
|
|
195
|
+
def url(self, url, encoded=True):
|
|
196
|
+
"""
|
|
197
|
+
传递参数将覆盖encoded=True,切勿同时使用这两个选项。
|
|
198
|
+
self.params 为 传递参数
|
|
199
|
+
aiohttp在发送请求之前在内部执行URL 规范化。
|
|
200
|
+
册封编码主机通过部分IDNA编解码器和适用 requoting到路径和查询部分。
|
|
201
|
+
例如URL('http://example.com/путь/%30?a=%31')转换为 URL('http://example.com/%D0%BF%D1%83%D1%82%D1%8C/0?a=1')。
|
|
202
|
+
如果服务器接受精确的表示并且不重新引用URL本身,则有时不希望进行规范化。
|
|
203
|
+
:param url:
|
|
204
|
+
:param encoded: 要禁用规范化,请使用encoded=True参数进行URL构建
|
|
205
|
+
:return:
|
|
206
|
+
"""
|
|
207
|
+
return URL(url, encoded=encoded)
|
|
208
|
+
|
|
209
|
+
def get(self):
|
|
210
|
+
"""
|
|
211
|
+
如果您需要设置自定义ssl参数(例如,使用自己的认证文件),则可以创建一个ssl.SSLContext实例并将其传递给适当的ClientSession方法
|
|
212
|
+
sslcontext = ssl.create_default_context(
|
|
213
|
+
cafile='/path/to/ca-bundle.crt')
|
|
214
|
+
如果需要验证自签名证书,则可以执行与上一个示例相同的操作,但是ssl.SSLContext.load_cert_chain()使用密钥对添加另一个调用 :
|
|
215
|
+
sslcontext = ssl.create_default_context(
|
|
216
|
+
cafile='/path/to/ca-bundle.crt')
|
|
217
|
+
sslcontext.load_cert_chain('/path/to/client/public/device.pem',
|
|
218
|
+
'/path/to/client/private/device.key')
|
|
219
|
+
ssl验证失败时存在显式错误
|
|
220
|
+
aiohttp.ClientConnectorSSLError
|
|
221
|
+
ssl=False aiohttp对HTTPS协议使用严格检查。认证检查可以通过设置适当放宽
|
|
222
|
+
:return:
|
|
223
|
+
"""
|
|
224
|
+
pass
|
|
225
|
+
|
|
226
|
+
def post(self):
|
|
227
|
+
pass
|
|
228
|
+
|
|
229
|
+
def put(self):
|
|
230
|
+
pass
|
|
231
|
+
|
|
232
|
+
def delete(self):
|
|
233
|
+
pass
|
|
234
|
+
|
|
235
|
+
def head(self):
|
|
236
|
+
pass
|
|
237
|
+
|
|
238
|
+
def options(self):
|
|
239
|
+
pass
|
|
240
|
+
|
|
241
|
+
def patch(self):
|
|
242
|
+
pass
|
|
243
|
+
|
|
244
|
+
def rsp(self):
|
|
245
|
+
"""
|
|
246
|
+
print(resp.status)
|
|
247
|
+
print(await resp.text())
|
|
248
|
+
aiohttp自动解码服务器中的内容。您可以为该text()方法指定自定义编码:
|
|
249
|
+
await resp.text(encoding='windows-1251')
|
|
250
|
+
对于非文本请求,您还可以字节形式访问响应主体:
|
|
251
|
+
print(await resp.read())
|
|
252
|
+
br编码解码需要:
|
|
253
|
+
https://github.com/python-hyper/brotlipy
|
|
254
|
+
# 如果JSON解码失败,json()将引发异常。可以为json()调用指定自定义编码和解码器功能。
|
|
255
|
+
print(await resp.json())
|
|
256
|
+
# 上面的方法将整个响应主体读入内存。如果您打算读取大量数据,请考虑使用下面记录的流响应方法。
|
|
257
|
+
# 您可以使用该content 属性。它是aiohttp.StreamReader 该类的一个实例。
|
|
258
|
+
# 在gzip和deflate转移编码自动进行解码为您提供:
|
|
259
|
+
with open(filename, 'wb') as fd:
|
|
260
|
+
while True:
|
|
261
|
+
chunk = await resp.content.read(chunk_size)
|
|
262
|
+
if not chunk:
|
|
263
|
+
break
|
|
264
|
+
fd.write(chunk)
|
|
265
|
+
|
|
266
|
+
print(await resp.headers)
|
|
267
|
+
# 但如果服务器使用非标准编码,则有时需要未转换的数据。
|
|
268
|
+
这些标头的格式不正确RFC 7230的 角度来看,可以通过使用
|
|
269
|
+
print(await resp.raw_headers)
|
|
270
|
+
如果响应包含一些HTTP Cookie,则可以快速访问它们:
|
|
271
|
+
响应Cookie仅包含重定向链中最后一个请求的Set-Cookie标头中的值。
|
|
272
|
+
要在所有重定向请求之间收集cookie,请使用aiohttp.ClientSession对象。
|
|
273
|
+
print(await resp.cookies)
|
|
274
|
+
# 如果请求被重定向,则可以使用history属性查看先前的响应:
|
|
275
|
+
如果未发生重定向或将其allow_redirects设置为False,则历史记录将为空序列。
|
|
276
|
+
print(await resp.history)
|
|
277
|
+
显式地传递期望的类型(在这种情况下,检查将是严格的,没有扩展格式的支持,因此custom/xxx+type将不被接受):
|
|
278
|
+
await resp.json(content_type='custom/type')。
|
|
279
|
+
完全禁用检查:
|
|
280
|
+
await resp.json(content_type=None)。
|
|
281
|
+
:return:
|
|
282
|
+
"""
|
|
283
|
+
pass
|
|
284
|
+
|
|
285
|
+
def multipart(self):
|
|
286
|
+
"""
|
|
287
|
+
https://docs.aiohttp.org/en/stable/multipart.html#aiohttp-multipart
|
|
288
|
+
:return:
|
|
289
|
+
"""
|
|
290
|
+
pass
|
|
291
|
+
|
|
292
|
+
def close(self):
|
|
293
|
+
self.session.close()
|
|
294
|
+
|
|
295
|
+
def __del__(self):
|
|
296
|
+
self.close()
|