如何在python请求中处理401(未授权)

时间:2014-10-10 11:55:39

标签: python python-requests

我想要做的是从网站获取并且如果该请求返回401,则重做我的身份验证摆动(可能已过期)并再试一次。但我不想第三次尝试,因为这将是我的身份验证摆弄错误的凭据。有没有人有一个很好的方法做到这一点,并没有涉及到适当的丑陋代码,理想情况下在python请求库中,但我不介意改变。

3 个答案:

答案 0 :(得分:3)

我认为它不会比这更难看:

import requests
from requests.auth import HTTPBasicAuth

response = requests.get('http://your_url')

if response.status_code == 401:    
    response = requests.get('http://your_url', auth=HTTPBasicAuth('user', 'pass'))

if response.status_code != 200:
    # Definitely something's wrong

答案 1 :(得分:1)

你可以将它包装在一个函数中并使用装饰器来评估响应并在401上重试auth。然后你只需要装饰任何需要这个重新验证逻辑的函数....

更新: 根据要求,一个代码示例。我担心这个是一段旧代码,基于Python 2,但你会明白这一点。这个将按照settings.NUM_PLATFORM_RETRIES中的定义多次重试http调用,并在auth失败时调用refresh_token。你可以调整用例和结果。 然后,您可以围绕方法使用此装饰器:

@retry_on_read_error
def some_func():
   do_something()



def retry_on_read_error(fn):
    """
    Retry Feed reads on failures
    If a token refresh is required it is performed before retry.
    This decorator relies on the model to have a refresh_token method defined, othewise it will fail
    """
    @wraps(fn)
    def _wrapper(self, *args, **kwargs):
        for i in range(settings.NUM_PLATFORM_RETRIES):
            try:
                res = fn(self, *args, **kwargs)

                try:
                    _res = json.loads(res)
                except ValueError:
                    # not a json response (could be local file read or non json data)
                    return res

                if 'error' in _res and _res['error']['status'] in (401, 400):
                    raise AccessRefusedException(_res['error']['message'])

                return res
            except (urllib2.URLError, IOError, AccessRefusedException) as e:
                if isinstance(e, AccessRefusedException):
                    self.refresh_token()
                continue
        raise ApiRequestFailed(
            "Api failing, after %s retries: %s" % (settings.NUM_PLATFORM_RETRIES, e), args, kwargs
        )

    return _wrapper

答案 2 :(得分:0)

您可以使用类似的东西

library(broom)
contrived_data %>% 
       group_by(subgroup) %>%
       summarize(avg     = mean(value),
                 std_dev = sd(value), 
                 out = list(tidy(ks.test(value, "pnorm", mean = 5, sd = 1)))) %>%
       unnest_wider(c(out))