Skip to main content
Warning: You are using the test version of PyPI. This is a pre-production deployment of Warehouse. Changes made here affect the production instance of TestPyPI (
Help us improve Python packaging - Donate today!

Like Requests, but using urllib2.

Project Description

A Python wrapper for the built-in urllib2 module. The API is compatible with the excellent Requests library, but omitting features such as sessions and support for keep-alive.

Notrequests is intended for doing HTTP requests on Google App Engine where Requests has some disadvantages.

It is not Python 3 compatible (yet).


From PyPI:

$ pip install notrequests

Or download and run setup as normal:

$ curl -L -o
$ unzip
$ cd notrequests-master
$ python install


Notrequests is compatible with the Requests API (or it tries to be).

>>> import notrequests
>>> response = notrequests.get('')
>>> response.status_code ==

But it doesn’t do everything that Requests does. There’s no session support, no keep-alive support and it reads the entire response into memory.

The response body is available as a byte string or as unicode, which relies on the server having sent a valid content-type header.

>>> response = notrequests.get('')
>>> response.headers['content-type']
'text/html; charset=utf-8'
>>> type(response.content)
<type 'str'>
>>> type(response.text)
<type 'unicode'>

Notrequests uses urllib2 but behaves more like Requests. So it won’t throw an exception on 4xx and 5xx responses.

>>> response = notrequests.get('')
>>> response.status_code ==

If you want to prevent Notrequests following a redirect response, you can use the allow_redirects keyword:

>>> url = ''
>>> response = notrequests.get(url)
>>> response.status_code
>>> response = notrequests.get(url, allow_redirects=False)
>>> response.status_code

On Google App Engine, the X-Appengine-Inbound-Appid header will only be set if the sending application doesn’t allow redirects!

You can do basic auth just like Requests (but not other authentication types):

>>> url = ''
>>> response = notrequests.get(url)
>>> response.status_code
>>> response = notrequests.get(url, auth=('alice', 'secret'))
>>> response.status_code

And send and decode JSON:

>>> import pprint
>>> response = notrequests.put('', json={'foo': ['bar', 'baz']})
>>> data = response.json()
>>> pprint.pprint(data)
{u'args': {},
 u'data': u'{"foo": ["bar", "baz"]}',
 u'files': {},
 u'form': {},
 u'headers': {u'Accept-Encoding': u'identity',
              u'Content-Length': u'23',
              u'Content-Type': u'application/json',
              u'Host': u'',
              u'User-Agent': u'notrequests/0.1'},
 u'json': {u'foo': [u'bar', u'baz']},
 u'origin': u'',
 u'url': u''}

If the server sent ‘Link’ headers in the response (often used by APIs to give links to the next page of results) then you can get the parsed links straight from the response object:

>>> response.headers['Link']
'<>; rel="next"'
>>> response.links['next']['url']

There’s also support for uploading files:

>>> import io
>>> fileobj = io.BytesIO('foo bar baz')
>>> response ='', files={'upload': fileobj})
>>> response.json()['files']
{u'upload': 'foo bar baz'}

As with Requests, the keys in the files dict are the form field input names and the values in the files dict can be a 2-tuple of file name with file object or byte string:

>>> files = {'upload': ('my-file.txt', b'Foo\nbar\nbaz.')}
>>> response ='', files=files)
>>> print
Content-Disposition: file; name="upload"; filename="my-file.txt"
Content-Type: text/plain


API compatibility

These are some features of the Requests API that Notrequests has not implemented. It isn’t a complete list, and it would be nice to have better support.

  • Sessions
  • Response.history
  • Response.raise_for_status()
  • Streaming uploads / downloads and iterating over data
  • Alternate names for status codes
  • Proxies


Run the tests with tox.

By default the tests make requests to, but you can run a local instance which will speed things up.

$ pip install httpbin gunicorn
$ gunicorn --bind httpbin:app
$ tox

Why not use Requests?

Google App Engine patches httplib in the standard library to use its urlfetch service, and restricts the sockets API to paid applications. Requests does not use httplib and uses sockets.

If you want to use the app identity service to authenticate connections between App Engine applications you have to use the urlfetch service, you cannot use Requests. Notrequests works because it uses urllib2, which uses httplib.

Release History

This version
History Node


History Node


History Node


History Node


Download Files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

File Name & Hash SHA256 Hash Help Version File Type Upload Date
(7.5 kB) Copy SHA256 Hash SHA256
Source Oct 8, 2015

Supported By

WebFaction WebFaction Technical Writing Elastic Elastic Search Pingdom Pingdom Monitoring Dyn Dyn DNS Sentry Sentry Error Logging CloudAMQP CloudAMQP RabbitMQ Heroku Heroku PaaS Kabu Creative Kabu Creative UX & Design Fastly Fastly CDN DigiCert DigiCert EV Certificate Rackspace Rackspace Cloud Servers DreamHost DreamHost Log Hosting