迷途小書童
讀完需要
9
分鐘速讀僅需 3 分鐘
1
? ?
環(huán)境
windows 10 64bit
python 3.8
httpx 0.23.0
2
? ?
簡介
之前我們介紹過使用 requests ( https://xugaoxiang.com/2020/11/28/python-module-requests/ ) 來進(jìn)行 http 操作,本篇介紹另一個(gè)功能非常類似的第三方庫 httpx,它提供了同步和異步的 API,同時(shí)支持 HTTP/1.1 和 HTTP/2,是一個(gè)全功能的 HTTP 客戶端。
3
? ?
安裝
使用 pip 安裝,執(zhí)行命令
pip install httpx
在安裝 python 庫的同時(shí),還安裝了命令行工具 httpx.exe
來看幾個(gè)簡單的示例
# get方法請求url
httpx.exe https://github.com -m get
# post方法請求url,同時(shí)上傳一個(gè)文本文件
httpx.exe https://domain.com -m post -f test.txt
4
? ?
基本使用
還是拿之前的 flask 后端例子來講
from flask import Flask, jsonify, request
from flask_restful import Api, Resource, reqparse
USERS = [
{"name": "zhangsan"},
{"name": "lisi"},
{"name": "wangwu"},
{"name": "zhaoliu"}
]
class Users(Resource):
def get(self):
return jsonify(USERS)
def post(self):
args = reqparse.RequestParser() \
.add_argument('name', type=str, location='json', required=True, help="名字不能為空") \
.parse_args()
if args['name'] not in USERS:
USERS.append({"name": args['name']})
return jsonify(USERS)
def delete(self):
USERS = []
return jsonify(USERS)
class UserId(Resource):
def __init__(self):
self.parser = reqparse.RequestParser()
self.parser.add_argument('name', type=str)
self.parser.add_argument('age', type=int)
def get(self, userid):
datas = self.parser.parse_args()
return jsonify(
{"name": USERS[int(userid)].get('name'), "age": datas.get('age')}
)
def post(self, userid):
file = request.files['file']
file.save('flask_file.txt')
return jsonify({
'msg' : 'success'
})
app = Flask(__name__)
api = Api(app, default_mediatype="application/json")
api.add_resource(Users, '/users')
api.add_resource(UserId, '/user/<userid>')
app.run(host='0.0.0.0', port=5000, use_reloader=True, debug=True)
啟動后端服務(wù)后,接著來看看客戶端的請求。httpx 的基本用法和 requests 近乎相同,很多時(shí)候,只需要將原來的代碼中的 requests 換成 httpx 就行。
import httpx
# 使用get方法
r = httpx.get('http://127.0.0.1:5000/users')
# http返回碼
print(r.status_code)
# http頭
print(r.headers['content-type'])
# 也可以使用 r.headers.get('content-type')
# 接口返回的json
print(r.json())
import httpx
import json
param = {'name': 'xugaoxiang'}
headers = {"Content-type": "application/json"}
# post請求
r = httpx.post('http://127.0.0.1:5000/users', data=json.dumps(param), headers=headers)
print(r.status_code)
print(r.json())
import httpx
# delete請求
r = httpx.delete('http://127.0.0.1:5000/users')
print(r.json())
print(r.status_code)
除此之外,像 put、head、options 方法的請求也是類似的,這里就不再舉例了
r = httpx.put(url, data={'key': 'value'})
r = httpx.head(url)
r = httpx.options(url)
5
? ?
高級用法
上面示例中的用法是 httpx 提供的 top-level API,這在寫一些測試腳本或者做系統(tǒng)原型時(shí)問題不大,但真正要在實(shí)際項(xiàng)目中去用的話,就會有性能上的問題。這是因?yàn)?httpx 在進(jìn)行每一次的請求時(shí)都會去重新建立一個(gè)鏈接,也就是原有的鏈接沒有被復(fù)用,這在高并發(fā)的情況就顯得特別低效。
類似于 requests 模塊中的 Session,httpx 提供了 Client,它會使用 http 連接池,大大減少鏈接重新建立的次數(shù),減少 cpu 的使用率,降低了網(wǎng)絡(luò)擁堵,提升系統(tǒng)效率。
Client 的使用比較簡單,推薦的做法是將 Client 作為 context 管理器,看下面的示例
import httpx
with httpx.Client() as client:
# 請求部分,將原來的 httpx 換成 client 就可以了,參數(shù)是一樣的
r = client.get('http://127.0.0.1:5000/users')
print(r.json())
print(r.status_code)
6
? ?
同步請求與異步請求
默認(rèn)情況下,httpx 提供的是標(biāo)準(zhǔn)同步 API,如果想使用異步請求,可以這樣
import httpx
import asyncio
async def make_async_request():
async with httpx.AsyncClient() as client:
r = await client.get('http://127.0.0.1:5000/users')
print(r.json())
print(r.status_code)
asyncio.run(make_async_request())
7
? ?
http2 支持
要使能 http2,我們需要額外安裝庫 httpx[http2]
# 這個(gè)包名取的太奇怪了
pip install httpx[http2]
然后在初始化 client 的時(shí)候加上 http2 的支持
with httpx.Client(http2=True) as client:
r = client.get('http://127.0.0.1:5000/users')
8文章來源:http://www.zghlxwxcb.cn/news/detail-663568.html
? ?
免費(fèi)社群文章來源地址http://www.zghlxwxcb.cn/news/detail-663568.html
到了這里,關(guān)于Python 的下一代 HTTP 客戶端的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!