异步http接口调用库:httpx
谈到http接口调用,Requests大家并不陌生,例如,robotframework-requests、HttpRunner等HTTP接口测试库/框架都是基于它开发。这里将介绍另一款http接口测试框架:httpx。
它的API和Requests高度一致。
github: https://github.com/encode/httpx
安装:
> pip install httpx
httpx 简单使用
当然,它是不支持python2.x的。
- 简单的get调用
import httpx
r = httpx.get("http://httpbin.org/get")
print(r.status_code)
print(r.json())
执行结果:
200
{'args': {}, 'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Host': 'httpbin.org', 'User-Agent': 'python-httpx/0.12.1', 'X-Amzn-Trace-Id': 'Root=1-5ea5b58c-e446c44392ea090809e8a4bc'}, 'origin': '113.97.33.224', 'url': 'http://httpbin.org/get'}
- 带参数的post调用
import httpx
payload = {'key1': 'value1', 'key2': 'value2'}
r = httpx.post("http://httpbin.org/post", data=payload)
print(r.json())
执行结果:
{'args': {}, 'data': '', 'files': {}, 'form': {'key1': 'value1', 'key2': 'value2'}, 'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Content-Length': '23', 'Content-Type': 'application/x-www-form-urlencoded', 'Host': 'httpbin.org', 'User-Agent': 'python-httpx/0.12.1', 'X-Amzn-Trace-Id': 'Root=1-5ea5b61d-1871d10e80b8324e48ea475e'}, 'json': None, 'origin': '113.97.33.224', 'url': 'http://httpbin.org/post'}
你会发现这几乎和requests一模一样,只不过把requests 换成了httpx。
httpx 异步调用
接下来认识httpx的异步调用:
import httpx
import asyncio
async def main():
async with httpx.AsyncClient() as client:
resp = await client.get('http://httpbin.org/get')
result = resp.json()
print(result)
asyncio.run(main())
这里用到了async 、await, asyncio等,等参考我关于python异步I/O的基础介绍:https://www.cnblogs.com/fnng/p/12757395.html
异步的调用的优势
我们发现,采用异步会让接口的调用更加复杂,那为什么还要使用异步呢?当你要调用1000次接口时,那么异步调用可以让你的调用更快。接下来我们通过简单让例子进行对比。
以我flask开发的简单接口为例子:
https://github.com/defnngj/learning-API-test
为了测试的更加准确性,我将flask服务部署在了另一台电脑,测试机与被测服务分离。
- httpx 同步调用
# 同步调用
import time
import httpx
def make_request(client):
resp = client.get('http://192.168.0.7:5000')
result = resp.json()
# print(result)
assert result["code"] == 10200
def main():
session = httpx.Client()
# 1000 次调用
for _ in range(1000):
make_request(session)
if __name__ == '__main__':
# 开始
start = time.time()
main()
# 结束
end = time.time()
print(f'同步:发送1000次请求,耗时:{end - start}')
结果:
...
同步:发送1000次请求,耗时:52.948561906814575
- httpx 异步调用
# 异步调用
import httpx
import asyncio
import time
async def request(client):
resp = await client.get('http://192.168.0.7:5000')
result = resp.json()
# print(result)
assert result["code"] == 10200
async def main():
async with httpx.AsyncClient() as client:
# # 开始
# start = time.time()
# 1000 次调用
task_list = []
for _ in range(1000):
req = request(client)
task = asyncio.create_task(req)
task_list.append(task)
await asyncio.gather(*task_list)
if __name__ == "__main__":
#开始
start = time.time()
asyncio.run(main())
# 结束
end = time.time()
print(f'异步:发送1000次请求,耗时:{end - start}')
结果:
...
异步:发送1000次请求,耗时:3.903275728225708
将httpx用于请求端,同步与异步请求差距非常明显。
以上的例子已经放到 learning-API-test github项目
总结
* 这里只是拿 flask 非异步框架做为接口服务端进行对比,如果如果将接口服务同样换作前面介绍的 snaic 异步框架,上面的两组测试对比并不明显(snaic的异步接口服务处理同步请求更快),在安装 snaic的时候会发现,他同样也集成了 httpx 库。
* 为什么要学习异步,因为我们公司有很多接口是异步调用的,所以,我想真正搞懂这个概念,就这么简单!保持在工作中对技术的好奇心。
- 异步与多线程的区别?这是我在学习 异步时候的一个疑问,我找到了一个比较形象的例子。
以火车站购票场景为例:一个火车站为一个进程,一个窗口和售票员的组合为一个线程:
- 多线程:火车站开了N个窗口售票员,我们去买票,会有工作人员(CPU)指定我们去某个窗口买票,你被安排到某个窗口后,告诉售票员你的请求(咨询或买票),售票员执行操作,如果这个过程中发送的阻塞,也是窗口售票员的阻塞(比如查票的过程),但是因为你开了很多个窗口,其他买票的人可以被安排去另外的空闲窗口,如果所有窗口都满了,工作人员就不会给你安排了,直到有空的窗口出来;
- 多进程(并行):建多个火车站售票,火车站与火车站间互不影响,看买票的自己想去哪里(这里不讨论负载均衡);
- 异步:火车站只有一个窗口售票员,但是窗口前有一个登记台(事件循环),你把你想买的票告诉给登记台,并留下你的手机(回调函数),然后你就可以走了,由于登记台只是登记了你的请求,并没有做任何其他操作,所以这个耗时基本忽略不计的。之后售票员处理完了上一个任务了,就会自己去登记台取剩下的未完成的任务,直到取到你的任务,操作完后,有票没票都会通过手机通知你,如果有票还会往你的手机发车票的二维码;
异步http接口调用库:httpx的更多相关文章
- ♫【异步】短小强悍的JavaScript异步调用库
短小强悍的JavaScript异步调用库 var queue = function(funcs, scope) { (function next() { if(funcs.length > 0) ...
- Java按时间梯度实现异步回调接口
1. 背景 在业务处理完之后,需要调用其他系统的接口,将相应的处理结果通知给对方,若是同步请求,假如调用的系统出现异常或是宕机等事件,会导致自身业务受到影响,事务会一直阻塞,数据库连接不够用等异常现象 ...
- 友盟推送 .NET (C#) 服务端 SDK rest api 调用库
友盟推送 .NET SDK rest api 介绍 该版本是基于友盟推送2.3版本封装的,网上查询了下发现没有.NET版本的调用库,官方也没有封装.NET的版本,只有python.java.php版本 ...
- ThinkPHP整合支付宝即时到账接口调用
首先是在支付宝的蚂蚁金服开放平台下载PHP的demo: https://doc.open.alipay.com/doc2/detail?treeId=62&articleId=103566&a ...
- OpenCV4Android开发之旅(一)----OpenCV2.4简介及 app通过Java接口调用OpenCV的示例
转自: http://blog.csdn.net/yanzi1225627/article/details/16917961 开发环境:windows+ADT Bundle+CDT+OpenCV-2 ...
- 转: ES6异步编程: co函数库的含义与用法
转: ES6异步编程: co函数库的含义与用法 co 函数库是著名程序员 TJ Holowaychuk 于2013年6月发布的一个小工具,用于 Generator 函数的自动执行. 比如,有一个 Ge ...
- 十分钟搭建redis单机版 & java接口调用
本次单机版redis服务器搭建采用的包为redis-3.0.0.tar.gz,主要是记录下安装的心得,不喜勿喷! 一.搭建redis服务器单机版 1.上传redis-3.0.0.tar.gz到服务器上 ...
- Vue之状态管理(vuex)与接口调用
Vue之状态管理(vuex)与接口调用 一,介绍与需求 1.1,介绍 1,状态管理(vuex) Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态 ...
- 记一次TCP重发接口调用的问题
问题描述:基于微软RDP协议,使用开源rdp库与微软skpye软件进行基于tcp的p2p通讯,由于rdp协议传输原始图片数据较大,调用公司内部ice p2p通讯接口处会导致失败. 错误思路:一开始是怀 ...
随机推荐
- Nginx四层代理
Nginx支持四层代理 http://nginx.org/en/docs/stream/ngx_stream_core_module.html 该ngx_stream_core_module模块自1. ...
- js 函数的多图片懒加载(lazy) 带插件版完整解析
前言: 本人纯小白一个,有很多地方理解的没有各位大牛那么透彻,如有错误,请各位大牛指出斧正!小弟感激不尽. 本篇文章为您分析一下原生JS实现图片懒加载效果 页面需求 1 ...
- 徐州赛区网络预赛 D Easy Math
比赛快结束的适合看了一下D题,发现跟前几天刚刚做过的HDU 5728 PowMod几乎一模一样,当时特兴奋,结果一直到比赛结束都一直WA.回来仔细一琢磨才发现,PowMod这道题保证了n不含平方因子, ...
- springboot docker jenkins 自动化部署并上传镜像
springboot + docker + jenkins自动化部署项目,jenkins.mysql.redis都是docker运行的,并且没有使用虚拟机,就在阿里云服务器(centos7)运行 1. ...
- Galera将死——MySQL Group Replication正式发布
2016-12-14 来源:InsideMySQL 作者:姜承尧 MySQL Group Replication GA 很多同学表示昨天的从你的全世界路过画风不对,好在今天MySQL界终于有大事情发生 ...
- 使用docker搭建自己的博客(一)
购买服务器 首先服务器选择腾讯云学生服务器,25岁以下实名认证后月租10块,还是很适合我这种简约派的 又财大气粗买了个一年的域名,后面涨价再说吧 安装docker 使用xshell连上服务器 安装必要 ...
- 【Java8新特性】你知道Java8为什么要引入Lambda表达式吗?
写在前面 这是一道真实的面试题,一个读者朋友出去面试,面试官竟然问他这样一个问题:你说说Java8中为什么引入Lambda表达式?引入Lambda表达式后有哪些好处呢?还好这个朋友对Java8早有准备 ...
- 详解十大经典数据挖掘算法之——Apriori
本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是机器学习专题的第19篇文章,我们来看经典的Apriori算法. Apriori算法号称是十大数据挖掘算法之一,在大数据时代威风无两,哪 ...
- 绕WAF文章收集
在看了bypassword的<在HTTP协议层面绕过WAF>之后,想起了之前做过的一些研究,所以写个简单的短文来补充一下文章里“分块传输”部分没提到的两个技巧. 技巧1 使用注释扰乱分块数 ...
- D - Pearls HDU - 1300 斜率dp+二分
D - Pearls HDU - 1300 这个题目也是一个比较裸的斜率dp,依照之前可以推一下这个公式,这个很好推 这个注意题目已经按照价格升序排列序,所以还是前缀和还是单调的. sum[i] 表示 ...