mirror of
https://github.com/kennethreitz/requests.git
synced 2026-06-05 22:50:18 +00:00
Merge branch 'develop'
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
.idea
|
||||
MANIFEST
|
||||
coverage.xml
|
||||
nosetests.xml
|
||||
|
||||
+3
-1
@@ -62,4 +62,6 @@ Patches and Suggestions
|
||||
- Ryan Kelly
|
||||
- Rolando Espinoza La fuente
|
||||
- Robert Gieseke
|
||||
- Idan Gazit
|
||||
- Idan Gazit
|
||||
- Ed Summers
|
||||
- Chris Van Horne
|
||||
@@ -1,6 +1,12 @@
|
||||
History
|
||||
-------
|
||||
|
||||
0.8.4 (2011-12-11)
|
||||
++++++++++++++++++
|
||||
|
||||
* Prefetch bugfix.
|
||||
* Added license to installed version.
|
||||
|
||||
0.8.3 (2011-11-27)
|
||||
++++++++++++++++++
|
||||
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
include README.rst LICENSE HISTORY.rst test_requests.py
|
||||
include README.rst LICENSE NOTICE HISTORY.rst test_requests.py
|
||||
|
||||
@@ -2,7 +2,7 @@ init:
|
||||
pip install -r reqs.txt
|
||||
|
||||
test:
|
||||
nosetests test_requests.py
|
||||
nosetests --with-color test_requests.py
|
||||
|
||||
ci: init
|
||||
nosetests test_requests.py --with-xunit --xunit-file=junit-report.xml
|
||||
|
||||
@@ -1,12 +1,26 @@
|
||||
Request includes some vendorized python libraries to ease installation.
|
||||
|
||||
Poster License
|
||||
==============
|
||||
Urllib3 License
|
||||
===============
|
||||
|
||||
Copyright (c) 2010 Chris AtLee
|
||||
This is the MIT license: http://www.opensource.org/licenses/mit-license.php
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
Copyright 2008-2011 Andrey Petrov and contributors (see CONTRIBUTORS.txt),
|
||||
Modifications copyright 2022 Kenneth Reitz.
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
software and associated documentation files (the "Software"), to deal in the Software
|
||||
without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or
|
||||
substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Vendored
+1
-1
@@ -2,7 +2,7 @@ krTheme Sphinx Style
|
||||
====================
|
||||
|
||||
This repository contains sphinx styles Kenneth Reitz uses in most of
|
||||
his projects. It is a drivative of Mitsuhiko's themes for Flask and Flask related
|
||||
his projects. It is a derivative of Mitsuhiko's themes for Flask and Flask related
|
||||
projects. To use this style in your Sphinx documentation, follow
|
||||
this guide:
|
||||
|
||||
|
||||
+1
-1
@@ -38,7 +38,7 @@ Testimonials
|
||||
`Twitter, Inc <http://twitter.com>`_,
|
||||
`Readability <http://readability.com>`_, and
|
||||
Federal US Institutions
|
||||
use Requests internally. It has been installed over 45,000 times from PyPi.
|
||||
use Requests internally. It has been installed over 45,000 times from PyPI.
|
||||
|
||||
**Armin Ronacher**
|
||||
Requests is the perfect example how beautiful an API can be with the
|
||||
|
||||
@@ -10,7 +10,7 @@ Session Objects
|
||||
---------------
|
||||
|
||||
The Session object allows you to persist certain parameters across
|
||||
requests. It also perstists cookies across all requests made from the
|
||||
requests. It also persists cookies across all requests made from the
|
||||
Session instance.
|
||||
|
||||
A session object has all the methods of the main Requests API.
|
||||
@@ -49,7 +49,7 @@ All values that are contained within a session are directly available to you. Se
|
||||
Body Content Workflow
|
||||
----------------------
|
||||
|
||||
By default, When you make a request, the body of the response isn't downloaded immediately. The response headers are downloaded when you make a request, but the content isn't downloaded until you access the :class:`Response.content` attribute.
|
||||
By default, when you make a request, the body of the response isn't downloaded immediately. The response headers are downloaded when you make a request, but the content isn't downloaded until you access the :class:`Response.content` attribute.
|
||||
|
||||
Let's walk through it::
|
||||
|
||||
@@ -80,6 +80,8 @@ Keep-Alive
|
||||
|
||||
Excellent news — thanks to urllib3, keep-alive is 100% automatic within a session! Any requests that you make within a session will automatically reuse the appropriate connection!
|
||||
|
||||
Note that connections are only released back to the pool for reuse once all body data has been read; be sure to either set ``prefetch`` to ``True`` or read the ``content`` property of the ``Response`` object.
|
||||
|
||||
If you'd like to disable keep-alive, you can simply set the ``keep_alive`` configuration to ``False``::
|
||||
|
||||
s = requests.session()
|
||||
@@ -89,8 +91,8 @@ If you'd like to disable keep-alive, you can simply set the ``keep_alive`` confi
|
||||
Asynchronous Requests
|
||||
----------------------
|
||||
|
||||
Requests has first-class support for concurrent requests, powered
|
||||
by gevent. This allows you to send a bunch of HTTP requests at the same
|
||||
Requests has first-class support for concurrent requests, powered by gevent.
|
||||
This allows you to send a bunch of HTTP requests at the same time.
|
||||
|
||||
First, let's import the async module. Heads up — if you don't have
|
||||
`gevent <http://pypi.python.org/pypi/gevent>`_ this will fail::
|
||||
@@ -122,7 +124,7 @@ will also guarantee execution of the ``response`` hook, described below. ::
|
||||
|
||||
.. admonition:: Throttling
|
||||
|
||||
The ``map`` function also takes a ``size`` parameter, that specifies the nubmer of connections to make at a time::
|
||||
The ``map`` function also takes a ``size`` parameter, that specifies the number of connections to make at a time::
|
||||
|
||||
async.map(rs, size=5)
|
||||
|
||||
@@ -229,7 +231,7 @@ Let's pretend that we have a web service that will only respond if the
|
||||
def __init__(self, username):
|
||||
# setup any auth-related data here
|
||||
self.username = username
|
||||
|
||||
|
||||
def __call__(self, r):
|
||||
# modify and return the request
|
||||
r.headers['X-Pizza'] = self.username
|
||||
|
||||
@@ -300,7 +300,7 @@ establishing OAuth connections. Documentation and examples can be found on the r
|
||||
Redirection and History
|
||||
-----------------------
|
||||
|
||||
Requests will automatically perform location redirection while using impodotent methods.
|
||||
Requests will automatically perform location redirection while using idempotent methods.
|
||||
|
||||
GitHub redirects all HTTP requests to HTTPS. Let's see what happens::
|
||||
|
||||
@@ -316,9 +316,9 @@ The :class:`Response.history` list contains a list of the
|
||||
:class:`Request` objects that were created in order to complete the request.
|
||||
|
||||
If you're using GET, HEAD, or OPTIONS, you can disable redirection
|
||||
handling with the ``disable_redirects`` parameter::
|
||||
handling with the ``allow_redirects`` parameter::
|
||||
|
||||
>>> r = requests.get('http://github.com')
|
||||
>>> r = requests.get('http://github.com', allow_redirects=False)
|
||||
>>> r.status_code
|
||||
301
|
||||
>>> r.history
|
||||
@@ -345,7 +345,7 @@ You can tell requests to stop waiting for a response after a given number of sec
|
||||
|
||||
.. admonition:: Note
|
||||
|
||||
``timeout`` only effects the connection process itself, not the downloading of the respone body.
|
||||
``timeout`` only effects the connection process itself, not the downloading of the response body.
|
||||
|
||||
|
||||
Errors and Exceptions
|
||||
|
||||
@@ -15,13 +15,14 @@ requests
|
||||
"""
|
||||
|
||||
__title__ = 'requests'
|
||||
__version__ = '0.8.3'
|
||||
__build__ = 0x000803
|
||||
__version__ = '0.8.4'
|
||||
__build__ = 0x000804
|
||||
__author__ = 'Kenneth Reitz'
|
||||
__license__ = 'ISC'
|
||||
__copyright__ = 'Copyright 2011 Kenneth Reitz'
|
||||
|
||||
|
||||
|
||||
from . import utils
|
||||
from .models import Request, Response
|
||||
from .api import request, get, head, post, patch, put, delete, options
|
||||
|
||||
+1
-1
@@ -39,7 +39,7 @@ def request(method, url,
|
||||
:param headers: (optional) Dictionary of HTTP Headers to send with the :class:`Request`.
|
||||
:param cookies: (optional) Dict or CookieJar object to send with the :class:`Request`.
|
||||
:param files: (optional) Dictionary of 'name': file-like-objects (or {'name': ('filename', fileobj)}) for multipart encoding upload.
|
||||
:param auth: (optional) Auth typle to enable Basic/Digest/Custom HTTP Auth.
|
||||
:param auth: (optional) Auth tuple to enable Basic/Digest/Custom HTTP Auth.
|
||||
:param timeout: (optional) Float describing the timeout of the request.
|
||||
:param allow_redirects: (optional) Boolean. Set to True if POST/PUT/DELETE redirect following is allowed.
|
||||
:param proxies: (optional) Dictionary mapping protocol to the URL of the proxy.
|
||||
|
||||
@@ -11,7 +11,7 @@ Configurations:
|
||||
:base_headers: Default HTTP headers.
|
||||
:verbose: Stream to write request logging to.
|
||||
:timeout: Seconds until request timeout.
|
||||
:max_redirects: Maximum njumber of redirects allowed within a request.
|
||||
:max_redirects: Maximum number of redirects allowed within a request.
|
||||
:decode_unicode: Decode unicode responses automatically?
|
||||
:keep_alive: Reuse HTTP Connections?
|
||||
:max_retries: The number of times a request should be retried in the event of a connection failure.
|
||||
|
||||
@@ -13,10 +13,10 @@ class RequestException(Exception):
|
||||
request."""
|
||||
|
||||
class HTTPError(RequestException):
|
||||
"""An HTTP error occured."""
|
||||
"""An HTTP error occurred."""
|
||||
|
||||
class ConnectionError(RequestException):
|
||||
"""A Connection error occured."""
|
||||
"""A Connection error occurred."""
|
||||
|
||||
class Timeout(RequestException):
|
||||
"""The request timed out."""
|
||||
|
||||
+6
-4
@@ -151,7 +151,7 @@ class Request(object):
|
||||
|
||||
if resp:
|
||||
|
||||
# Fallback to None if there's no staus_code, for whatever reason.
|
||||
# Fallback to None if there's no status_code, for whatever reason.
|
||||
response.status_code = getattr(resp, 'status', None)
|
||||
|
||||
# Make headers case-insensitive.
|
||||
@@ -171,7 +171,7 @@ class Request(object):
|
||||
# Save cookies in Response.
|
||||
response.cookies = cookies
|
||||
|
||||
# Save original resopnse for later.
|
||||
# Save original response for later.
|
||||
response.raw = resp
|
||||
|
||||
if is_error:
|
||||
@@ -441,11 +441,12 @@ class Request(object):
|
||||
headers=self.headers,
|
||||
redirect=False,
|
||||
assert_same_host=False,
|
||||
preload_content=prefetch,
|
||||
preload_content=False,
|
||||
decode_content=False,
|
||||
retries=self.config.get('max_retries', 0),
|
||||
timeout=self.timeout,
|
||||
)
|
||||
self.sent = True
|
||||
|
||||
|
||||
except MaxRetryError, e:
|
||||
@@ -469,7 +470,8 @@ class Request(object):
|
||||
|
||||
# If prefetch is True, mark content as consumed.
|
||||
if prefetch:
|
||||
self.response._content_consumed = True
|
||||
# Save the response.
|
||||
self.response.content
|
||||
|
||||
return self.sent
|
||||
|
||||
|
||||
@@ -123,7 +123,7 @@ class Session(object):
|
||||
:param headers: (optional) Dictionary of HTTP Headers to send with the :class:`Request`.
|
||||
:param cookies: (optional) Dict or CookieJar object to send with the :class:`Request`.
|
||||
:param files: (optional) Dictionary of 'filename': file-like-objects for multipart encoding upload.
|
||||
:param auth: (optional) Auth typle to enable Basic/Digest/Custom HTTP Auth.
|
||||
:param auth: (optional) Auth tuple to enable Basic/Digest/Custom HTTP Auth.
|
||||
:param timeout: (optional) Float describing the timeout of the request.
|
||||
:param allow_redirects: (optional) Boolean. Set to True if POST/PUT/DELETE redirect following is allowed.
|
||||
:param proxies: (optional) Dictionary mapping protocol to the URL of the proxy.
|
||||
|
||||
+2
-2
@@ -4,7 +4,7 @@
|
||||
requests.utils
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
This module provides utlity functions that are used within Requests
|
||||
This module provides utility functions that are used within Requests
|
||||
that are also useful for external consumption.
|
||||
|
||||
"""
|
||||
@@ -374,7 +374,7 @@ def requote_path(path):
|
||||
"""Re-quote the given URL path component.
|
||||
|
||||
This function passes the given path through an unquote/quote cycle to
|
||||
ensure that it is fully and consistenty quoted.
|
||||
ensure that it is fully and consistently quoted.
|
||||
"""
|
||||
parts = path.split("/")
|
||||
parts = (urllib.quote(urllib.unquote(part), safe="") for part in parts)
|
||||
|
||||
@@ -12,12 +12,12 @@ except ImportError:
|
||||
|
||||
|
||||
|
||||
if sys.argv[-1] == "publish":
|
||||
os.system("python setup.py sdist upload")
|
||||
if sys.argv[-1] == 'publish':
|
||||
os.system('python setup.py sdist upload')
|
||||
sys.exit()
|
||||
|
||||
if sys.argv[-1] == "test":
|
||||
os.system("python test_requests.py")
|
||||
if sys.argv[-1] == 'test':
|
||||
os.system('python test_requests.py')
|
||||
sys.exit()
|
||||
|
||||
required = []
|
||||
@@ -34,12 +34,14 @@ setup(
|
||||
author='Kenneth Reitz',
|
||||
author_email='me@kennethreitz.com',
|
||||
url='http://python-requests.org',
|
||||
packages= [
|
||||
packages=[
|
||||
'requests',
|
||||
'requests.packages',
|
||||
'requests.packages.urllib3',
|
||||
'requests.packages.oreos'
|
||||
],
|
||||
package_data={'': ['LICENSE', 'NOTICE']},
|
||||
include_package_data=True,
|
||||
install_requires=required,
|
||||
license='ISC',
|
||||
classifiers=(
|
||||
|
||||
@@ -81,6 +81,11 @@ class RequestsTestSuite(unittest.TestCase):
|
||||
r = requests.get(httpbin('/get'))
|
||||
self.assertEqual(r.status_code, 200)
|
||||
|
||||
def test_response_sent(self):
|
||||
r = requests.get(httpbin('/get'))
|
||||
|
||||
self.assertTrue(r.request.sent)
|
||||
|
||||
def test_HTTP_302_ALLOW_REDIRECT_GET(self):
|
||||
r = requests.get(httpbin('redirect', '1'))
|
||||
self.assertEqual(r.status_code, 200)
|
||||
@@ -577,6 +582,14 @@ class RequestsTestSuite(unittest.TestCase):
|
||||
r = requests.get(hah, allow_redirects=False, config=config)
|
||||
assert r.content == None
|
||||
|
||||
def test_cached_response(self):
|
||||
|
||||
r1 = requests.get(httpbin('get'), prefetch=False)
|
||||
assert r1.content
|
||||
assert r1.content
|
||||
|
||||
r2 = requests.get(httpbin('get'), prefetch=True)
|
||||
assert r2.content
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
Reference in New Issue
Block a user