1# -*- coding: utf-8 -*-
2
3#   __
4#  /__)  _  _     _   _ _/   _
5# / (   (- (/ (/ (- _)  /  _)
6#          /
7
8"""
9Requests HTTP Library
10~~~~~~~~~~~~~~~~~~~~~
11
12Requests is an HTTP library, written in Python, for human beings.
13Basic GET usage:
14
15   >>> import requests
16   >>> r = requests.get('https://www.python.org')
17   >>> r.status_code
18   200
19   >>> b'Python is a programming language' in r.content
20   True
21
22... or POST:
23
24   >>> payload = dict(key1='value1', key2='value2')
25   >>> r = requests.post('https://httpbin.org/post', data=payload)
26   >>> print(r.text)
27   {
28     ...
29     "form": {
30       "key1": "value1",
31       "key2": "value2"
32     },
33     ...
34   }
35
36The other HTTP methods are supported - see `requests.api`. Full documentation
37is at <https://requests.readthedocs.io>.
38
39:copyright: (c) 2017 by Kenneth Reitz.
40:license: Apache 2.0, see LICENSE for more details.
41"""
42
43import urllib3
44import chardet
45import warnings
46from .exceptions import RequestsDependencyWarning
47
48
49def check_compatibility(urllib3_version, chardet_version):
50    urllib3_version = urllib3_version.split('.')
51    assert urllib3_version != ['dev']  # Verify urllib3 isn't installed from git.
52
53    # Sometimes, urllib3 only reports its version as 16.1.
54    if len(urllib3_version) == 2:
55        urllib3_version.append('0')
56
57    # Check urllib3 for compatibility.
58    major, minor, patch = urllib3_version  # noqa: F811
59    major, minor, patch = int(major), int(minor), int(patch)
60    # urllib3 >= 1.21.1, <= 1.26
61    assert major == 1
62    assert minor >= 21
63    assert minor <= 26
64
65    # Check chardet for compatibility.
66    major, minor, patch = chardet_version.split('.')[:3]
67    major, minor, patch = int(major), int(minor), int(patch)
68    # chardet >= 3.0.2, < 5.0.0
69    assert (3, 0, 2) <= (major, minor, patch) < (5, 0, 0)
70
71
72def _check_cryptography(cryptography_version):
73    # cryptography < 1.3.4
74    try:
75        cryptography_version = list(map(int, cryptography_version.split('.')))
76    except ValueError:
77        return
78
79    if cryptography_version < [1, 3, 4]:
80        warning = 'Old version of cryptography ({}) may cause slowdown.'.format(cryptography_version)
81        warnings.warn(warning, RequestsDependencyWarning)
82
83# Check imported dependencies for compatibility.
84try:
85    check_compatibility(urllib3.__version__, chardet.__version__)
86except (AssertionError, ValueError):
87    warnings.warn("urllib3 ({}) or chardet ({}) doesn't match a supported "
88                  "version!".format(urllib3.__version__, chardet.__version__),
89                  RequestsDependencyWarning)
90
91# Attempt to enable urllib3's fallback for SNI support
92# if the standard library doesn't support SNI or the
93# 'ssl' library isn't available.
94try:
95    try:
96        import ssl
97    except ImportError:
98        ssl = None
99
100    if not getattr(ssl, "HAS_SNI", False):
101        from urllib3.contrib import pyopenssl
102        pyopenssl.inject_into_urllib3()
103
104        # Check cryptography version
105        from cryptography import __version__ as cryptography_version
106        _check_cryptography(cryptography_version)
107except ImportError:
108    pass
109
110# urllib3's DependencyWarnings should be silenced.
111from urllib3.exceptions import DependencyWarning
112warnings.simplefilter('ignore', DependencyWarning)
113
114from .__version__ import __title__, __description__, __url__, __version__
115from .__version__ import __build__, __author__, __author_email__, __license__
116from .__version__ import __copyright__, __cake__
117
118from . import utils
119from . import packages
120from .models import Request, Response, PreparedRequest
121from .api import request, get, head, post, patch, put, delete, options
122from .sessions import session, Session
123from .status_codes import codes
124from .exceptions import (
125    RequestException, Timeout, URLRequired,
126    TooManyRedirects, HTTPError, ConnectionError,
127    FileModeWarning, ConnectTimeout, ReadTimeout
128)
129
130# Set default logging handler to avoid "No handler found" warnings.
131import logging
132from logging import NullHandler
133
134logging.getLogger(__name__).addHandler(NullHandler())
135
136# FileModeWarnings go off per the default.
137warnings.simplefilter('default', FileModeWarning, append=True)
138