title: Python Requests - retry request after re-authentication
body: <p>I am using <code>Python</code> 3.5.1 with <code>Requests</code> 2.9.1. My use case as follows: I need to authenticate (get a token) from service T and use it as value of the <code>Authorization</code> header when making requests to a resource server R. The token expires at some point and a new one needs to be fetched.</p>
  
  <p>I have an application using <code>requests</code>, which when started first fetches a token and remembers it - sets in the <code>Session</code> used for requests to R. From then on for 3 minutes, everything works as a charm. After 3 minutes, I get <code>unauthorized</code> responses as the token is invalid.</p>
  
  <p>I use <code>Session</code> for all requests <strong>except</strong> for the one to authenticate; this call updates the <code>Authorization</code> header on the <code>Session</code> for other requests to use.</p>
  
  <p>I created code to re-authenticate automatically when <code>unauthorized</code> is detected, using the <code>response</code> hook (set only on the <code>Session</code>), here is the code:</p>
  
  <pre><code>def __hook(self, res, *args, **kwargs):
      if res.status_code == requests.codes.unauthorized:
          print('Token expired, refreshing')
          self.auth() # sets the token on self.__session
  
          req = res.request
          print('Resending request', req.method, req.url, req.headers)
          req.headers['Authorization'] = self.__session.headers['Authorization'] # why is it needed?
  
          return self.__session.send(res.request)
  </code></pre>
  
  <p>Basically, it even works. There are a couple of issues, though:</p>
  
  <ol>
  <li><p>Why is it necessary to re-set the <code>Authorization</code> header on the request, even though the session is updated and is used to resend the original request? Without the line, the application will just keep on refreshing the token as the new one is never used, this can be seen in the output, the token is the original one which caused the automatic refresh.</p></li>
  <li><p>How can I make the code more robust, i.e. prevent endless recursion (I am not sure whether it is possible in reality, but with the line setting the <code>Authorization</code> header on the retried request it will just go on an on)? I was thinking of setting a custom header, and if the hooks discovers the failed request has it, it would not re-authenticate and resend. Is there anything better?
  <strong>Edit:</strong> it turns out it is possible to get an (almost) endless loop (it is recursive, after all) if the configuration is wrong: the tokens are taken for one environment (like STAGING), but the resource server is from another (TEST) - the <code>auth</code> request will succeed but the token is actually incorrect for the resource server. For the time being I implemented the 'special' header solution mentioned above.</p></li>
  </ol>
  
  <p>Is this a good approach in general or is there anything better suited for the task in <code>requests</code>?</p>