aiohttp模块1 client

Make a Request

import aiohttp

async with aiohttp.ClientSession() as session:
    async with session.get('https://api.github.com/events') as resp:
        print(resp.status)
        print(await resp.text())

session.post('http://httpbin.org/post', data=b'data')
session.put('http://httpbin.org/put', data=b'data')
session.delete('http://httpbin.org/delete')
session.head('http://httpbin.org/get')
session.options('http://httpbin.org/get')
session.patch('http://httpbin.org/patch', data=b'data')
aiohttp.ClientSession.get(self, url, allow_redirects=True, **kwargs)
aiohttp.ClientSession.post(self, url, data=None, **kwargs)
aiohttp.ClientSession.put(self, url, data=None, **kwargs)
aiohttp.ClientSession.delete(self, url, **kwargs)
aiohttp.ClientSession.head(self, url, allow_redirects=False, **kwargs)
aiohttp.ClientSession.options(self, url, allow_redirects=True, **kwargs)
aiohttp.ClientSession.patch(self, url, data=None, **kwargs)

# 无须为每个request建立session. 仅需要为每个application建立session供所有request使用. session内部包含连接池,connection复用与长连接加速总性能。

Passing Parameters In URLs

# 字典
params = {'key1': 'value1', 'key2': 'value2'}
async with session.get('http://httpbin.org/get', params=params) as resp:
    assert str(resp.url) == 'http://httpbin.org/get?key2=value2&key1=value1'

# 数组
params = [('key', 'value1'), ('key', 'value2')]
async with session.get('http://httpbin.org/get', params=params) as r:
    assert str(r.url) == 'http://httpbin.org/get?key=value2&key=value1'

# 字符串
async with session.get('http://httpbin.org/get', params='key=value+1') as r:
    assert str(r.url) == 'http://httpbin.org/get?key=value+1'

# aiohttp在发送请求前在内部自动对url进行转码,如URL('http://example.com/путь%30?a=%31') -> URL('http://example.com/%D0%BF%D1%83%D1%82%D1%8C/0?a=1')
# 使用encoded=True开关禁用, 如await session.get(URL('http://example.com/%30', encoded=True))

Response Content and Status Code

async with session.get('https://api.github.com/events') as resp:
    print(resp.status)
    print(await resp.text())
# out
200
'[{"created_at":"2015-06-12T14:06:22Z","public":true,"actor":{... '

# aiohttp自动对服务端返回的内容进行decode.可以使用text()方法自定义encode,如 await resp.text(encoding='windows-1251')

Binary Response Content

async with session.get('https://api.github.com/events') as resp:
    print(await resp.read())
# out
b'[{"created_at":"2015-06-12T14:06:22Z","public":true,"actor":{... ]'

# gzip和deflate压缩算法,自动解码。brotli压缩算法需要安装 brotlipy 模块

JSON Request

async with aiohttp.ClientSession() as session:
    async with session.post(url, json={'test': 'object'})

默认使用标准库json进行序列化,如果想快一点的话,可以使用第三方库ujson,但小小的不兼容

import ujson

async with aiohttp.ClientSession(json_serialize=ujson.dumps) as session:
    async with session.post(url, json={'test': 'object'})

JSON Response Content

async with session.get('https://api.github.com/events') as resp:
    print(await resp.json())

# 如果json解析失败,会抛出异常

Streaming Response Content

async with aiohttp.StreamReader() as session:
    async with session.get('https://api.github.com/events') as resp:
        await resp.content.read(10)

# read(), json(),text()将内容放在内存中,如果文件内容比较大,1G以上,需要使用 aiohttp.StreamReader 替代,它会对gzip和deflate压缩算法自动解码
with open(filename, 'wb') as fd:
    while True:
        chunk = await resp.content.read(chunk_size)
        if not chunk:
            break
        fd.write(chunk)

# 写入文件

More complicated POST requests

payload = {'key1': 'value1', 'key2': 'value2'}
async with session.post('http://httpbin.org/post',
                        data=payload) as resp:
    print(await resp.text())
# form-encoded data (HTML form), 使用字典,字典数据自动编码为form-encoded
{
  ...
  "form": {
    "key2": "value2",
    "key1": "value1"
  },
  ...
}
async with session.post(url, data=b'x00Binary-datax00') as resp:
    ...

# 非 form-encoded数据使用bytes类型,数据发送默认使用content-type ‘application/octet-stream’ 
async with session.post(url, json={'example': 'test'}) as resp:
    ...

# josn类型
async with session.post(url, text='Тест') as resp:
    ...

# content-type text类型

POST a Multipart-Encoded File

url = 'http://httpbin.org/post'
files = {'file': open('report.xls', 'rb')}

await session.post(url, data=files)
url = 'http://httpbin.org/post'
data = FormData()
data.add_field('file',
               open('report.xls', 'rb'),
               filename='report.xls',
               content_type='application/vnd.ms-excel')

await session.post(url, data=data)

# 上传文件对象,aiohttp使用stream

Streaming uploads

with open('massive-body', 'rb') as f:
   await session.post('http://httpbin.org/post', data=f)

# 文件类型过大,使用Stream方式
@aiohttp.streamer
def file_sender(writer, file_name=None):
    with open(file_name, 'rb') as f:
        chunk = f.read(2**16)
        while chunk:
            yield from writer.write(chunk)
            chunk = f.read(2**16)

# Then you can use file_sender as a data provider:

async with session.post('http://httpbin.org/post',
                        data=file_sender(file_name='huge_file')) as resp:
    print(await resp.text())
async def feed_stream(resp, stream):
    h = hashlib.sha256()

    while True:
        chunk = await resp.content.readany()
        if not chunk:
            break
        h.update(chunk)
        stream.feed_data(chunk)

    return h.hexdigest()

resp = session.get('http://httpbin.org/post')
stream = StreamReader()
loop.create_task(session.post('http://httpbin.org/post', data=stream))

file_hash = await feed_stream(resp, stream)
r = await session.get('http://python.org')
await session.post('http://httpbin.org/post', data=r.content)

WebSockets

session = aiohttp.ClientSession()
async with session.ws_connect('http://example.org/websocket') as ws:

    async for msg in ws:
        if msg.type == aiohttp.WSMsgType.TEXT:
            if msg.data == 'close cmd':
                await ws.close()
                break
            else:
                await ws.send_str(msg.data + '/answer')
        elif msg.type == aiohttp.WSMsgType.CLOSED:
            break
        elif msg.type == aiohttp.WSMsgType.ERROR:
            break

Timeouts

async with session.get('https://github.com', timeout=60) as r:
    ...

# 默认IO操作延时5分钟,None 或者 0 禁用延时
# 使用async_timeout模块
import async_timeout

with async_timeout.timeout(0.001):
    async with session.get('https://github.com') as r:
        await r.text()
原文地址:https://www.cnblogs.com/liujitao79/p/8608021.html