Python 的异步 IO:Aiohttp Client 代码分析
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'])
由 host
,port
和 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 代码分析相关推荐
- python asyncio_Python 异步 IO系列:认识asyncio
Python的asyncio是使用 async/await 语法编写并发代码的标准库.通过上一篇文章,我们了解了它不断变化的发展历史.到了Python最新稳定版 3.7 这个版本,asyncio又做了 ...
- python异步的发展历程_深入了解Python的异步IO:概念和历史
前面发表了<简说Python Web异步框架>一文后,很多朋友希望能更多了解Python关于asyncio的知识.正好,我也想深入理解理解这方面的知识,于是就促成了这篇文章. 一.软件系统 ...
- python开源代码-这7个开源的Python库,让你轻松代码分析
原标题:这7个开源的Python库,让你轻松代码分析 开源最前线(ID:OpenSourceTop) 猿妹编译 来源:https://opensource.com/article/18/7/7-pyt ...
- Thrift异步IO服务器源码分析
http://yanyiwu.com/work/2014/12/06/thrift-tnonblockingserver-analysis.html 最近在使用 libevent 开发项目,想起之前写 ...
- Python黑魔法--异步IO(asyncio)协程 (三)
接: https://blog.csdn.net/Enjolras_fuu/article/details/83869864 不同线程的事件循环 很多时候,我们的事件循环用于注册协程,而有的协程需要动 ...
- python百度ai文字识别、代码分析_python利用百度AI实现文字识别功能
本文为大家分享了python实现文字识别功能大全,供大家参考,具体内容如下 1.通用文字识别 # -*- coding: UTF-8 -*- from aip import AipOcr # 定义常量 ...
- Python 异步 IO 、协程、asyncio、async/await、aiohttp
From :廖雪峰 异步IO :https://www.liaoxuefeng.com/wiki/1016959663602400/1017959540289152 Python Async/Awai ...
- python asyncio教程_python中使用asyncio实现异步IO实例分析
1.说明 Python实现异步IO非常简单,asyncio是Python 3.4版本引入的标准库,直接内置了对异步IO的支持. asyncio的编程模型就是一个消息循环.我们从asyncio模块中直接 ...
- Python网络请求、JSON转换、多线程、异步IO
在 Python 众多的 HTTP 客户端中,最有名的莫过于 requests . aiohttp 和 httpx . 在不借助其他第三方库的情况下, requests 只能发送同步请求: aioht ...
最新文章
- 手把手教你安装深度学习软件环境(附代码)
- html5新年网页做给父母的,春节回家,要陪父母做这十件小事
- Mycat1.6之注解多租户
- hive解决数据倾斜问题_八种解决 Spark 数据倾斜的方法
- 服务器抽屉式维护,一种服务器用可顺序运动的滑轨
- 怎样安装两个tomcat,怎样配置
- 谷歌浏览器实现直接打印效果
- mysql的orm框架_Mysql-Sqlalchemy-ORM框架
- 如果你对web前端学习感到迷茫的话请看完本文
- Linq中查询List组合相同值数量大于1
- setInterval 和 setTimeout
- 新能源电动汽车的充电
- 中国历史朝代变迁简介
- java stl分解_stl文件格式解析代码--java版
- CAD和GIS绘制图形分析
- 龙与地下城中的人物属性
- 今日添加ubuntu7.10配置
- k8s原生的CI/CD工具tekton
- android图片转视频
- 由ThinkServer RQ940死机到系统无法引导带来的感想