Python 的异步 IO:Aiohttp Client 代码分析

Aiohttp 是 Python 的一个 HTTP 框架,基于 asyncio,所以叫 Aiohttp。

我主要是看源码,想理解它的设计,所以附上了类图与时序图。不可避免的,可读性会比较差。
想找教程的话,请移步 官方教程,写得还是挺不错的。

一个例子

下面这个例子,通过 HTTP GET 列出 GitHub 的 public events:

import asyncio
import aiohttpasync def main():async with aiohttp.ClientSession() as session:async with session.get('https://api.github.com/events') as resp:print(resp.status)print(await resp.text())loop = asyncio.get_event_loop()
loop.run_until_complete(main())

Response 是一个 JSON 格式的文本:

[{"id": "6888907432","type": "PushEvent","actor": {"id": 3956266,"login": "sekineh","display_login": "sekineh","gravatar_id": "","url": "https://api.github.com/users/sekineh","avatar_url": "https://avatars.githubusercontent.com/u/3956266?"},...
]

ClientSession 是一个 Asynchronous Context Manager,所以搭配 async with 语句一起使用。像下面这样应该也是可以的:

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

不过肯定是不推荐的,就当是帮助理解吧。

ClientSession.get() 返回一个 ClientResponse 对象,通过 text() 方法,可以拿到 response 的文本:

print(await resp.text())

当然,text() 是一个协程:

    @asyncio.coroutinedef text(self, encoding=None, errors='strict'):"""Read response payload and decode."""...

Connector

ClientSession 依赖 Connector 来创建连接,缺省为 TCPConnector,它继承自 BaseConnector,此外还有 UnixConnector(应该是 Unix Domain Socket)。

Connector 的接口比较简单,主要提供了 connect() 方法(也是协程):

    @asyncio.coroutinedef connect(self, req):"""Get from pool or create new connection."""...

以及 close() 方法:

    def close(self):"""Close all opened transports."""...

ConnectionKey

ClientRequest 有个属性 connection_key

class ClientRequest:
    @propertydef connection_key(self):return ConnectionKey(self.host, self.port, self.ssl)

它是一个 namedtuple

ConnectionKey = namedtuple('ConnectionKey', ['host', 'port', 'ssl'])

由 hostport 和 ssl 三个元素组成,这三个元素可以唯一定义一个连接,所以叫 ConnectionKey
文章开头的那个例子中,ConnectionKey 为:

ConnectionKey(host='api.github.com', port=443, ssl=True)

全局函数 request()

Aiohttp 为 Client 程序提供了一个全局函数 request(),用法如下:

async def main():resp = await aiohttp.request('GET', 'http://python.org/')print(resp)loop = asyncio.get_event_loop()
loop.run_until_complete(main())

可见 request() 只是 ClientSession 的一个简单封装,其步骤大致为:

  • 创建 TCPConnector
  • 创建 ClientSession
  • 调用 ClientSession._request()

建议不要直接使用 request(),而只把它当成 ClientSession 的一个样例。因为 Aiohttp 官方文档是 这样说的:

Don’t create a session per request. Most likely you need a session per application which performs all requests altogether.

A session contains a connection pool inside, connection reusage and keep-alives (both are on by default) may speed up total performance.

即,一个 request 用一个 session,太浪费;通常是一个 application 用一个 session。

一些小问题

我经常发现一个变量,明明可以是局部变量,却被当成了成员变量。

Request 里放了一个 response?

class ClientRequest:def send(self, conn):...self.response = self.response_class(self.method, self.original_url,writer=self._writer, ...)self.response._post_init(self.loop, self._session)return self.response

self.response 在 ClientRequest 其他地方并没有用到,是否可以改成局部变量?

ClientResponse.start() 里的 _protocol 应该用局部变量吧?

class ClientResponse:
   @asyncio.coroutinedef start(self, connection, read_until_eof=False):"""Start response processing."""self._closed = Falseself._protocol = connection.protocol

Python 的异步 IO:Aiohttp Client 代码分析相关推荐

  1. python asyncio_Python 异步 IO系列:认识asyncio

    Python的asyncio是使用 async/await 语法编写并发代码的标准库.通过上一篇文章,我们了解了它不断变化的发展历史.到了Python最新稳定版 3.7 这个版本,asyncio又做了 ...

  2. python异步的发展历程_深入了解Python的异步IO:概念和历史

    前面发表了<简说Python Web异步框架>一文后,很多朋友希望能更多了解Python关于asyncio的知识.正好,我也想深入理解理解这方面的知识,于是就促成了这篇文章. 一.软件系统 ...

  3. python开源代码-这7个开源的Python库,让你轻松代码分析

    原标题:这7个开源的Python库,让你轻松代码分析 开源最前线(ID:OpenSourceTop) 猿妹编译 来源:https://opensource.com/article/18/7/7-pyt ...

  4. Thrift异步IO服务器源码分析

    http://yanyiwu.com/work/2014/12/06/thrift-tnonblockingserver-analysis.html 最近在使用 libevent 开发项目,想起之前写 ...

  5. Python黑魔法--异步IO(asyncio)协程 (三)

    接: https://blog.csdn.net/Enjolras_fuu/article/details/83869864 不同线程的事件循环 很多时候,我们的事件循环用于注册协程,而有的协程需要动 ...

  6. python百度ai文字识别、代码分析_python利用百度AI实现文字识别功能

    本文为大家分享了python实现文字识别功能大全,供大家参考,具体内容如下 1.通用文字识别 # -*- coding: UTF-8 -*- from aip import AipOcr # 定义常量 ...

  7. Python 异步 IO 、协程、asyncio、async/await、aiohttp

    From :廖雪峰 异步IO :https://www.liaoxuefeng.com/wiki/1016959663602400/1017959540289152 Python Async/Awai ...

  8. python asyncio教程_python中使用asyncio实现异步IO实例分析

    1.说明 Python实现异步IO非常简单,asyncio是Python 3.4版本引入的标准库,直接内置了对异步IO的支持. asyncio的编程模型就是一个消息循环.我们从asyncio模块中直接 ...

  9. Python网络请求、JSON转换、多线程、异步IO

    在 Python 众多的 HTTP 客户端中,最有名的莫过于 requests . aiohttp 和 httpx . 在不借助其他第三方库的情况下, requests 只能发送同步请求: aioht ...

最新文章

  1. 手把手教你安装深度学习软件环境(附代码)
  2. html5新年网页做给父母的,春节回家,要陪父母做这十件小事
  3. Mycat1.6之注解多租户
  4. hive解决数据倾斜问题_八种解决 Spark 数据倾斜的方法
  5. 服务器抽屉式维护,一种服务器用可顺序运动的滑轨
  6. 怎样安装两个tomcat,怎样配置
  7. 谷歌浏览器实现直接打印效果
  8. mysql的orm框架_Mysql-Sqlalchemy-ORM框架
  9. 如果你对web前端学习感到迷茫的话请看完本文
  10. Linq中查询List组合相同值数量大于1
  11. setInterval 和 setTimeout
  12. 新能源电动汽车的充电
  13. 中国历史朝代变迁简介
  14. java stl分解_stl文件格式解析代码--java版
  15. CAD和GIS绘制图形分析
  16. 龙与地下城中的人物属性
  17. 今日添加ubuntu7.10配置
  18. k8s原生的CI/CD工具tekton
  19. android图片转视频
  20. 由ThinkServer RQ940死机到系统无法引导带来的感想

热门文章

  1. 量子位智库报告:三分钟看懂ChatGPT | 附下载
  2. windows下移植别人配置好的python环境
  3. 通过封装和数字万用表判断贴片二极管、稳压管、LED、正负级性
  4. java 匿名函数_Java中的lambda匿名函数使用
  5. 安卓app测试之流量监控
  6. sap docking 简单分屏alv
  7. Codis学习笔记--Java连接codis
  8. 阿里AI天池大赛-天猫复购预测-基于XGBoost模型预测
  9. 学生护眼灯怎么选择?推荐学生护眼台灯十大名牌排行榜
  10. IDEA 的 plugins 搜不到任何的东西