summaryrefslogtreecommitdiffhomepage
path: root/libs/requests
diff options
context:
space:
mode:
authormorpheus65535 <[email protected]>2021-05-08 10:39:00 -0400
committerGitHub <[email protected]>2021-05-08 10:39:00 -0400
commit44c51b2e2c3bffdfc0e0c447c038f6cd0bfd2cbe (patch)
treef4c16f35853afd27abb4e48fb2a72a11145360a7 /libs/requests
parent72b6ab3c6a11e1c12d86563989d88d73e4e64377 (diff)
downloadbazarr-44c51b2e2c3bffdfc0e0c447c038f6cd0bfd2cbe.tar.gz
bazarr-44c51b2e2c3bffdfc0e0c447c038f6cd0bfd2cbe.zip
Added real-time sync with Sonarr v3 and Radarr v3 by feeding from SignalR feeds. You can now reduce frequency of sync tasks to something like once a day.
Diffstat (limited to 'libs/requests')
-rw-r--r--libs/requests/__init__.py42
-rw-r--r--libs/requests/__version__.py8
-rw-r--r--libs/requests/api.py7
-rw-r--r--libs/requests/auth.py4
-rw-r--r--libs/requests/compat.py2
-rw-r--r--libs/requests/exceptions.py9
-rw-r--r--libs/requests/models.py23
-rw-r--r--libs/requests/sessions.py51
-rw-r--r--libs/requests/status_codes.py15
-rw-r--r--libs/requests/structures.py4
-rw-r--r--libs/requests/utils.py27
11 files changed, 117 insertions, 75 deletions
diff --git a/libs/requests/__init__.py b/libs/requests/__init__.py
index 9a899df67..f8f94295f 100644
--- a/libs/requests/__init__.py
+++ b/libs/requests/__init__.py
@@ -9,14 +9,14 @@
Requests HTTP Library
~~~~~~~~~~~~~~~~~~~~~
-Requests is an HTTP library, written in Python, for human beings. Basic GET
-usage:
+Requests is an HTTP library, written in Python, for human beings.
+Basic GET usage:
>>> import requests
>>> r = requests.get('https://www.python.org')
>>> r.status_code
200
- >>> 'Python is a programming language' in r.content
+ >>> b'Python is a programming language' in r.content
True
... or POST:
@@ -27,14 +27,14 @@ usage:
{
...
"form": {
- "key2": "value2",
- "key1": "value1"
+ "key1": "value1",
+ "key2": "value2"
},
...
}
The other HTTP methods are supported - see `requests.api`. Full documentation
-is at <http://python-requests.org>.
+is at <https://requests.readthedocs.io>.
:copyright: (c) 2017 by Kenneth Reitz.
:license: Apache 2.0, see LICENSE for more details.
@@ -57,18 +57,16 @@ def check_compatibility(urllib3_version, chardet_version):
# Check urllib3 for compatibility.
major, minor, patch = urllib3_version # noqa: F811
major, minor, patch = int(major), int(minor), int(patch)
- # urllib3 >= 1.21.1, <= 1.25
+ # urllib3 >= 1.21.1, <= 1.26
assert major == 1
assert minor >= 21
- assert minor <= 25
+ assert minor <= 26
# Check chardet for compatibility.
major, minor, patch = chardet_version.split('.')[:3]
major, minor, patch = int(major), int(minor), int(patch)
- # chardet >= 3.0.2, < 3.1.0
- assert major == 3
- assert minor < 1
- assert patch >= 2
+ # chardet >= 3.0.2, < 5.0.0
+ assert (3, 0, 2) <= (major, minor, patch) < (5, 0, 0)
def _check_cryptography(cryptography_version):
@@ -90,14 +88,22 @@ except (AssertionError, ValueError):
"version!".format(urllib3.__version__, chardet.__version__),
RequestsDependencyWarning)
-# Attempt to enable urllib3's SNI support, if possible
+# Attempt to enable urllib3's fallback for SNI support
+# if the standard library doesn't support SNI or the
+# 'ssl' library isn't available.
try:
- from urllib3.contrib import pyopenssl
- pyopenssl.inject_into_urllib3()
+ try:
+ import ssl
+ except ImportError:
+ ssl = None
+
+ if not getattr(ssl, "HAS_SNI", False):
+ from urllib3.contrib import pyopenssl
+ pyopenssl.inject_into_urllib3()
- # Check cryptography version
- from cryptography import __version__ as cryptography_version
- _check_cryptography(cryptography_version)
+ # Check cryptography version
+ from cryptography import __version__ as cryptography_version
+ _check_cryptography(cryptography_version)
except ImportError:
pass
diff --git a/libs/requests/__version__.py b/libs/requests/__version__.py
index 9844f740a..1267488d2 100644
--- a/libs/requests/__version__.py
+++ b/libs/requests/__version__.py
@@ -4,11 +4,11 @@
__title__ = 'requests'
__description__ = 'Python HTTP for Humans.'
-__url__ = 'http://python-requests.org'
-__version__ = '2.22.0'
-__build__ = 0x022200
+__url__ = 'https://requests.readthedocs.io'
+__version__ = '2.25.1'
+__build__ = 0x022501
__author__ = 'Kenneth Reitz'
__author_email__ = '[email protected]'
__license__ = 'Apache 2.0'
-__copyright__ = 'Copyright 2019 Kenneth Reitz'
+__copyright__ = 'Copyright 2020 Kenneth Reitz'
__cake__ = u'\u2728 \U0001f370 \u2728'
diff --git a/libs/requests/api.py b/libs/requests/api.py
index ef71d0759..e978e2031 100644
--- a/libs/requests/api.py
+++ b/libs/requests/api.py
@@ -16,7 +16,7 @@ from . import sessions
def request(method, url, **kwargs):
"""Constructs and sends a :class:`Request <Request>`.
- :param method: method for the new :class:`Request` object.
+ :param method: method for the new :class:`Request` object: ``GET``, ``OPTIONS``, ``HEAD``, ``POST``, ``PUT``, ``PATCH``, or ``DELETE``.
:param url: URL for the new :class:`Request` object.
:param params: (optional) Dictionary, list of tuples or bytes to send
in the query string for the :class:`Request`.
@@ -50,6 +50,7 @@ def request(method, url, **kwargs):
>>> import requests
>>> req = requests.request('GET', 'https://httpbin.org/get')
+ >>> req
<Response [200]>
"""
@@ -92,7 +93,9 @@ def head(url, **kwargs):
r"""Sends a HEAD request.
:param url: URL for the new :class:`Request` object.
- :param \*\*kwargs: Optional arguments that ``request`` takes.
+ :param \*\*kwargs: Optional arguments that ``request`` takes. If
+ `allow_redirects` is not provided, it will be set to `False` (as
+ opposed to the default :meth:`request` behavior).
:return: :class:`Response <Response>` object
:rtype: requests.Response
"""
diff --git a/libs/requests/auth.py b/libs/requests/auth.py
index bdde51c7f..eeface39a 100644
--- a/libs/requests/auth.py
+++ b/libs/requests/auth.py
@@ -50,7 +50,7 @@ def _basic_auth_str(username, password):
"Non-string passwords will no longer be supported in Requests "
"3.0.0. Please convert the object you've passed in ({!r}) to "
"a string or bytes object in the near future to avoid "
- "problems.".format(password),
+ "problems.".format(type(password)),
category=DeprecationWarning,
)
password = str(password)
@@ -239,7 +239,7 @@ class HTTPDigestAuth(AuthBase):
"""
# If response is not 4xx, do not auth
- # See https://github.com/requests/requests/issues/3772
+ # See https://github.com/psf/requests/issues/3772
if not 400 <= r.status_code < 500:
self._thread_local.num_401_calls = 1
return r
diff --git a/libs/requests/compat.py b/libs/requests/compat.py
index c44b35efb..5de0769f5 100644
--- a/libs/requests/compat.py
+++ b/libs/requests/compat.py
@@ -43,6 +43,7 @@ if is_py2:
import cookielib
from Cookie import Morsel
from StringIO import StringIO
+ # Keep OrderedDict for backwards compatibility.
from collections import Callable, Mapping, MutableMapping, OrderedDict
@@ -59,6 +60,7 @@ elif is_py3:
from http import cookiejar as cookielib
from http.cookies import Morsel
from io import StringIO
+ # Keep OrderedDict for backwards compatibility.
from collections import OrderedDict
from collections.abc import Callable, Mapping, MutableMapping
diff --git a/libs/requests/exceptions.py b/libs/requests/exceptions.py
index a80cad80f..0e9c820c8 100644
--- a/libs/requests/exceptions.py
+++ b/libs/requests/exceptions.py
@@ -94,11 +94,11 @@ class ChunkedEncodingError(RequestException):
class ContentDecodingError(RequestException, BaseHTTPError):
- """Failed to decode response content"""
+ """Failed to decode response content."""
class StreamConsumedError(RequestException, TypeError):
- """The content for this response was already consumed"""
+ """The content for this response was already consumed."""
class RetryError(RequestException):
@@ -106,21 +106,18 @@ class RetryError(RequestException):
class UnrewindableBodyError(RequestException):
- """Requests encountered an error when trying to rewind a body"""
+ """Requests encountered an error when trying to rewind a body."""
# Warnings
class RequestsWarning(Warning):
"""Base warning for Requests."""
- pass
class FileModeWarning(RequestsWarning, DeprecationWarning):
"""A file was opened in text mode, but Requests determined its binary length."""
- pass
class RequestsDependencyWarning(RequestsWarning):
"""An imported dependency doesn't match the expected version range."""
- pass
diff --git a/libs/requests/models.py b/libs/requests/models.py
index 62dcd0b7c..ec2edc20b 100644
--- a/libs/requests/models.py
+++ b/libs/requests/models.py
@@ -12,7 +12,7 @@ import sys
# Import encoding now, to avoid implicit import later.
# Implicit import within threads may cause LookupError when standard library is in a ZIP,
-# such as in Embedded Python. See https://github.com/requests/requests/issues/3578.
+# such as in Embedded Python. See https://github.com/psf/requests/issues/3578.
import encodings.idna
from urllib3.fields import RequestField
@@ -273,13 +273,16 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
"""The fully mutable :class:`PreparedRequest <PreparedRequest>` object,
containing the exact bytes that will be sent to the server.
- Generated from either a :class:`Request <Request>` object or manually.
+ Instances are generated from a :class:`Request <Request>` object, and
+ should not be instantiated manually; doing so may produce undesirable
+ effects.
Usage::
>>> import requests
>>> req = requests.Request('GET', 'https://httpbin.org/get')
>>> r = req.prepare()
+ >>> r
<PreparedRequest [GET]>
>>> s = requests.Session()
@@ -358,7 +361,7 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
#: We're unable to blindly call unicode/str functions
#: as this will include the bytestring indicator (b'')
#: on python 3.x.
- #: https://github.com/requests/requests/pull/2238
+ #: https://github.com/psf/requests/pull/2238
if isinstance(url, bytes):
url = url.decode('utf8')
else:
@@ -472,12 +475,12 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
not isinstance(data, (basestring, list, tuple, Mapping))
])
- try:
- length = super_len(data)
- except (TypeError, AttributeError, UnsupportedOperation):
- length = None
-
if is_stream:
+ try:
+ length = super_len(data)
+ except (TypeError, AttributeError, UnsupportedOperation):
+ length = None
+
body = data
if getattr(body, 'tell', None) is not None:
@@ -608,7 +611,7 @@ class Response(object):
#: File-like object representation of response (for advanced usage).
#: Use of ``raw`` requires that ``stream=True`` be set on the request.
- # This requirement does not apply for use internally to Requests.
+ #: This requirement does not apply for use internally to Requests.
self.raw = None
#: Final URL location of Response.
@@ -915,7 +918,7 @@ class Response(object):
return l
def raise_for_status(self):
- """Raises stored :class:`HTTPError`, if one occurred."""
+ """Raises :class:`HTTPError`, if one occurred."""
http_error_msg = ''
if isinstance(self.reason, bytes):
diff --git a/libs/requests/sessions.py b/libs/requests/sessions.py
index d73d700fa..45ab8a5d3 100644
--- a/libs/requests/sessions.py
+++ b/libs/requests/sessions.py
@@ -1,8 +1,8 @@
# -*- coding: utf-8 -*-
"""
-requests.session
-~~~~~~~~~~~~~~~~
+requests.sessions
+~~~~~~~~~~~~~~~~~
This module provides a Session object to manage and persist settings across
requests (cookies, auth, proxies).
@@ -11,9 +11,10 @@ import os
import sys
import time
from datetime import timedelta
+from collections import OrderedDict
from .auth import _basic_auth_str
-from .compat import cookielib, is_py3, OrderedDict, urljoin, urlparse, Mapping
+from .compat import cookielib, is_py3, urljoin, urlparse, Mapping
from .cookies import (
cookiejar_from_dict, extract_cookies_to_jar, RequestsCookieJar, merge_cookies)
from .models import Request, PreparedRequest, DEFAULT_REDIRECT_LIMIT
@@ -162,7 +163,7 @@ class SessionRedirectMixin(object):
resp.raw.read(decode_content=False)
if len(resp.history) >= self.max_redirects:
- raise TooManyRedirects('Exceeded %s redirects.' % self.max_redirects, response=resp)
+ raise TooManyRedirects('Exceeded {} redirects.'.format(self.max_redirects), response=resp)
# Release the connection back into the pool.
resp.close()
@@ -170,7 +171,7 @@ class SessionRedirectMixin(object):
# Handle redirection without scheme (see: RFC 1808 Section 4)
if url.startswith('//'):
parsed_rurl = urlparse(resp.url)
- url = '%s:%s' % (to_native_string(parsed_rurl.scheme), url)
+ url = ':'.join([to_native_string(parsed_rurl.scheme), url])
# Normalize url case and attach previous fragment if needed (RFC 7231 7.1.2)
parsed = urlparse(url)
@@ -192,19 +193,16 @@ class SessionRedirectMixin(object):
self.rebuild_method(prepared_request, resp)
- # https://github.com/requests/requests/issues/1084
+ # https://github.com/psf/requests/issues/1084
if resp.status_code not in (codes.temporary_redirect, codes.permanent_redirect):
- # https://github.com/requests/requests/issues/3490
+ # https://github.com/psf/requests/issues/3490
purged_headers = ('Content-Length', 'Content-Type', 'Transfer-Encoding')
for header in purged_headers:
prepared_request.headers.pop(header, None)
prepared_request.body = None
headers = prepared_request.headers
- try:
- del headers['Cookie']
- except KeyError:
- pass
+ headers.pop('Cookie', None)
# Extract any cookies sent on the response to the cookiejar
# in the new request. Because we've mutated our copied prepared
@@ -271,7 +269,6 @@ class SessionRedirectMixin(object):
if new_auth is not None:
prepared_request.prepare_auth(new_auth)
- return
def rebuild_proxies(self, prepared_request, proxies):
"""This method re-evaluates the proxy configuration by considering the
@@ -352,13 +349,13 @@ class Session(SessionRedirectMixin):
Or as a context manager::
>>> with requests.Session() as s:
- >>> s.get('https://httpbin.org/get')
+ ... s.get('https://httpbin.org/get')
<Response [200]>
"""
__attrs__ = [
'headers', 'cookies', 'auth', 'proxies', 'hooks', 'params', 'verify',
- 'cert', 'prefetch', 'adapters', 'stream', 'trust_env',
+ 'cert', 'adapters', 'stream', 'trust_env',
'max_redirects',
]
@@ -390,6 +387,13 @@ class Session(SessionRedirectMixin):
self.stream = False
#: SSL Verification default.
+ #: Defaults to `True`, requiring requests to verify the TLS certificate at the
+ #: remote end.
+ #: If verify is set to `False`, requests will accept any TLS certificate
+ #: presented by the server, and will ignore hostname mismatches and/or
+ #: expired certificates, which will make your application vulnerable to
+ #: man-in-the-middle (MitM) attacks.
+ #: Only set this to `False` for testing.
self.verify = True
#: SSL client certificate default, if String, path to ssl client
@@ -498,7 +502,12 @@ class Session(SessionRedirectMixin):
content. Defaults to ``False``.
:param verify: (optional) Either a boolean, in which case it controls whether we verify
the server's TLS certificate, or a string, in which case it must be a path
- to a CA bundle to use. Defaults to ``True``.
+ to a CA bundle to use. Defaults to ``True``. When set to
+ ``False``, requests will accept any TLS certificate presented by
+ the server, and will ignore hostname mismatches and/or expired
+ certificates, which will make your application vulnerable to
+ man-in-the-middle (MitM) attacks. Setting verify to ``False``
+ may be useful during local development or testing.
:param cert: (optional) if String, path to ssl client cert file (.pem).
If Tuple, ('cert', 'key') pair.
:rtype: requests.Response
@@ -661,11 +670,13 @@ class Session(SessionRedirectMixin):
extract_cookies_to_jar(self.cookies, request, r.raw)
- # Redirect resolving generator.
- gen = self.resolve_redirects(r, request, **kwargs)
-
# Resolve redirects if allowed.
- history = [resp for resp in gen] if allow_redirects else []
+ if allow_redirects:
+ # Redirect resolving generator.
+ gen = self.resolve_redirects(r, request, **kwargs)
+ history = [resp for resp in gen]
+ else:
+ history = []
# Shuffle things around if there's history.
if history:
@@ -728,7 +739,7 @@ class Session(SessionRedirectMixin):
return adapter
# Nothing matches :-/
- raise InvalidSchema("No connection adapters were found for '%s'" % url)
+ raise InvalidSchema("No connection adapters were found for {!r}".format(url))
def close(self):
"""Closes all adapters and as such the session"""
diff --git a/libs/requests/status_codes.py b/libs/requests/status_codes.py
index 813e8c4e6..d80a7cd4d 100644
--- a/libs/requests/status_codes.py
+++ b/libs/requests/status_codes.py
@@ -5,12 +5,15 @@ The ``codes`` object defines a mapping from common names for HTTP statuses
to their numerical codes, accessible either as attributes or as dictionary
items.
->>> requests.codes['temporary_redirect']
-307
->>> requests.codes.teapot
-418
->>> requests.codes['\o/']
-200
+Example::
+
+ >>> import requests
+ >>> requests.codes['temporary_redirect']
+ 307
+ >>> requests.codes.teapot
+ 418
+ >>> requests.codes['\o/']
+ 200
Some codes have multiple names, and both upper- and lower-case versions of
the names are allowed. For example, ``codes.ok``, ``codes.OK``, and
diff --git a/libs/requests/structures.py b/libs/requests/structures.py
index da930e285..8ee0ba7a0 100644
--- a/libs/requests/structures.py
+++ b/libs/requests/structures.py
@@ -7,7 +7,9 @@ requests.structures
Data structures that power Requests.
"""
-from .compat import OrderedDict, Mapping, MutableMapping
+from collections import OrderedDict
+
+from .compat import Mapping, MutableMapping
class CaseInsensitiveDict(MutableMapping):
diff --git a/libs/requests/utils.py b/libs/requests/utils.py
index 8170a8d2c..db67938e6 100644
--- a/libs/requests/utils.py
+++ b/libs/requests/utils.py
@@ -19,6 +19,7 @@ import sys
import tempfile
import warnings
import zipfile
+from collections import OrderedDict
from .__version__ import __version__
from . import certs
@@ -26,7 +27,7 @@ from . import certs
from ._internal_utils import to_native_string
from .compat import parse_http_list as _parse_list_header
from .compat import (
- quote, urlparse, bytes, str, OrderedDict, unquote, getproxies,
+ quote, urlparse, bytes, str, unquote, getproxies,
proxy_bypass, urlunparse, basestring, integer_types, is_py3,
proxy_bypass_environment, getproxies_environment, Mapping)
from .cookies import cookiejar_from_dict
@@ -168,18 +169,24 @@ def super_len(o):
def get_netrc_auth(url, raise_errors=False):
"""Returns the Requests tuple auth for a given url from netrc."""
+ netrc_file = os.environ.get('NETRC')
+ if netrc_file is not None:
+ netrc_locations = (netrc_file,)
+ else:
+ netrc_locations = ('~/{}'.format(f) for f in NETRC_FILES)
+
try:
from netrc import netrc, NetrcParseError
netrc_path = None
- for f in NETRC_FILES:
+ for f in netrc_locations:
try:
- loc = os.path.expanduser('~/{}'.format(f))
+ loc = os.path.expanduser(f)
except KeyError:
# os.path.expanduser can fail when $HOME is undefined and
# getpwuid fails. See https://bugs.python.org/issue20164 &
- # https://github.com/requests/requests/issues/1846
+ # https://github.com/psf/requests/issues/1846
return
if os.path.exists(loc):
@@ -211,7 +218,7 @@ def get_netrc_auth(url, raise_errors=False):
if raise_errors:
raise
- # AppEngine hackiness.
+ # App Engine hackiness.
except (ImportError, AttributeError):
pass
@@ -266,6 +273,8 @@ def from_key_val_list(value):
>>> from_key_val_list([('key', 'val')])
OrderedDict([('key', 'val')])
>>> from_key_val_list('string')
+ Traceback (most recent call last):
+ ...
ValueError: cannot encode objects that are not 2-tuples
>>> from_key_val_list({'key': 'val'})
OrderedDict([('key', 'val')])
@@ -292,7 +301,9 @@ def to_key_val_list(value):
>>> to_key_val_list({'key': 'val'})
[('key', 'val')]
>>> to_key_val_list('string')
- ValueError: cannot encode objects that are not 2-tuples.
+ Traceback (most recent call last):
+ ...
+ ValueError: cannot encode objects that are not 2-tuples
:rtype: list
"""
@@ -492,6 +503,10 @@ def get_encoding_from_headers(headers):
if 'text' in content_type:
return 'ISO-8859-1'
+ if 'application/json' in content_type:
+ # Assume UTF-8 based on RFC 4627: https://www.ietf.org/rfc/rfc4627.txt since the charset was unset
+ return 'utf-8'
+
def stream_decode_response_unicode(iterator, r):
"""Stream decodes a iterator."""