title: Python: grequest and request give different response
body: <p><strong>My original task:</strong> Using <a href="https://developers.trello.com/advanced-reference/list" rel="nofollow">Trello API</a>, get data through HTTP GET requests. Run requests and process responses asynchronously, if possible. The API provider uses "https://" URL I access to with some key and token.</p>
  
  <p><strong>Tools I used:</strong></p>
  
  <ul>
  <li>Python 2.7.10 | Anaconda 2.3.0 (64-bit) | (default, May 28 2015, 16:44:52) [MSC v.1500 64 bit (AMD64)] on win32</li>
  <li><code>requests</code> library (just
  imported without installation)</li>
  <li><code>grequests</code> library (installed via pip
  from <a href="https://github.com/kennethreitz/grequests.git" rel="nofollow">this git repo</a>)</li>
  </ul>
  
  <p><strong>Original task result:</strong> Only <code>requests</code> library worked, I've got Trello API's response, great. <code>grequests</code> library was failing with status_code = 302.</p>
  
  <p>I tried to understand why it happens and wrote two reproducible scripts.</p>
  
  <p><strong>Script A</strong> : <code>requests</code> library used:</p>
  
  <pre><code>import requests
  
  urls = [
      "https://www.google.com",
      "https://www.facebook.com/",
      "http://www.facebook.com/",
      "http://www.google.com",
      "http://fakedomain/",
      "http://python-tablib.org"
  ]
  
  # Run requests:
  for url in urls:
      print requests.get(url).status_code
  </code></pre>
  
  <p><strong>Console output A</strong> (having some exception because of <code>http://fakedomain/</code>) :</p>
  
  <pre><code>200
  200
  200
  200
  Traceback (most recent call last):
    File "req.py", line 14, in &lt;module&gt;
      print requests.get(url).status_code
    File "D:\python\lib\site-packages\requests\api.py", line 69, in get
      return request('get', url, params=params, **kwargs)
    File "D:\python\lib\site-packages\requests\api.py", line 50, in request
      response = session.request(method=method, url=url, **kwargs)
    File "D:\python\lib\site-packages\requests\sessions.py", line 465, in request
      resp = self.send(prep, **send_kwargs)
    File "D:\python\lib\site-packages\requests\sessions.py", line 573, in send
      r = adapter.send(request, **kwargs)
    File "D:\python\lib\site-packages\requests\adapters.py", line 415, in send
      raise ConnectionError(err, request=request)
  requests.exceptions.ConnectionError: ('Connection aborted.', gaierror(11001, 'getaddrinfo failed'))
  </code></pre>
  
  <p><strong>Script B</strong> : <code>grequests</code> library used with <code>map</code> to send asynchronous requests:</p>
  
  <pre><code>import grequests
  
  # This function will execute set of instructions when responses come:
  def proc_response(response, **kwargs):
      # do something ..
      print response
  
  # Request exception handler:
  def my_except_handler(request, excetion):
      print "Request failed : " + request.url
  
  urls = [
      "https://www.google.com",
      "https://www.facebook.com/",
      "http://www.facebook.com/",
      "http://www.google.com",
      "http://fakedomain/",
      "http://python-tablib.org"
  ]
  # Here is the list of tasks we build and run in parallel later:
  actions_list = []
  
  # Tasks list building:
  for url in urls:
      action_item = grequests.get(url, hooks = {'response' : proc_response})
      actions_list.append(action_item)
  
  # Run grequests:
  print grequests.map(actions_list, exception_handler=my_except_handler)
  </code></pre>
  
  <p><strong>Console output B</strong> :</p>
  
  <pre><code>&lt;Response [302]&gt;
  &lt;Response [302]&gt;
  &lt;Response [200]&gt;
  &lt;Response [301]&gt;
  &lt;Response [302]&gt;
  &lt;Response [200]&gt;
  Request failed : https://www.google.com
  Request failed : https://www.facebook.com/
  Request failed : http://www.facebook.com/
  Request failed : http://fakedomain/
  [None, None, None, &lt;Response [200]&gt;, None, &lt;Response [200]&gt;]
  </code></pre>
  
  <p>All I can conclude based on this information and my relatively small experience is the following - because of some reason <code>grequests</code> is rejected by remote websites <code>requests</code> works normally with. As long as 302 means redirection of some kind, it seems that <code>grequests</code> can not get data from source it is redirected to when <code>requests</code> can. <code>allow_redirects=True</code> in <code>get</code> method in Script B didn't solve the issue.</p>
  
  <p>I wonder why libraries give different response. It is possible that I miss something, and these two scripts have to return different results by design, not because of differences between two libraries.</p>
  
  <p>Thanks for your help in advance.</p>