我刚刚将我的请求库升级到2.3.0(从0.14.0开始),我的自定义身份验证不再有效。问题是我们使用的自定义身份验证会在请求中附加API密钥和时间戳,因此我们所有的帮助方法都不需要这样做。
class APIAuth(requests.auth.AuthBase):
def __call__(self, request):
api_secret = settings.API_SHARED_SECRET
api_key = settings.API_KEY
request.params.update(dict(
api_key=api_key,
timestamp=int(time.time()*1000)))
signature = base64.b64encode(hmac.new(
api_secret,
msg=unquote(request.full_url),
digestmod=hashlib.sha256
).digest()).decode()
request.headers['Authorization'] = "signature {0}".format(signature)
return request
错误:
AttributeError: 'PreparedRequest' object has no attribute 'params'
准备好的请求不允许修改params dict,大概是因为它已经被构造了。有没有一种简单的方法来更新我们的自定义身份验证中的params dict,使任何现有的params保持不变?或者我必须咬紧牙关并为每个请求方法添加这两个参数?
答案 0 :(得分:3)
实际上,现在传入PreparedRequest
,并且已经从参数设置了URL查询字符串。
但是,PreparedRequest.prepare_url()
method会让您使用其他参数更新网址:
class APIAuth(requests.auth.AuthBase):
def __call__(self, request):
api_secret = settings.API_SHARED_SECRET
api_key = settings.API_KEY
request.prepare_url(request.url, dict(
api_key=api_key,
timestamp=int(time.time()*1000)))
signature = base64.b64encode(hmac.new(
api_secret,
msg=unquote(request.full_url),
digestmod=hashlib.sha256
).digest()).decode()
request.headers['Authorization'] = "signature {0}".format(signature)
return request
演示:
>>> import requests
>>> prepared = requests.Request(url='http://httpbin.org/get').prepare()
>>> prepared.url
'http://httpbin.org/get'
>>> prepared.prepare_url(prepared.url, {'foo': 'bar', 'spam': 42})
>>> prepared.url
'http://httpbin.org/get?foo=bar&spam=42'
>>> prepared.prepare_url(prepared.url, {'monty': 'python'})
>>> prepared.url
'http://httpbin.org/get?foo=bar&spam=42&monty=python'
通过传递prepared.url
,URL会更新以添加额外参数。新参数始终是添加;如果新参数与已添加的参数具有相同的名称,则不会删除旧参数。