談到http接口調(diào)用,Requests大家并不陌生,例如,robotframework-requests、HttpRunner等HTTP接口測試庫/框架都是基于它開發(fā)。這里將介紹另一款http接口測試框架:httpx。
它的API和Requests高度一致。
github: GitHub - encode/httpx: A next generation HTTP client for Python. ??
安裝:
> pip install httpx
httpx 簡單使用
當(dāng)然,它是不支持python2.x的。
- 簡單的get調(diào)用
import httpx
r = httpx.get("http://httpbin.org/get")
print(r.status_code)
print(r.json())
執(zhí)行結(jié)果:
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'}
- 帶參數(shù)的post調(diào)用
import httpx
payload = {'key1': 'value1', 'key2': 'value2'}
r = httpx.post("http://httpbin.org/post", data=payload)
print(r.json())
執(zhí)行結(jié)果:
{'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'}
你會(huì)發(fā)現(xiàn)這幾乎和requests一模一樣,只不過把requests 換成了httpx。
httpx?異步調(diào)用
接下來認(rèn)識(shí)httpx的異步調(diào)用:
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等,等參考我關(guān)于python異步I/O的基礎(chǔ)介紹:https://www.cnblogs.com/fnng/p/12757395.html
異步的調(diào)用的優(yōu)勢
我們發(fā)現(xiàn),采用異步會(huì)讓接口的調(diào)用更加復(fù)雜,那為什么還要使用異步呢?當(dāng)你要調(diào)用1000次接口時(shí),那么異步調(diào)用可以讓你的調(diào)用更快。接下來我們通過簡單讓例子進(jìn)行對(duì)比。
以我flask開發(fā)的簡單接口為例子:
GitHub - defnngj/learning-API-test: learning API test
為了測試的更加準(zhǔn)確性,我將flask服務(wù)部署在了另一臺(tái)電腦,測試機(jī)與被測服務(wù)分離。
- httpx 同步調(diào)用
# 同步調(diào)用
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 次調(diào)用
for _ in range(1000):
make_request(session)
if __name__ == '__main__':
# 開始
start = time.time()
main()
# 結(jié)束
end = time.time()
print(f'同步:發(fā)送1000次請(qǐng)求,耗時(shí):{end - start}')
結(jié)果:
...
同步:發(fā)送1000次請(qǐng)求,耗時(shí):52.948561906814575
- httpx 異步調(diào)用
# 異步調(diào)用
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 次調(diào)用
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())
# 結(jié)束
end = time.time()
print(f'異步:發(fā)送1000次請(qǐng)求,耗時(shí):{end - start}')
結(jié)果:
...
異步:發(fā)送1000次請(qǐng)求,耗時(shí):3.903275728225708
將httpx用于請(qǐng)求端,同步與異步請(qǐng)求差距非常明顯。
以上的例子已經(jīng)放到 learning-API-test github項(xiàng)目
總結(jié)
* 這里只是拿 flask 非異步框架做為接口服務(wù)端進(jìn)行對(duì)比,如果如果將接口服務(wù)同樣換作前面介紹的 snaic 異步框架,上面的兩組測試對(duì)比并不明顯(snaic的異步接口服務(wù)處理同步請(qǐng)求更快),在安裝 snaic的時(shí)候會(huì)發(fā)現(xiàn),他同樣也集成了 httpx 庫。
* 為什么要學(xué)習(xí)異步,因?yàn)槲覀児居泻芏嘟涌谑钱惒秸{(diào)用的,所以,我想真正搞懂這個(gè)概念,就這么簡單!保持在工作中對(duì)技術(shù)的好奇心。
異步與多線程的區(qū)別?這是我在學(xué)習(xí) 異步時(shí)候的一個(gè)疑問,我找到了一個(gè)比較形象的例子。
以火車站購票場景為例:一個(gè)火車站為一個(gè)進(jìn)程,一個(gè)窗口和售票員的組合為一個(gè)線程:
多線程:火車站開了N個(gè)窗口售票員,我們?nèi)ベI票,會(huì)有工作人員(CPU)指定我們?nèi)ツ硞€(gè)窗口買票,你被安排到某個(gè)窗口后,告訴售票員你的請(qǐng)求(咨詢或買票),售票員執(zhí)行操作,如果這個(gè)過程中發(fā)送的阻塞,也是窗口售票員的阻塞(比如查票的過程),但是因?yàn)槟汩_了很多個(gè)窗口,其他買票的人可以被安排去另外的空閑窗口,如果所有窗口都滿了,工作人員就不會(huì)給你安排了,直到有空的窗口出來;
多進(jìn)程(并行):建多個(gè)火車站售票,火車站與火車站間互不影響,看買票的自己想去哪里(這里不討論負(fù)載均衡);
異步:火車站只有一個(gè)窗口售票員,但是窗口前有一個(gè)登記臺(tái)(事件循環(huán)),你把你想買的票告訴給登記臺(tái),并留下你的手機(jī)(回調(diào)函數(shù)),然后你就可以走了,由于登記臺(tái)只是登記了你的請(qǐng)求,并沒有做任何其他操作,所以這個(gè)耗時(shí)基本忽略不計(jì)的。之后售票員處理完了上一個(gè)任務(wù)了,就會(huì)自己去登記臺(tái)取剩下的未完成的任務(wù),直到取到你的任務(wù),操作完后,有票沒票都會(huì)通過手機(jī)通知你,如果有票還會(huì)往你的手機(jī)發(fā)車票的二維碼;
總結(jié):
感謝每一個(gè)認(rèn)真閱讀我文章的人?。?!
作為一位過來人也是希望大家少走一些彎路,如果你不想再體驗(yàn)一次學(xué)習(xí)時(shí)找不到資料,沒人解答問題,堅(jiān)持幾天便放棄的感受的話,在這里我給大家分享一些自動(dòng)化測試的學(xué)習(xí)資源,希望能給你前進(jìn)的路上帶來幫助。
?
文檔獲取方式:
加入我的軟件測試交流群:1007119548免費(fèi)獲取~(同行大佬一起學(xué)術(shù)交流,每晚都有大佬直播分享技術(shù)知識(shí)點(diǎn))
這份文檔,對(duì)于想從事【軟件測試】的朋友來說應(yīng)該是最全面最完整的備戰(zhàn)倉庫,這個(gè)倉庫也陪伴我走過了最艱難的路程,希望也能幫助到你!文章來源:http://www.zghlxwxcb.cn/news/detail-791589.html
以上均可以分享,只需要你搜索vx公眾號(hào):程序員雨果,即可免費(fèi)領(lǐng)取文章來源地址http://www.zghlxwxcb.cn/news/detail-791589.html
到了這里,關(guān)于異步http接口調(diào)用庫:httpx的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!