aiohttp:response.status什么时候可用?

时间:2017-09-27 10:03:39

标签: python python-asyncio aiohttp

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())

我无法理解response.status何时可用。我的理解是协同程序在await response.read()行释放控制权。在等待回复回复之前,我怎样才能访问状态?

3 个答案:

答案 0 :(得分:3)

首先获取HTTP响应标头,其中包含第一行的状态代码。如果您这样选择,则可以阅读响应正文的其余部分(此处带有resp.text())。由于标题总是相对较小而且正文可能非常大,所以aiohttp让您有机会单独阅读。

答案 1 :(得分:3)

重要区别:await ...可以释放对上下文的控制,例如,如果等待的数据不够快,则可以使用。 async with ...语句也是如此。因此,在resp可用之前,您的代码才会到达print(resp.status)行。

例如代码:

import aiohttp
import asyncio
import urllib.parse
import datetime

async def get(session, url):
    print("[{:%M:%S.%f}] getting {} ...".format(datetime.datetime.now(), urllib.parse.urlsplit(url).hostname))
    async with session.get(url) as resp:
        print("[{:%M:%S.%f}] {}, status: {}".format(datetime.datetime.now(), urllib.parse.urlsplit(url).hostname, resp.status))
        doc = await resp.text()
        print("[{:%M:%S.%f}] {}, len: {}".format(datetime.datetime.now(), urllib.parse.urlsplit(url).hostname, len(doc)))

async def main():
    session = aiohttp.ClientSession()

    url = "http://demo.borland.com/Testsite/stadyn_largepagewithimages.html"
    f1 = asyncio.ensure_future(get(session, url))
    print("[{:%M:%S.%f}] added {} to event loop".format(datetime.datetime.now(), urllib.parse.urlsplit(url).hostname))

    url = "https://stackoverflow.com/questions/46445019/aiohttp-when-is-the-response-status-available"
    f2 = asyncio.ensure_future(get(session, url))
    print("[{:%M:%S.%f}] added {} to event loop".format(datetime.datetime.now(), urllib.parse.urlsplit(url).hostname))

    url = "https://api.github.com/events"
    f3 = asyncio.ensure_future(get(session, url))
    print("[{:%M:%S.%f}] added {} to event loop".format(datetime.datetime.now(), urllib.parse.urlsplit(url).hostname))

    await f1
    await f2
    await f3

    session.close()

if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())

可以产生这样的结果:

[16:42.415481] added demo.borland.com to event loop
[16:42.415481] added stackoverflow.com to event loop
[16:42.415481] added api.github.com to event loop
[16:42.415481] getting demo.borland.com ...
[16:42.422481] getting stackoverflow.com ...
[16:42.682496] getting api.github.com ...
[16:43.002515] demo.borland.com, status: 200
[16:43.510544] stackoverflow.com, status: 200
[16:43.759558] stackoverflow.com, len: 110650
[16:43.883565] demo.borland.com, len: 239012
[16:44.089577] api.github.com, status: 200
[16:44.318590] api.github.com, len: 43055
澄清(thx @deceze):在这里你可以看到(查看括号之间的时间)所有协同程序在发送检索网站的请求后释放控制权,并在等待响应文本时第二次。与stackoverflow相比,borland还有很多文本(不包括其他网络特性),只有在打印出stackoverflow文本后才能显示它,尽管之前已经请求过。

答案 2 :(得分:2)

resp对象在async with块内可用。因此resp.status也可用。您也可以在某些方法上调用await,例如resp.text(),但不会释放对async with块的控制权。即使在resp被调用后,您也可以使用await