How to deal with 401 (unauthorised) in python requests

前端 未结 3 584
余生分开走
余生分开走 2021-01-06 05:58

What I want to do is GET from a site and if that request returns a 401, then redo my authentication wiggle (which may be out of date) and try again. But I don\'t want to try

3条回答
  •  再見小時候
    2021-01-06 06:42

    You could have wrapped this in a function and used a decorator to evaluate the response and retry the auth on 401. Then you only need to decorate any function that requires this re-auth logic....

    Update: As requested, a code example. I'm afraid this one is an old piece of code, Python 2 based, but you'll get the idea. This one will retry an http call a number of times as defined in settings.NUM_PLATFORM_RETRIES and will call a refresh_token on auth failures. you can adjust the use case and result to whatever. You can then use this decorator around methods:

    @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
    

提交回复
热议问题