zoukankan      html  css  js  c++  java
  • 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()
    
  • 相关阅读:
    CompareUtil
    linux awk学习笔记
    linux用grep查找包含两个关键字的命令
    mysql 使用set names 解决乱码问题
    对私有静态方法进行单测
    使用JUnit测试预期异常
    Tortoise svn 冲突解决主要办法
    tortoise svn冲突解决
    word-break与word-wrap
    移动端适配
  • 原文地址:https://www.cnblogs.com/liujitao79/p/8608021.html
Copyright © 2011-2022 走看看