【发布时间】:2021-07-14 08:43:53
【问题描述】:
来自https://docs.python-requests.org/en/master/user/authentication/的文档
我收集到我自己的 Auth 类中的 __call__ 函数应该有 r 参数,
但是,当我在 requests.get(auth=MyClass) 中调用此类时,我收到错误 TypeError: __call__() missing 1 required positional argument: 'r'
我的课程代码可以在这里找到https://pastebin.com/YDZ2DeaT
import requests
import time
import base64
from requests.auth import AuthBase
class TokenAuth(AuthBase):
"""Refreshes SkyKick token, for use with all Skykick requests"""
def __init__(self, Username: str, SubKey: str):
self.Username = Username
self.SubKey = SubKey
# Initialise with no token and instant expiry
self.Token = None
self.TokenExpiry = time.time()
self.Headers = {
# Request headers
'Content-Type' : 'application/x-www-form-urlencoded',
'Ocp-Apim-Subscription-Key': self.SubKey,
}
self.Body = {
# Request body
'grant_type': 'client_credentials',
'scope' : 'Partner'
}
def regenToken(self):
# Sends request to regenerate token
try:
# Get key from API
response = requests.post("https://apis.skykick.com/auth/token",
headers=self.Headers,
auth=(self.Username, self.SubKey),
data=self.Body,
).json()
except:
raise Exception("Sending request failed, check connection.")
# API errors are inconsistent, easiest way to catch them
if "error" in response or "statusCode" in response:
raise Exception(
"Token requesting failed, cannot proceed with any Skykick actions, exiting.\n"
f"Error raised was {response}")
# Get token from response and set expiry
self.Token = response["access_token"]
self.TokenExpiry = time.time() + 82800
def __call__(self, r):
# If token expiry is now or in past, call regenToken
if self.TokenExpiry <= time.time():
self.regenToken()
# Set headers and return complete requests.Request object
r.headers["Authorization"] = f"Bearer {self.Token}"
return r
# Initialise our token class, so it is ready to call
TokenClass = TokenAuth("test", "1234")
#Send request with class as auth method.
requests.get("https://apis.skykick.com/whoami", auth=TokenClass())
我已经尝试使用示例代码,它可以工作,但我无法弄清楚为什么我的代码不起作用。
python-requests 版本是 2.25.1
【问题讨论】:
-
如果我创建一个空白 Request 对象,并将其传递到请求中,它可以工作,
r = requests.Request() response = requests.get("https://apis.skykick.com/whoami", auth=TokenClass(r)) Traceback这与文档显示用法的方式不同。 -
TokenClass = TokenAuth("test", "1234")您似乎正在从一个类中创建一个对象,然后调用该对象并将其传入。您不应该只传入TokenClass的实例吗? -
@Alex028502 我不太确定有什么区别,你的意思是用 requests.get(auth=TokenAuth("test","1234")) 代替吗?