AIOHTTP用法

发布时间 2023-12-11 18:49:54作者: linux星
$ pip install aiohttp

为了加快客户端 API 的 DNS 解析速度,您也可以安装 aiodns。 强烈建议使用此选项:

$ pip install aiodns

客户端示例

import aiohttp
import asyncio

async def main():

    async with aiohttp.ClientSession() as session:
        async with session.get('http://python.org') as response:

            print("Status:", response.status)
            print("Content-type:", response.headers['content-type'])

            html = await response.text()
            print("Body:", html[:15], "...")

asyncio.run(main())

这将打印:

Status: 200
Content-type: text/html; charset=utf-8
Body: <!doctype html> ...

服务器示例:

from aiohttp import web

async def handle(request):
    name = request.match_info.get('name', "Anonymous")
    text = "Hello, " + name
    return web.Response(text=text)

app = web.Application()
app.add_routes([web.get('/', handle),
                web.get('/{name}', handle)])

if __name__ == '__main__':
    web.run_app(app)

Client Session

是所有人的心脏和主要切入点 客户端 API 操作。

首先创建会话,使用实例执行 HTTP 请求并启动 WebSocket 连接。

会话包含一个 cookie 存储和连接池,因此 Cookie 和连接在 HTTP 请求之间共享 同一会话。

Custom Request Headers

如果需要将 HTTP 标头添加到请求中,请将它们传递给 headers 参数。

例如,如果要直接指定 content-type:

url = 'http://example.com/image'
payload = b'GIF89a\x01\x00\x01\x00\x00\xff\x00,\x00\x00'
          b'\x00\x00\x01\x00\x01\x00\x00\x02\x00;'
headers = {'content-type': 'image/gif'}

await session.post(url,
                   data=payload,
                   headers=headers)

您还可以为所有会话请求设置默认标头:

headers={"Authorization": "Basic bG9naW46cGFzcw=="}
async with aiohttp.ClientSession(headers=headers) as session:
    async with session.get("http://httpbin.org/headers") as r:
        json_body = await r.json()
        assert json_body['headers']['Authorization'] == \
            'Basic bG9naW46cGFzcw=='

典型的用例是发送 JSON 正文。您可以指定内容类型 直接如上图所示,但使用特殊关键字更方便:json

await session.post(url, json={'example': 'text'})

对于文本/纯文本

await session.post(url, data='Привет, Мир!')

自定义 Cookie

要将您自己的 cookie 发送到服务器,您可以使用构造函数的 cookie 参数:

url = 'http://httpbin.org/cookies'
cookies = {'cookies_are': 'working'}
async with ClientSession(cookies=cookies) as session:
    async with session.get(url) as resp:
        assert await resp.json() == {
           "cookies": {"cookies_are": "working"}}

可用于共享 Cookie 在多个请求之间:

async with aiohttp.ClientSession() as session:
    await session.get(
        'http://httpbin.org/cookies/set?my_cookie=my_value')
    filtered = session.cookie_jar.filter_cookies(
        'http://httpbin.org')
    assert filtered['my_cookie'].value == 'my_value'
    async with session.get('http://httpbin.org/cookies') as r:
        json_body = await r.json()
        assert json_body['cookies']['my_cookie'] == 'my_value'

响应标头和 Cookie

我们可以使用 答:

assert resp.headers == {
    'ACCESS-CONTROL-ALLOW-ORIGIN': '*',
    'CONTENT-TYPE': 'application/json',
    'DATE': 'Tue, 15 Jul 2014 16:49:51 GMT',
    'SERVER': 'gunicorn/18.0',
    'CONTENT-LENGTH': '331',
    'CONNECTION': 'keep-alive'}

不过,字典很特别:它是专门为 HTTP 制作的 头。根据 RFC 7230,HTTP 标头名称 不区分大小写。它还支持相同的多个值 键,就像 HTTP 协议一样。

因此,我们可以使用我们想要的任何大小写来访问标头:

assert resp.headers['Content-Type'] == 'application/json'

assert resp.headers.get('content-type') == 'application/json'

所有标头都使用 UTF-8 和 option 从二进制数据转换而来。这在大多数情况下都很好用,但是 如果服务器使用非标准数据,有时需要未转换的数据 编码。虽然从 RFC 7230 的角度来看,这些标头的格式不正确,但可以使用属性检索它们:surrogateescape

assert resp.raw_headers == (
    (b'SERVER', b'nginx'),
    (b'DATE', b'Sat, 09 Jan 2016 20:28:40 GMT'),
    (b'CONTENT-TYPE', b'text/html; charset=utf-8'),
    (b'CONTENT-LENGTH', b'12150'),
    (b'CONNECTION', b'keep-alive'))

如果响应包含一些 HTTP Cookie,您可以快速访问它们:

url = 'http://example.com/some/cookie/setting/url'
async with session.get(url) as resp:
    print(resp.cookies['example_cookie_name'])