rigid 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/bin/rigid +4 -0
- data/rigid +16 -0
- data/vendor/PyYAML-3.12.dist-info/DESCRIPTION.rst +12 -0
- data/vendor/PyYAML-3.12.dist-info/INSTALLER +1 -0
- data/vendor/PyYAML-3.12.dist-info/METADATA +35 -0
- data/vendor/PyYAML-3.12.dist-info/RECORD +42 -0
- data/vendor/PyYAML-3.12.dist-info/WHEEL +5 -0
- data/vendor/PyYAML-3.12.dist-info/metadata.json +1 -0
- data/vendor/PyYAML-3.12.dist-info/top_level.txt +2 -0
- data/vendor/_yaml.so +0 -0
- data/vendor/click/__init__.py +98 -0
- data/vendor/click/__init__.pyc +0 -0
- data/vendor/click/_bashcomplete.py +83 -0
- data/vendor/click/_bashcomplete.pyc +0 -0
- data/vendor/click/_compat.py +642 -0
- data/vendor/click/_compat.pyc +0 -0
- data/vendor/click/_termui_impl.py +547 -0
- data/vendor/click/_termui_impl.pyc +0 -0
- data/vendor/click/_textwrap.py +38 -0
- data/vendor/click/_textwrap.pyc +0 -0
- data/vendor/click/_unicodefun.py +119 -0
- data/vendor/click/_unicodefun.pyc +0 -0
- data/vendor/click/_winconsole.py +273 -0
- data/vendor/click/_winconsole.pyc +0 -0
- data/vendor/click/core.py +1738 -0
- data/vendor/click/core.pyc +0 -0
- data/vendor/click/decorators.py +304 -0
- data/vendor/click/decorators.pyc +0 -0
- data/vendor/click/exceptions.py +201 -0
- data/vendor/click/exceptions.pyc +0 -0
- data/vendor/click/formatting.py +256 -0
- data/vendor/click/formatting.pyc +0 -0
- data/vendor/click/globals.py +48 -0
- data/vendor/click/globals.pyc +0 -0
- data/vendor/click/parser.py +426 -0
- data/vendor/click/parser.pyc +0 -0
- data/vendor/click/termui.py +539 -0
- data/vendor/click/termui.pyc +0 -0
- data/vendor/click/testing.py +322 -0
- data/vendor/click/testing.pyc +0 -0
- data/vendor/click/types.py +550 -0
- data/vendor/click/types.pyc +0 -0
- data/vendor/click/utils.py +415 -0
- data/vendor/click/utils.pyc +0 -0
- data/vendor/click-6.6.dist-info/DESCRIPTION.rst +3 -0
- data/vendor/click-6.6.dist-info/INSTALLER +1 -0
- data/vendor/click-6.6.dist-info/METADATA +16 -0
- data/vendor/click-6.6.dist-info/RECORD +41 -0
- data/vendor/click-6.6.dist-info/WHEEL +6 -0
- data/vendor/click-6.6.dist-info/metadata.json +1 -0
- data/vendor/click-6.6.dist-info/top_level.txt +1 -0
- data/vendor/easy_install.py +5 -0
- data/vendor/easy_install.pyc +0 -0
- data/vendor/pip-9.0.1.dist-info/DESCRIPTION.rst +39 -0
- data/vendor/pip-9.0.1.dist-info/INSTALLER +1 -0
- data/vendor/pip-9.0.1.dist-info/METADATA +69 -0
- data/vendor/pip-9.0.1.dist-info/RECORD +501 -0
- data/vendor/pip-9.0.1.dist-info/WHEEL +6 -0
- data/vendor/pip-9.0.1.dist-info/entry_points.txt +5 -0
- data/vendor/pip-9.0.1.dist-info/metadata.json +1 -0
- data/vendor/pip-9.0.1.dist-info/top_level.txt +1 -0
- data/vendor/pkg_resources/__init__.py +3051 -0
- data/vendor/pkg_resources/__init__.pyc +0 -0
- data/vendor/pkg_resources/_vendor/__init__.py +0 -0
- data/vendor/pkg_resources/_vendor/__init__.pyc +0 -0
- data/vendor/pkg_resources/_vendor/appdirs.py +552 -0
- data/vendor/pkg_resources/_vendor/appdirs.pyc +0 -0
- data/vendor/pkg_resources/_vendor/packaging/__about__.py +21 -0
- data/vendor/pkg_resources/_vendor/packaging/__about__.pyc +0 -0
- data/vendor/pkg_resources/_vendor/packaging/__init__.py +14 -0
- data/vendor/pkg_resources/_vendor/packaging/__init__.pyc +0 -0
- data/vendor/pkg_resources/_vendor/packaging/_compat.py +30 -0
- data/vendor/pkg_resources/_vendor/packaging/_compat.pyc +0 -0
- data/vendor/pkg_resources/_vendor/packaging/_structures.py +68 -0
- data/vendor/pkg_resources/_vendor/packaging/_structures.pyc +0 -0
- data/vendor/pkg_resources/_vendor/packaging/markers.py +287 -0
- data/vendor/pkg_resources/_vendor/packaging/markers.pyc +0 -0
- data/vendor/pkg_resources/_vendor/packaging/requirements.py +127 -0
- data/vendor/pkg_resources/_vendor/packaging/requirements.pyc +0 -0
- data/vendor/pkg_resources/_vendor/packaging/specifiers.py +774 -0
- data/vendor/pkg_resources/_vendor/packaging/specifiers.pyc +0 -0
- data/vendor/pkg_resources/_vendor/packaging/utils.py +14 -0
- data/vendor/pkg_resources/_vendor/packaging/utils.pyc +0 -0
- data/vendor/pkg_resources/_vendor/packaging/version.py +393 -0
- data/vendor/pkg_resources/_vendor/packaging/version.pyc +0 -0
- data/vendor/pkg_resources/_vendor/pyparsing.py +5696 -0
- data/vendor/pkg_resources/_vendor/pyparsing.pyc +0 -0
- data/vendor/pkg_resources/_vendor/six.py +868 -0
- data/vendor/pkg_resources/_vendor/six.pyc +0 -0
- data/vendor/pkg_resources/extern/__init__.py +73 -0
- data/vendor/pkg_resources/extern/__init__.pyc +0 -0
- data/vendor/requests/__init__.py +86 -0
- data/vendor/requests/__init__.pyc +0 -0
- data/vendor/requests/adapters.py +503 -0
- data/vendor/requests/adapters.pyc +0 -0
- data/vendor/requests/api.py +148 -0
- data/vendor/requests/api.pyc +0 -0
- data/vendor/requests/auth.py +252 -0
- data/vendor/requests/auth.pyc +0 -0
- data/vendor/requests/cacert.pem +5616 -0
- data/vendor/requests/certs.py +25 -0
- data/vendor/requests/certs.pyc +0 -0
- data/vendor/requests/compat.py +66 -0
- data/vendor/requests/compat.pyc +0 -0
- data/vendor/requests/cookies.py +540 -0
- data/vendor/requests/cookies.pyc +0 -0
- data/vendor/requests/exceptions.py +114 -0
- data/vendor/requests/exceptions.pyc +0 -0
- data/vendor/requests/hooks.py +34 -0
- data/vendor/requests/hooks.pyc +0 -0
- data/vendor/requests/models.py +873 -0
- data/vendor/requests/models.pyc +0 -0
- data/vendor/requests/packages/__init__.py +36 -0
- data/vendor/requests/packages/__init__.pyc +0 -0
- data/vendor/requests/packages/chardet/__init__.py +32 -0
- data/vendor/requests/packages/chardet/__init__.pyc +0 -0
- data/vendor/requests/packages/chardet/big5freq.py +925 -0
- data/vendor/requests/packages/chardet/big5freq.pyc +0 -0
- data/vendor/requests/packages/chardet/big5prober.py +42 -0
- data/vendor/requests/packages/chardet/big5prober.pyc +0 -0
- data/vendor/requests/packages/chardet/chardetect.py +80 -0
- data/vendor/requests/packages/chardet/chardetect.pyc +0 -0
- data/vendor/requests/packages/chardet/chardistribution.py +231 -0
- data/vendor/requests/packages/chardet/chardistribution.pyc +0 -0
- data/vendor/requests/packages/chardet/charsetgroupprober.py +106 -0
- data/vendor/requests/packages/chardet/charsetgroupprober.pyc +0 -0
- data/vendor/requests/packages/chardet/charsetprober.py +62 -0
- data/vendor/requests/packages/chardet/charsetprober.pyc +0 -0
- data/vendor/requests/packages/chardet/codingstatemachine.py +61 -0
- data/vendor/requests/packages/chardet/codingstatemachine.pyc +0 -0
- data/vendor/requests/packages/chardet/compat.py +34 -0
- data/vendor/requests/packages/chardet/compat.pyc +0 -0
- data/vendor/requests/packages/chardet/constants.py +39 -0
- data/vendor/requests/packages/chardet/constants.pyc +0 -0
- data/vendor/requests/packages/chardet/cp949prober.py +44 -0
- data/vendor/requests/packages/chardet/cp949prober.pyc +0 -0
- data/vendor/requests/packages/chardet/escprober.py +86 -0
- data/vendor/requests/packages/chardet/escprober.pyc +0 -0
- data/vendor/requests/packages/chardet/escsm.py +242 -0
- data/vendor/requests/packages/chardet/escsm.pyc +0 -0
- data/vendor/requests/packages/chardet/eucjpprober.py +90 -0
- data/vendor/requests/packages/chardet/eucjpprober.pyc +0 -0
- data/vendor/requests/packages/chardet/euckrfreq.py +596 -0
- data/vendor/requests/packages/chardet/euckrfreq.pyc +0 -0
- data/vendor/requests/packages/chardet/euckrprober.py +42 -0
- data/vendor/requests/packages/chardet/euckrprober.pyc +0 -0
- data/vendor/requests/packages/chardet/euctwfreq.py +428 -0
- data/vendor/requests/packages/chardet/euctwfreq.pyc +0 -0
- data/vendor/requests/packages/chardet/euctwprober.py +41 -0
- data/vendor/requests/packages/chardet/euctwprober.pyc +0 -0
- data/vendor/requests/packages/chardet/gb2312freq.py +472 -0
- data/vendor/requests/packages/chardet/gb2312freq.pyc +0 -0
- data/vendor/requests/packages/chardet/gb2312prober.py +41 -0
- data/vendor/requests/packages/chardet/gb2312prober.pyc +0 -0
- data/vendor/requests/packages/chardet/hebrewprober.py +283 -0
- data/vendor/requests/packages/chardet/hebrewprober.pyc +0 -0
- data/vendor/requests/packages/chardet/jisfreq.py +569 -0
- data/vendor/requests/packages/chardet/jisfreq.pyc +0 -0
- data/vendor/requests/packages/chardet/jpcntx.py +227 -0
- data/vendor/requests/packages/chardet/jpcntx.pyc +0 -0
- data/vendor/requests/packages/chardet/langbulgarianmodel.py +229 -0
- data/vendor/requests/packages/chardet/langbulgarianmodel.pyc +0 -0
- data/vendor/requests/packages/chardet/langcyrillicmodel.py +329 -0
- data/vendor/requests/packages/chardet/langcyrillicmodel.pyc +0 -0
- data/vendor/requests/packages/chardet/langgreekmodel.py +225 -0
- data/vendor/requests/packages/chardet/langgreekmodel.pyc +0 -0
- data/vendor/requests/packages/chardet/langhebrewmodel.py +201 -0
- data/vendor/requests/packages/chardet/langhebrewmodel.pyc +0 -0
- data/vendor/requests/packages/chardet/langhungarianmodel.py +225 -0
- data/vendor/requests/packages/chardet/langhungarianmodel.pyc +0 -0
- data/vendor/requests/packages/chardet/langthaimodel.py +200 -0
- data/vendor/requests/packages/chardet/langthaimodel.pyc +0 -0
- data/vendor/requests/packages/chardet/latin1prober.py +139 -0
- data/vendor/requests/packages/chardet/latin1prober.pyc +0 -0
- data/vendor/requests/packages/chardet/mbcharsetprober.py +86 -0
- data/vendor/requests/packages/chardet/mbcharsetprober.pyc +0 -0
- data/vendor/requests/packages/chardet/mbcsgroupprober.py +54 -0
- data/vendor/requests/packages/chardet/mbcsgroupprober.pyc +0 -0
- data/vendor/requests/packages/chardet/mbcssm.py +572 -0
- data/vendor/requests/packages/chardet/mbcssm.pyc +0 -0
- data/vendor/requests/packages/chardet/sbcharsetprober.py +120 -0
- data/vendor/requests/packages/chardet/sbcharsetprober.pyc +0 -0
- data/vendor/requests/packages/chardet/sbcsgroupprober.py +69 -0
- data/vendor/requests/packages/chardet/sbcsgroupprober.pyc +0 -0
- data/vendor/requests/packages/chardet/sjisprober.py +91 -0
- data/vendor/requests/packages/chardet/sjisprober.pyc +0 -0
- data/vendor/requests/packages/chardet/universaldetector.py +170 -0
- data/vendor/requests/packages/chardet/universaldetector.pyc +0 -0
- data/vendor/requests/packages/chardet/utf8prober.py +76 -0
- data/vendor/requests/packages/chardet/utf8prober.pyc +0 -0
- data/vendor/requests/packages/urllib3/__init__.py +96 -0
- data/vendor/requests/packages/urllib3/__init__.pyc +0 -0
- data/vendor/requests/packages/urllib3/_collections.py +324 -0
- data/vendor/requests/packages/urllib3/_collections.pyc +0 -0
- data/vendor/requests/packages/urllib3/connection.py +330 -0
- data/vendor/requests/packages/urllib3/connection.pyc +0 -0
- data/vendor/requests/packages/urllib3/connectionpool.py +866 -0
- data/vendor/requests/packages/urllib3/connectionpool.pyc +0 -0
- data/vendor/requests/packages/urllib3/contrib/__init__.py +0 -0
- data/vendor/requests/packages/urllib3/contrib/__init__.pyc +0 -0
- data/vendor/requests/packages/urllib3/contrib/appengine.py +231 -0
- data/vendor/requests/packages/urllib3/contrib/appengine.pyc +0 -0
- data/vendor/requests/packages/urllib3/contrib/ntlmpool.py +115 -0
- data/vendor/requests/packages/urllib3/contrib/ntlmpool.pyc +0 -0
- data/vendor/requests/packages/urllib3/contrib/pyopenssl.py +358 -0
- data/vendor/requests/packages/urllib3/contrib/pyopenssl.pyc +0 -0
- data/vendor/requests/packages/urllib3/contrib/socks.py +172 -0
- data/vendor/requests/packages/urllib3/contrib/socks.pyc +0 -0
- data/vendor/requests/packages/urllib3/exceptions.py +209 -0
- data/vendor/requests/packages/urllib3/exceptions.pyc +0 -0
- data/vendor/requests/packages/urllib3/fields.py +178 -0
- data/vendor/requests/packages/urllib3/fields.pyc +0 -0
- data/vendor/requests/packages/urllib3/filepost.py +94 -0
- data/vendor/requests/packages/urllib3/filepost.pyc +0 -0
- data/vendor/requests/packages/urllib3/packages/__init__.py +5 -0
- data/vendor/requests/packages/urllib3/packages/__init__.pyc +0 -0
- data/vendor/requests/packages/urllib3/packages/ordered_dict.py +259 -0
- data/vendor/requests/packages/urllib3/packages/ordered_dict.pyc +0 -0
- data/vendor/requests/packages/urllib3/packages/six.py +868 -0
- data/vendor/requests/packages/urllib3/packages/six.pyc +0 -0
- data/vendor/requests/packages/urllib3/packages/ssl_match_hostname/__init__.py +13 -0
- data/vendor/requests/packages/urllib3/packages/ssl_match_hostname/__init__.pyc +0 -0
- data/vendor/requests/packages/urllib3/packages/ssl_match_hostname/_implementation.py +105 -0
- data/vendor/requests/packages/urllib3/packages/ssl_match_hostname/_implementation.pyc +0 -0
- data/vendor/requests/packages/urllib3/poolmanager.py +367 -0
- data/vendor/requests/packages/urllib3/poolmanager.pyc +0 -0
- data/vendor/requests/packages/urllib3/request.py +151 -0
- data/vendor/requests/packages/urllib3/request.pyc +0 -0
- data/vendor/requests/packages/urllib3/response.py +530 -0
- data/vendor/requests/packages/urllib3/response.pyc +0 -0
- data/vendor/requests/packages/urllib3/util/__init__.py +46 -0
- data/vendor/requests/packages/urllib3/util/__init__.pyc +0 -0
- data/vendor/requests/packages/urllib3/util/connection.py +144 -0
- data/vendor/requests/packages/urllib3/util/connection.pyc +0 -0
- data/vendor/requests/packages/urllib3/util/request.py +72 -0
- data/vendor/requests/packages/urllib3/util/request.pyc +0 -0
- data/vendor/requests/packages/urllib3/util/response.py +74 -0
- data/vendor/requests/packages/urllib3/util/response.pyc +0 -0
- data/vendor/requests/packages/urllib3/util/retry.py +300 -0
- data/vendor/requests/packages/urllib3/util/retry.pyc +0 -0
- data/vendor/requests/packages/urllib3/util/ssl_.py +320 -0
- data/vendor/requests/packages/urllib3/util/ssl_.pyc +0 -0
- data/vendor/requests/packages/urllib3/util/timeout.py +242 -0
- data/vendor/requests/packages/urllib3/util/timeout.pyc +0 -0
- data/vendor/requests/packages/urllib3/util/url.py +217 -0
- data/vendor/requests/packages/urllib3/util/url.pyc +0 -0
- data/vendor/requests/sessions.py +712 -0
- data/vendor/requests/sessions.pyc +0 -0
- data/vendor/requests/status_codes.py +91 -0
- data/vendor/requests/status_codes.pyc +0 -0
- data/vendor/requests/structures.py +105 -0
- data/vendor/requests/structures.pyc +0 -0
- data/vendor/requests/utils.py +817 -0
- data/vendor/requests/utils.pyc +0 -0
- data/vendor/requests-2.11.1.dist-info/DESCRIPTION.rst +1294 -0
- data/vendor/requests-2.11.1.dist-info/INSTALLER +1 -0
- data/vendor/requests-2.11.1.dist-info/METADATA +1323 -0
- data/vendor/requests-2.11.1.dist-info/RECORD +170 -0
- data/vendor/requests-2.11.1.dist-info/WHEEL +6 -0
- data/vendor/requests-2.11.1.dist-info/metadata.json +1 -0
- data/vendor/requests-2.11.1.dist-info/top_level.txt +1 -0
- data/vendor/rigid/__init__.py +1 -0
- data/vendor/rigid/__init__.pyc +0 -0
- data/vendor/rigid/api.py +129 -0
- data/vendor/rigid/api.pyc +0 -0
- data/vendor/rigid/commands/__init__.py +260 -0
- data/vendor/rigid/commands/__init__.pyc +0 -0
- data/vendor/rigid/commands/deploy.py +0 -0
- data/vendor/rigid/commands/deploy.pyc +0 -0
- data/vendor/rigid/deploy.py +70 -0
- data/vendor/rigid/deploy.pyc +0 -0
- data/vendor/rigid/file_scanner.py +63 -0
- data/vendor/rigid/file_scanner.pyc +0 -0
- data/vendor/rigid/utils.py +17 -0
- data/vendor/rigid/utils.pyc +0 -0
- data/vendor/rigid-0.2.0.dist-info/DESCRIPTION.rst +3 -0
- data/vendor/rigid-0.2.0.dist-info/INSTALLER +1 -0
- data/vendor/rigid-0.2.0.dist-info/METADATA +23 -0
- data/vendor/rigid-0.2.0.dist-info/RECORD +49 -0
- data/vendor/rigid-0.2.0.dist-info/WHEEL +5 -0
- data/vendor/rigid-0.2.0.dist-info/entry_points.txt +3 -0
- data/vendor/rigid-0.2.0.dist-info/metadata.json +1 -0
- data/vendor/rigid-0.2.0.dist-info/top_level.txt +2 -0
- data/vendor/setuptools-28.8.0.dist-info/DESCRIPTION.rst +243 -0
- data/vendor/setuptools-28.8.0.dist-info/INSTALLER +1 -0
- data/vendor/setuptools-28.8.0.dist-info/METADATA +272 -0
- data/vendor/setuptools-28.8.0.dist-info/RECORD +143 -0
- data/vendor/setuptools-28.8.0.dist-info/WHEEL +6 -0
- data/vendor/setuptools-28.8.0.dist-info/dependency_links.txt +2 -0
- data/vendor/setuptools-28.8.0.dist-info/entry_points.txt +63 -0
- data/vendor/setuptools-28.8.0.dist-info/metadata.json +1 -0
- data/vendor/setuptools-28.8.0.dist-info/top_level.txt +3 -0
- data/vendor/setuptools-28.8.0.dist-info/zip-safe +1 -0
- data/vendor/tests/__init__.py +0 -0
- data/vendor/tests/__init__.pyc +0 -0
- data/vendor/tests/integration/__init__.py +0 -0
- data/vendor/tests/integration/__init__.pyc +0 -0
- data/vendor/tests/integration/test_app.py +63 -0
- data/vendor/tests/integration/test_app.pyc +0 -0
- data/vendor/tests/integration/test_apps.py +27 -0
- data/vendor/tests/integration/test_apps.pyc +0 -0
- data/vendor/tests/integration/test_deploy.py +128 -0
- data/vendor/tests/integration/test_deploy.pyc +0 -0
- data/vendor/tests/integration/test_domains.py +35 -0
- data/vendor/tests/integration/test_domains.pyc +0 -0
- data/vendor/tests/integration/test_login.py +37 -0
- data/vendor/tests/integration/test_login.pyc +0 -0
- data/vendor/tests/integration/test_promote.py +24 -0
- data/vendor/tests/integration/test_promote.pyc +0 -0
- data/vendor/tests/integration/test_token.py +33 -0
- data/vendor/tests/integration/test_token.pyc +0 -0
- data/vendor/tests/integration/test_whoami.py +24 -0
- data/vendor/tests/integration/test_whoami.pyc +0 -0
- data/vendor/tests/test_deploy.py +33 -0
- data/vendor/tests/test_deploy.pyc +0 -0
- data/vendor/tests/test_file_scanner.py +89 -0
- data/vendor/tests/test_file_scanner.pyc +0 -0
- data/vendor/tests/utils.py +78 -0
- data/vendor/tests/utils.pyc +0 -0
- data/vendor/wheel-0.30.0a0.dist-info/DESCRIPTION.rst +325 -0
- data/vendor/wheel-0.30.0a0.dist-info/INSTALLER +1 -0
- data/vendor/wheel-0.30.0a0.dist-info/LICENSE.txt +22 -0
- data/vendor/wheel-0.30.0a0.dist-info/METADATA +357 -0
- data/vendor/wheel-0.30.0a0.dist-info/RECORD +86 -0
- data/vendor/wheel-0.30.0a0.dist-info/WHEEL +6 -0
- data/vendor/wheel-0.30.0a0.dist-info/entry_points.txt +6 -0
- data/vendor/wheel-0.30.0a0.dist-info/metadata.json +1 -0
- data/vendor/wheel-0.30.0a0.dist-info/top_level.txt +1 -0
- data/vendor/yaml/__init__.py +315 -0
- data/vendor/yaml/__init__.pyc +0 -0
- data/vendor/yaml/composer.py +139 -0
- data/vendor/yaml/composer.pyc +0 -0
- data/vendor/yaml/constructor.py +675 -0
- data/vendor/yaml/constructor.pyc +0 -0
- data/vendor/yaml/cyaml.py +85 -0
- data/vendor/yaml/cyaml.pyc +0 -0
- data/vendor/yaml/dumper.py +62 -0
- data/vendor/yaml/dumper.pyc +0 -0
- data/vendor/yaml/emitter.py +1140 -0
- data/vendor/yaml/emitter.pyc +0 -0
- data/vendor/yaml/error.py +75 -0
- data/vendor/yaml/error.pyc +0 -0
- data/vendor/yaml/events.py +86 -0
- data/vendor/yaml/events.pyc +0 -0
- data/vendor/yaml/loader.py +40 -0
- data/vendor/yaml/loader.pyc +0 -0
- data/vendor/yaml/nodes.py +49 -0
- data/vendor/yaml/nodes.pyc +0 -0
- data/vendor/yaml/parser.py +589 -0
- data/vendor/yaml/parser.pyc +0 -0
- data/vendor/yaml/reader.py +190 -0
- data/vendor/yaml/reader.pyc +0 -0
- data/vendor/yaml/representer.py +486 -0
- data/vendor/yaml/representer.pyc +0 -0
- data/vendor/yaml/resolver.py +227 -0
- data/vendor/yaml/resolver.pyc +0 -0
- data/vendor/yaml/scanner.py +1453 -0
- data/vendor/yaml/scanner.pyc +0 -0
- data/vendor/yaml/serializer.py +111 -0
- data/vendor/yaml/serializer.pyc +0 -0
- data/vendor/yaml/tokens.py +104 -0
- data/vendor/yaml/tokens.pyc +0 -0
- metadata +407 -0
@@ -0,0 +1,873 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
"""
|
4
|
+
requests.models
|
5
|
+
~~~~~~~~~~~~~~~
|
6
|
+
|
7
|
+
This module contains the primary objects that power Requests.
|
8
|
+
"""
|
9
|
+
|
10
|
+
import collections
|
11
|
+
import datetime
|
12
|
+
|
13
|
+
from io import BytesIO, UnsupportedOperation
|
14
|
+
from .hooks import default_hooks
|
15
|
+
from .structures import CaseInsensitiveDict
|
16
|
+
|
17
|
+
from .auth import HTTPBasicAuth
|
18
|
+
from .cookies import cookiejar_from_dict, get_cookie_header, _copy_cookie_jar
|
19
|
+
from .packages.urllib3.fields import RequestField
|
20
|
+
from .packages.urllib3.filepost import encode_multipart_formdata
|
21
|
+
from .packages.urllib3.util import parse_url
|
22
|
+
from .packages.urllib3.exceptions import (
|
23
|
+
DecodeError, ReadTimeoutError, ProtocolError, LocationParseError)
|
24
|
+
from .exceptions import (
|
25
|
+
HTTPError, MissingSchema, InvalidURL, ChunkedEncodingError,
|
26
|
+
ContentDecodingError, ConnectionError, StreamConsumedError)
|
27
|
+
from .utils import (
|
28
|
+
guess_filename, get_auth_from_url, requote_uri,
|
29
|
+
stream_decode_response_unicode, to_key_val_list, parse_header_links,
|
30
|
+
iter_slices, guess_json_utf, super_len, to_native_string,
|
31
|
+
check_header_validity)
|
32
|
+
from .compat import (
|
33
|
+
cookielib, urlunparse, urlsplit, urlencode, str, bytes, StringIO,
|
34
|
+
is_py2, chardet, builtin_str, basestring)
|
35
|
+
from .compat import json as complexjson
|
36
|
+
from .status_codes import codes
|
37
|
+
|
38
|
+
#: The set of HTTP status codes that indicate an automatically
|
39
|
+
#: processable redirect.
|
40
|
+
REDIRECT_STATI = (
|
41
|
+
codes.moved, # 301
|
42
|
+
codes.found, # 302
|
43
|
+
codes.other, # 303
|
44
|
+
codes.temporary_redirect, # 307
|
45
|
+
codes.permanent_redirect, # 308
|
46
|
+
)
|
47
|
+
|
48
|
+
DEFAULT_REDIRECT_LIMIT = 30
|
49
|
+
CONTENT_CHUNK_SIZE = 10 * 1024
|
50
|
+
ITER_CHUNK_SIZE = 512
|
51
|
+
|
52
|
+
|
53
|
+
class RequestEncodingMixin(object):
|
54
|
+
@property
|
55
|
+
def path_url(self):
|
56
|
+
"""Build the path URL to use."""
|
57
|
+
|
58
|
+
url = []
|
59
|
+
|
60
|
+
p = urlsplit(self.url)
|
61
|
+
|
62
|
+
path = p.path
|
63
|
+
if not path:
|
64
|
+
path = '/'
|
65
|
+
|
66
|
+
url.append(path)
|
67
|
+
|
68
|
+
query = p.query
|
69
|
+
if query:
|
70
|
+
url.append('?')
|
71
|
+
url.append(query)
|
72
|
+
|
73
|
+
return ''.join(url)
|
74
|
+
|
75
|
+
@staticmethod
|
76
|
+
def _encode_params(data):
|
77
|
+
"""Encode parameters in a piece of data.
|
78
|
+
|
79
|
+
Will successfully encode parameters when passed as a dict or a list of
|
80
|
+
2-tuples. Order is retained if data is a list of 2-tuples but arbitrary
|
81
|
+
if parameters are supplied as a dict.
|
82
|
+
"""
|
83
|
+
|
84
|
+
if isinstance(data, (str, bytes)):
|
85
|
+
return data
|
86
|
+
elif hasattr(data, 'read'):
|
87
|
+
return data
|
88
|
+
elif hasattr(data, '__iter__'):
|
89
|
+
result = []
|
90
|
+
for k, vs in to_key_val_list(data):
|
91
|
+
if isinstance(vs, basestring) or not hasattr(vs, '__iter__'):
|
92
|
+
vs = [vs]
|
93
|
+
for v in vs:
|
94
|
+
if v is not None:
|
95
|
+
result.append(
|
96
|
+
(k.encode('utf-8') if isinstance(k, str) else k,
|
97
|
+
v.encode('utf-8') if isinstance(v, str) else v))
|
98
|
+
return urlencode(result, doseq=True)
|
99
|
+
else:
|
100
|
+
return data
|
101
|
+
|
102
|
+
@staticmethod
|
103
|
+
def _encode_files(files, data):
|
104
|
+
"""Build the body for a multipart/form-data request.
|
105
|
+
|
106
|
+
Will successfully encode files when passed as a dict or a list of
|
107
|
+
tuples. Order is retained if data is a list of tuples but arbitrary
|
108
|
+
if parameters are supplied as a dict.
|
109
|
+
The tuples may be 2-tuples (filename, fileobj), 3-tuples (filename, fileobj, contentype)
|
110
|
+
or 4-tuples (filename, fileobj, contentype, custom_headers).
|
111
|
+
"""
|
112
|
+
if (not files):
|
113
|
+
raise ValueError("Files must be provided.")
|
114
|
+
elif isinstance(data, basestring):
|
115
|
+
raise ValueError("Data must not be a string.")
|
116
|
+
|
117
|
+
new_fields = []
|
118
|
+
fields = to_key_val_list(data or {})
|
119
|
+
files = to_key_val_list(files or {})
|
120
|
+
|
121
|
+
for field, val in fields:
|
122
|
+
if isinstance(val, basestring) or not hasattr(val, '__iter__'):
|
123
|
+
val = [val]
|
124
|
+
for v in val:
|
125
|
+
if v is not None:
|
126
|
+
# Don't call str() on bytestrings: in Py3 it all goes wrong.
|
127
|
+
if not isinstance(v, bytes):
|
128
|
+
v = str(v)
|
129
|
+
|
130
|
+
new_fields.append(
|
131
|
+
(field.decode('utf-8') if isinstance(field, bytes) else field,
|
132
|
+
v.encode('utf-8') if isinstance(v, str) else v))
|
133
|
+
|
134
|
+
for (k, v) in files:
|
135
|
+
# support for explicit filename
|
136
|
+
ft = None
|
137
|
+
fh = None
|
138
|
+
if isinstance(v, (tuple, list)):
|
139
|
+
if len(v) == 2:
|
140
|
+
fn, fp = v
|
141
|
+
elif len(v) == 3:
|
142
|
+
fn, fp, ft = v
|
143
|
+
else:
|
144
|
+
fn, fp, ft, fh = v
|
145
|
+
else:
|
146
|
+
fn = guess_filename(v) or k
|
147
|
+
fp = v
|
148
|
+
|
149
|
+
if isinstance(fp, (str, bytes, bytearray)):
|
150
|
+
fdata = fp
|
151
|
+
else:
|
152
|
+
fdata = fp.read()
|
153
|
+
|
154
|
+
rf = RequestField(name=k, data=fdata, filename=fn, headers=fh)
|
155
|
+
rf.make_multipart(content_type=ft)
|
156
|
+
new_fields.append(rf)
|
157
|
+
|
158
|
+
body, content_type = encode_multipart_formdata(new_fields)
|
159
|
+
|
160
|
+
return body, content_type
|
161
|
+
|
162
|
+
|
163
|
+
class RequestHooksMixin(object):
|
164
|
+
def register_hook(self, event, hook):
|
165
|
+
"""Properly register a hook."""
|
166
|
+
|
167
|
+
if event not in self.hooks:
|
168
|
+
raise ValueError('Unsupported event specified, with event name "%s"' % (event))
|
169
|
+
|
170
|
+
if isinstance(hook, collections.Callable):
|
171
|
+
self.hooks[event].append(hook)
|
172
|
+
elif hasattr(hook, '__iter__'):
|
173
|
+
self.hooks[event].extend(h for h in hook if isinstance(h, collections.Callable))
|
174
|
+
|
175
|
+
def deregister_hook(self, event, hook):
|
176
|
+
"""Deregister a previously registered hook.
|
177
|
+
Returns True if the hook existed, False if not.
|
178
|
+
"""
|
179
|
+
|
180
|
+
try:
|
181
|
+
self.hooks[event].remove(hook)
|
182
|
+
return True
|
183
|
+
except ValueError:
|
184
|
+
return False
|
185
|
+
|
186
|
+
|
187
|
+
class Request(RequestHooksMixin):
|
188
|
+
"""A user-created :class:`Request <Request>` object.
|
189
|
+
|
190
|
+
Used to prepare a :class:`PreparedRequest <PreparedRequest>`, which is sent to the server.
|
191
|
+
|
192
|
+
:param method: HTTP method to use.
|
193
|
+
:param url: URL to send.
|
194
|
+
:param headers: dictionary of headers to send.
|
195
|
+
:param files: dictionary of {filename: fileobject} files to multipart upload.
|
196
|
+
:param data: the body to attach to the request. If a dictionary is provided, form-encoding will take place.
|
197
|
+
:param json: json for the body to attach to the request (if files or data is not specified).
|
198
|
+
:param params: dictionary of URL parameters to append to the URL.
|
199
|
+
:param auth: Auth handler or (user, pass) tuple.
|
200
|
+
:param cookies: dictionary or CookieJar of cookies to attach to this request.
|
201
|
+
:param hooks: dictionary of callback hooks, for internal usage.
|
202
|
+
|
203
|
+
Usage::
|
204
|
+
|
205
|
+
>>> import requests
|
206
|
+
>>> req = requests.Request('GET', 'http://httpbin.org/get')
|
207
|
+
>>> req.prepare()
|
208
|
+
<PreparedRequest [GET]>
|
209
|
+
"""
|
210
|
+
|
211
|
+
def __init__(self, method=None, url=None, headers=None, files=None,
|
212
|
+
data=None, params=None, auth=None, cookies=None, hooks=None, json=None):
|
213
|
+
|
214
|
+
# Default empty dicts for dict params.
|
215
|
+
data = [] if data is None else data
|
216
|
+
files = [] if files is None else files
|
217
|
+
headers = {} if headers is None else headers
|
218
|
+
params = {} if params is None else params
|
219
|
+
hooks = {} if hooks is None else hooks
|
220
|
+
|
221
|
+
self.hooks = default_hooks()
|
222
|
+
for (k, v) in list(hooks.items()):
|
223
|
+
self.register_hook(event=k, hook=v)
|
224
|
+
|
225
|
+
self.method = method
|
226
|
+
self.url = url
|
227
|
+
self.headers = headers
|
228
|
+
self.files = files
|
229
|
+
self.data = data
|
230
|
+
self.json = json
|
231
|
+
self.params = params
|
232
|
+
self.auth = auth
|
233
|
+
self.cookies = cookies
|
234
|
+
|
235
|
+
def __repr__(self):
|
236
|
+
return '<Request [%s]>' % (self.method)
|
237
|
+
|
238
|
+
def prepare(self):
|
239
|
+
"""Constructs a :class:`PreparedRequest <PreparedRequest>` for transmission and returns it."""
|
240
|
+
p = PreparedRequest()
|
241
|
+
p.prepare(
|
242
|
+
method=self.method,
|
243
|
+
url=self.url,
|
244
|
+
headers=self.headers,
|
245
|
+
files=self.files,
|
246
|
+
data=self.data,
|
247
|
+
json=self.json,
|
248
|
+
params=self.params,
|
249
|
+
auth=self.auth,
|
250
|
+
cookies=self.cookies,
|
251
|
+
hooks=self.hooks,
|
252
|
+
)
|
253
|
+
return p
|
254
|
+
|
255
|
+
|
256
|
+
class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
|
257
|
+
"""The fully mutable :class:`PreparedRequest <PreparedRequest>` object,
|
258
|
+
containing the exact bytes that will be sent to the server.
|
259
|
+
|
260
|
+
Generated from either a :class:`Request <Request>` object or manually.
|
261
|
+
|
262
|
+
Usage::
|
263
|
+
|
264
|
+
>>> import requests
|
265
|
+
>>> req = requests.Request('GET', 'http://httpbin.org/get')
|
266
|
+
>>> r = req.prepare()
|
267
|
+
<PreparedRequest [GET]>
|
268
|
+
|
269
|
+
>>> s = requests.Session()
|
270
|
+
>>> s.send(r)
|
271
|
+
<Response [200]>
|
272
|
+
"""
|
273
|
+
|
274
|
+
def __init__(self):
|
275
|
+
#: HTTP verb to send to the server.
|
276
|
+
self.method = None
|
277
|
+
#: HTTP URL to send the request to.
|
278
|
+
self.url = None
|
279
|
+
#: dictionary of HTTP headers.
|
280
|
+
self.headers = None
|
281
|
+
# The `CookieJar` used to create the Cookie header will be stored here
|
282
|
+
# after prepare_cookies is called
|
283
|
+
self._cookies = None
|
284
|
+
#: request body to send to the server.
|
285
|
+
self.body = None
|
286
|
+
#: dictionary of callback hooks, for internal usage.
|
287
|
+
self.hooks = default_hooks()
|
288
|
+
|
289
|
+
def prepare(self, method=None, url=None, headers=None, files=None,
|
290
|
+
data=None, params=None, auth=None, cookies=None, hooks=None, json=None):
|
291
|
+
"""Prepares the entire request with the given parameters."""
|
292
|
+
|
293
|
+
self.prepare_method(method)
|
294
|
+
self.prepare_url(url, params)
|
295
|
+
self.prepare_headers(headers)
|
296
|
+
self.prepare_cookies(cookies)
|
297
|
+
self.prepare_body(data, files, json)
|
298
|
+
self.prepare_auth(auth, url)
|
299
|
+
|
300
|
+
# Note that prepare_auth must be last to enable authentication schemes
|
301
|
+
# such as OAuth to work on a fully prepared request.
|
302
|
+
|
303
|
+
# This MUST go after prepare_auth. Authenticators could add a hook
|
304
|
+
self.prepare_hooks(hooks)
|
305
|
+
|
306
|
+
def __repr__(self):
|
307
|
+
return '<PreparedRequest [%s]>' % (self.method)
|
308
|
+
|
309
|
+
def copy(self):
|
310
|
+
p = PreparedRequest()
|
311
|
+
p.method = self.method
|
312
|
+
p.url = self.url
|
313
|
+
p.headers = self.headers.copy() if self.headers is not None else None
|
314
|
+
p._cookies = _copy_cookie_jar(self._cookies)
|
315
|
+
p.body = self.body
|
316
|
+
p.hooks = self.hooks
|
317
|
+
return p
|
318
|
+
|
319
|
+
def prepare_method(self, method):
|
320
|
+
"""Prepares the given HTTP method."""
|
321
|
+
self.method = method
|
322
|
+
if self.method is not None:
|
323
|
+
self.method = to_native_string(self.method.upper())
|
324
|
+
|
325
|
+
def prepare_url(self, url, params):
|
326
|
+
"""Prepares the given HTTP URL."""
|
327
|
+
#: Accept objects that have string representations.
|
328
|
+
#: We're unable to blindly call unicode/str functions
|
329
|
+
#: as this will include the bytestring indicator (b'')
|
330
|
+
#: on python 3.x.
|
331
|
+
#: https://github.com/kennethreitz/requests/pull/2238
|
332
|
+
if isinstance(url, bytes):
|
333
|
+
url = url.decode('utf8')
|
334
|
+
else:
|
335
|
+
url = unicode(url) if is_py2 else str(url)
|
336
|
+
|
337
|
+
# Don't do any URL preparation for non-HTTP schemes like `mailto`,
|
338
|
+
# `data` etc to work around exceptions from `url_parse`, which
|
339
|
+
# handles RFC 3986 only.
|
340
|
+
if ':' in url and not url.lower().startswith('http'):
|
341
|
+
self.url = url
|
342
|
+
return
|
343
|
+
|
344
|
+
# Support for unicode domain names and paths.
|
345
|
+
try:
|
346
|
+
scheme, auth, host, port, path, query, fragment = parse_url(url)
|
347
|
+
except LocationParseError as e:
|
348
|
+
raise InvalidURL(*e.args)
|
349
|
+
|
350
|
+
if not scheme:
|
351
|
+
error = ("Invalid URL {0!r}: No schema supplied. Perhaps you meant http://{0}?")
|
352
|
+
error = error.format(to_native_string(url, 'utf8'))
|
353
|
+
|
354
|
+
raise MissingSchema(error)
|
355
|
+
|
356
|
+
if not host:
|
357
|
+
raise InvalidURL("Invalid URL %r: No host supplied" % url)
|
358
|
+
|
359
|
+
# Only want to apply IDNA to the hostname
|
360
|
+
try:
|
361
|
+
host = host.encode('idna').decode('utf-8')
|
362
|
+
except UnicodeError:
|
363
|
+
raise InvalidURL('URL has an invalid label.')
|
364
|
+
|
365
|
+
# Carefully reconstruct the network location
|
366
|
+
netloc = auth or ''
|
367
|
+
if netloc:
|
368
|
+
netloc += '@'
|
369
|
+
netloc += host
|
370
|
+
if port:
|
371
|
+
netloc += ':' + str(port)
|
372
|
+
|
373
|
+
# Bare domains aren't valid URLs.
|
374
|
+
if not path:
|
375
|
+
path = '/'
|
376
|
+
|
377
|
+
if is_py2:
|
378
|
+
if isinstance(scheme, str):
|
379
|
+
scheme = scheme.encode('utf-8')
|
380
|
+
if isinstance(netloc, str):
|
381
|
+
netloc = netloc.encode('utf-8')
|
382
|
+
if isinstance(path, str):
|
383
|
+
path = path.encode('utf-8')
|
384
|
+
if isinstance(query, str):
|
385
|
+
query = query.encode('utf-8')
|
386
|
+
if isinstance(fragment, str):
|
387
|
+
fragment = fragment.encode('utf-8')
|
388
|
+
|
389
|
+
if isinstance(params, (str, bytes)):
|
390
|
+
params = to_native_string(params)
|
391
|
+
|
392
|
+
enc_params = self._encode_params(params)
|
393
|
+
if enc_params:
|
394
|
+
if query:
|
395
|
+
query = '%s&%s' % (query, enc_params)
|
396
|
+
else:
|
397
|
+
query = enc_params
|
398
|
+
|
399
|
+
url = requote_uri(urlunparse([scheme, netloc, path, None, query, fragment]))
|
400
|
+
self.url = url
|
401
|
+
|
402
|
+
def prepare_headers(self, headers):
|
403
|
+
"""Prepares the given HTTP headers."""
|
404
|
+
|
405
|
+
self.headers = CaseInsensitiveDict()
|
406
|
+
if headers:
|
407
|
+
for header in headers.items():
|
408
|
+
# Raise exception on invalid header value.
|
409
|
+
check_header_validity(header)
|
410
|
+
name, value = header
|
411
|
+
self.headers[to_native_string(name)] = value
|
412
|
+
|
413
|
+
def prepare_body(self, data, files, json=None):
|
414
|
+
"""Prepares the given HTTP body data."""
|
415
|
+
|
416
|
+
# Check if file, fo, generator, iterator.
|
417
|
+
# If not, run through normal process.
|
418
|
+
|
419
|
+
# Nottin' on you.
|
420
|
+
body = None
|
421
|
+
content_type = None
|
422
|
+
length = None
|
423
|
+
|
424
|
+
if not data and json is not None:
|
425
|
+
# urllib3 requires a bytes-like body. Python 2's json.dumps
|
426
|
+
# provides this natively, but Python 3 gives a Unicode string.
|
427
|
+
content_type = 'application/json'
|
428
|
+
body = complexjson.dumps(json)
|
429
|
+
if not isinstance(body, bytes):
|
430
|
+
body = body.encode('utf-8')
|
431
|
+
|
432
|
+
is_stream = all([
|
433
|
+
hasattr(data, '__iter__'),
|
434
|
+
not isinstance(data, (basestring, list, tuple, dict))
|
435
|
+
])
|
436
|
+
|
437
|
+
try:
|
438
|
+
length = super_len(data)
|
439
|
+
except (TypeError, AttributeError, UnsupportedOperation):
|
440
|
+
length = None
|
441
|
+
|
442
|
+
if is_stream:
|
443
|
+
body = data
|
444
|
+
|
445
|
+
if files:
|
446
|
+
raise NotImplementedError('Streamed bodies and files are mutually exclusive.')
|
447
|
+
|
448
|
+
if length:
|
449
|
+
self.headers['Content-Length'] = builtin_str(length)
|
450
|
+
else:
|
451
|
+
self.headers['Transfer-Encoding'] = 'chunked'
|
452
|
+
else:
|
453
|
+
# Multi-part file uploads.
|
454
|
+
if files:
|
455
|
+
(body, content_type) = self._encode_files(files, data)
|
456
|
+
else:
|
457
|
+
if data:
|
458
|
+
body = self._encode_params(data)
|
459
|
+
if isinstance(data, basestring) or hasattr(data, 'read'):
|
460
|
+
content_type = None
|
461
|
+
else:
|
462
|
+
content_type = 'application/x-www-form-urlencoded'
|
463
|
+
|
464
|
+
self.prepare_content_length(body)
|
465
|
+
|
466
|
+
# Add content-type if it wasn't explicitly provided.
|
467
|
+
if content_type and ('content-type' not in self.headers):
|
468
|
+
self.headers['Content-Type'] = content_type
|
469
|
+
|
470
|
+
self.body = body
|
471
|
+
|
472
|
+
def prepare_content_length(self, body):
|
473
|
+
if hasattr(body, 'seek') and hasattr(body, 'tell'):
|
474
|
+
curr_pos = body.tell()
|
475
|
+
body.seek(0, 2)
|
476
|
+
end_pos = body.tell()
|
477
|
+
self.headers['Content-Length'] = builtin_str(max(0, end_pos - curr_pos))
|
478
|
+
body.seek(curr_pos, 0)
|
479
|
+
elif body is not None:
|
480
|
+
l = super_len(body)
|
481
|
+
if l:
|
482
|
+
self.headers['Content-Length'] = builtin_str(l)
|
483
|
+
elif (self.method not in ('GET', 'HEAD')) and (self.headers.get('Content-Length') is None):
|
484
|
+
self.headers['Content-Length'] = '0'
|
485
|
+
|
486
|
+
def prepare_auth(self, auth, url=''):
|
487
|
+
"""Prepares the given HTTP auth data."""
|
488
|
+
|
489
|
+
# If no Auth is explicitly provided, extract it from the URL first.
|
490
|
+
if auth is None:
|
491
|
+
url_auth = get_auth_from_url(self.url)
|
492
|
+
auth = url_auth if any(url_auth) else None
|
493
|
+
|
494
|
+
if auth:
|
495
|
+
if isinstance(auth, tuple) and len(auth) == 2:
|
496
|
+
# special-case basic HTTP auth
|
497
|
+
auth = HTTPBasicAuth(*auth)
|
498
|
+
|
499
|
+
# Allow auth to make its changes.
|
500
|
+
r = auth(self)
|
501
|
+
|
502
|
+
# Update self to reflect the auth changes.
|
503
|
+
self.__dict__.update(r.__dict__)
|
504
|
+
|
505
|
+
# Recompute Content-Length
|
506
|
+
self.prepare_content_length(self.body)
|
507
|
+
|
508
|
+
def prepare_cookies(self, cookies):
|
509
|
+
"""Prepares the given HTTP cookie data.
|
510
|
+
|
511
|
+
This function eventually generates a ``Cookie`` header from the
|
512
|
+
given cookies using cookielib. Due to cookielib's design, the header
|
513
|
+
will not be regenerated if it already exists, meaning this function
|
514
|
+
can only be called once for the life of the
|
515
|
+
:class:`PreparedRequest <PreparedRequest>` object. Any subsequent calls
|
516
|
+
to ``prepare_cookies`` will have no actual effect, unless the "Cookie"
|
517
|
+
header is removed beforehand.
|
518
|
+
"""
|
519
|
+
if isinstance(cookies, cookielib.CookieJar):
|
520
|
+
self._cookies = cookies
|
521
|
+
else:
|
522
|
+
self._cookies = cookiejar_from_dict(cookies)
|
523
|
+
|
524
|
+
cookie_header = get_cookie_header(self._cookies, self)
|
525
|
+
if cookie_header is not None:
|
526
|
+
self.headers['Cookie'] = cookie_header
|
527
|
+
|
528
|
+
def prepare_hooks(self, hooks):
|
529
|
+
"""Prepares the given hooks."""
|
530
|
+
# hooks can be passed as None to the prepare method and to this
|
531
|
+
# method. To prevent iterating over None, simply use an empty list
|
532
|
+
# if hooks is False-y
|
533
|
+
hooks = hooks or []
|
534
|
+
for event in hooks:
|
535
|
+
self.register_hook(event, hooks[event])
|
536
|
+
|
537
|
+
|
538
|
+
class Response(object):
|
539
|
+
"""The :class:`Response <Response>` object, which contains a
|
540
|
+
server's response to an HTTP request.
|
541
|
+
"""
|
542
|
+
|
543
|
+
__attrs__ = [
|
544
|
+
'_content', 'status_code', 'headers', 'url', 'history',
|
545
|
+
'encoding', 'reason', 'cookies', 'elapsed', 'request'
|
546
|
+
]
|
547
|
+
|
548
|
+
def __init__(self):
|
549
|
+
super(Response, self).__init__()
|
550
|
+
|
551
|
+
self._content = False
|
552
|
+
self._content_consumed = False
|
553
|
+
|
554
|
+
#: Integer Code of responded HTTP Status, e.g. 404 or 200.
|
555
|
+
self.status_code = None
|
556
|
+
|
557
|
+
#: Case-insensitive Dictionary of Response Headers.
|
558
|
+
#: For example, ``headers['content-encoding']`` will return the
|
559
|
+
#: value of a ``'Content-Encoding'`` response header.
|
560
|
+
self.headers = CaseInsensitiveDict()
|
561
|
+
|
562
|
+
#: File-like object representation of response (for advanced usage).
|
563
|
+
#: Use of ``raw`` requires that ``stream=True`` be set on the request.
|
564
|
+
# This requirement does not apply for use internally to Requests.
|
565
|
+
self.raw = None
|
566
|
+
|
567
|
+
#: Final URL location of Response.
|
568
|
+
self.url = None
|
569
|
+
|
570
|
+
#: Encoding to decode with when accessing r.text.
|
571
|
+
self.encoding = None
|
572
|
+
|
573
|
+
#: A list of :class:`Response <Response>` objects from
|
574
|
+
#: the history of the Request. Any redirect responses will end
|
575
|
+
#: up here. The list is sorted from the oldest to the most recent request.
|
576
|
+
self.history = []
|
577
|
+
|
578
|
+
#: Textual reason of responded HTTP Status, e.g. "Not Found" or "OK".
|
579
|
+
self.reason = None
|
580
|
+
|
581
|
+
#: A CookieJar of Cookies the server sent back.
|
582
|
+
self.cookies = cookiejar_from_dict({})
|
583
|
+
|
584
|
+
#: The amount of time elapsed between sending the request
|
585
|
+
#: and the arrival of the response (as a timedelta).
|
586
|
+
#: This property specifically measures the time taken between sending
|
587
|
+
#: the first byte of the request and finishing parsing the headers. It
|
588
|
+
#: is therefore unaffected by consuming the response content or the
|
589
|
+
#: value of the ``stream`` keyword argument.
|
590
|
+
self.elapsed = datetime.timedelta(0)
|
591
|
+
|
592
|
+
#: The :class:`PreparedRequest <PreparedRequest>` object to which this
|
593
|
+
#: is a response.
|
594
|
+
self.request = None
|
595
|
+
|
596
|
+
def __getstate__(self):
|
597
|
+
# Consume everything; accessing the content attribute makes
|
598
|
+
# sure the content has been fully read.
|
599
|
+
if not self._content_consumed:
|
600
|
+
self.content
|
601
|
+
|
602
|
+
return dict(
|
603
|
+
(attr, getattr(self, attr, None))
|
604
|
+
for attr in self.__attrs__
|
605
|
+
)
|
606
|
+
|
607
|
+
def __setstate__(self, state):
|
608
|
+
for name, value in state.items():
|
609
|
+
setattr(self, name, value)
|
610
|
+
|
611
|
+
# pickled objects do not have .raw
|
612
|
+
setattr(self, '_content_consumed', True)
|
613
|
+
setattr(self, 'raw', None)
|
614
|
+
|
615
|
+
def __repr__(self):
|
616
|
+
return '<Response [%s]>' % (self.status_code)
|
617
|
+
|
618
|
+
def __bool__(self):
|
619
|
+
"""Returns true if :attr:`status_code` is 'OK'."""
|
620
|
+
return self.ok
|
621
|
+
|
622
|
+
def __nonzero__(self):
|
623
|
+
"""Returns true if :attr:`status_code` is 'OK'."""
|
624
|
+
return self.ok
|
625
|
+
|
626
|
+
def __iter__(self):
|
627
|
+
"""Allows you to use a response as an iterator."""
|
628
|
+
return self.iter_content(128)
|
629
|
+
|
630
|
+
@property
|
631
|
+
def ok(self):
|
632
|
+
try:
|
633
|
+
self.raise_for_status()
|
634
|
+
except HTTPError:
|
635
|
+
return False
|
636
|
+
return True
|
637
|
+
|
638
|
+
@property
|
639
|
+
def is_redirect(self):
|
640
|
+
"""True if this Response is a well-formed HTTP redirect that could have
|
641
|
+
been processed automatically (by :meth:`Session.resolve_redirects`).
|
642
|
+
"""
|
643
|
+
return ('location' in self.headers and self.status_code in REDIRECT_STATI)
|
644
|
+
|
645
|
+
@property
|
646
|
+
def is_permanent_redirect(self):
|
647
|
+
"""True if this Response one of the permanent versions of redirect"""
|
648
|
+
return ('location' in self.headers and self.status_code in (codes.moved_permanently, codes.permanent_redirect))
|
649
|
+
|
650
|
+
@property
|
651
|
+
def apparent_encoding(self):
|
652
|
+
"""The apparent encoding, provided by the chardet library"""
|
653
|
+
return chardet.detect(self.content)['encoding']
|
654
|
+
|
655
|
+
def iter_content(self, chunk_size=1, decode_unicode=False):
|
656
|
+
"""Iterates over the response data. When stream=True is set on the
|
657
|
+
request, this avoids reading the content at once into memory for
|
658
|
+
large responses. The chunk size is the number of bytes it should
|
659
|
+
read into memory. This is not necessarily the length of each item
|
660
|
+
returned as decoding can take place.
|
661
|
+
|
662
|
+
chunk_size must be of type int or None. A value of None will
|
663
|
+
function differently depending on the value of `stream`.
|
664
|
+
stream=True will read data as it arrives in whatever size the
|
665
|
+
chunks are received. If stream=False, data is returned as
|
666
|
+
a single chunk.
|
667
|
+
|
668
|
+
If decode_unicode is True, content will be decoded using the best
|
669
|
+
available encoding based on the response.
|
670
|
+
"""
|
671
|
+
|
672
|
+
def generate():
|
673
|
+
# Special case for urllib3.
|
674
|
+
if hasattr(self.raw, 'stream'):
|
675
|
+
try:
|
676
|
+
for chunk in self.raw.stream(chunk_size, decode_content=True):
|
677
|
+
yield chunk
|
678
|
+
except ProtocolError as e:
|
679
|
+
raise ChunkedEncodingError(e)
|
680
|
+
except DecodeError as e:
|
681
|
+
raise ContentDecodingError(e)
|
682
|
+
except ReadTimeoutError as e:
|
683
|
+
raise ConnectionError(e)
|
684
|
+
else:
|
685
|
+
# Standard file-like object.
|
686
|
+
while True:
|
687
|
+
chunk = self.raw.read(chunk_size)
|
688
|
+
if not chunk:
|
689
|
+
break
|
690
|
+
yield chunk
|
691
|
+
|
692
|
+
self._content_consumed = True
|
693
|
+
|
694
|
+
if self._content_consumed and isinstance(self._content, bool):
|
695
|
+
raise StreamConsumedError()
|
696
|
+
elif chunk_size is not None and not isinstance(chunk_size, int):
|
697
|
+
raise TypeError("chunk_size must be an int, it is instead a %s." % type(chunk_size))
|
698
|
+
# simulate reading small chunks of the content
|
699
|
+
reused_chunks = iter_slices(self._content, chunk_size)
|
700
|
+
|
701
|
+
stream_chunks = generate()
|
702
|
+
|
703
|
+
chunks = reused_chunks if self._content_consumed else stream_chunks
|
704
|
+
|
705
|
+
if decode_unicode:
|
706
|
+
chunks = stream_decode_response_unicode(chunks, self)
|
707
|
+
|
708
|
+
return chunks
|
709
|
+
|
710
|
+
def iter_lines(self, chunk_size=ITER_CHUNK_SIZE, decode_unicode=None, delimiter=None):
|
711
|
+
"""Iterates over the response data, one line at a time. When
|
712
|
+
stream=True is set on the request, this avoids reading the
|
713
|
+
content at once into memory for large responses.
|
714
|
+
|
715
|
+
.. note:: This method is not reentrant safe.
|
716
|
+
"""
|
717
|
+
|
718
|
+
pending = None
|
719
|
+
|
720
|
+
for chunk in self.iter_content(chunk_size=chunk_size, decode_unicode=decode_unicode):
|
721
|
+
|
722
|
+
if pending is not None:
|
723
|
+
chunk = pending + chunk
|
724
|
+
|
725
|
+
if delimiter:
|
726
|
+
lines = chunk.split(delimiter)
|
727
|
+
else:
|
728
|
+
lines = chunk.splitlines()
|
729
|
+
|
730
|
+
if lines and lines[-1] and chunk and lines[-1][-1] == chunk[-1]:
|
731
|
+
pending = lines.pop()
|
732
|
+
else:
|
733
|
+
pending = None
|
734
|
+
|
735
|
+
for line in lines:
|
736
|
+
yield line
|
737
|
+
|
738
|
+
if pending is not None:
|
739
|
+
yield pending
|
740
|
+
|
741
|
+
@property
|
742
|
+
def content(self):
|
743
|
+
"""Content of the response, in bytes."""
|
744
|
+
|
745
|
+
if self._content is False:
|
746
|
+
# Read the contents.
|
747
|
+
try:
|
748
|
+
if self._content_consumed:
|
749
|
+
raise RuntimeError(
|
750
|
+
'The content for this response was already consumed')
|
751
|
+
|
752
|
+
if self.status_code == 0:
|
753
|
+
self._content = None
|
754
|
+
else:
|
755
|
+
self._content = bytes().join(self.iter_content(CONTENT_CHUNK_SIZE)) or bytes()
|
756
|
+
|
757
|
+
except AttributeError:
|
758
|
+
self._content = None
|
759
|
+
|
760
|
+
self._content_consumed = True
|
761
|
+
# don't need to release the connection; that's been handled by urllib3
|
762
|
+
# since we exhausted the data.
|
763
|
+
return self._content
|
764
|
+
|
765
|
+
@property
|
766
|
+
def text(self):
|
767
|
+
"""Content of the response, in unicode.
|
768
|
+
|
769
|
+
If Response.encoding is None, encoding will be guessed using
|
770
|
+
``chardet``.
|
771
|
+
|
772
|
+
The encoding of the response content is determined based solely on HTTP
|
773
|
+
headers, following RFC 2616 to the letter. If you can take advantage of
|
774
|
+
non-HTTP knowledge to make a better guess at the encoding, you should
|
775
|
+
set ``r.encoding`` appropriately before accessing this property.
|
776
|
+
"""
|
777
|
+
|
778
|
+
# Try charset from content-type
|
779
|
+
content = None
|
780
|
+
encoding = self.encoding
|
781
|
+
|
782
|
+
if not self.content:
|
783
|
+
return str('')
|
784
|
+
|
785
|
+
# Fallback to auto-detected encoding.
|
786
|
+
if self.encoding is None:
|
787
|
+
encoding = self.apparent_encoding
|
788
|
+
|
789
|
+
# Decode unicode from given encoding.
|
790
|
+
try:
|
791
|
+
content = str(self.content, encoding, errors='replace')
|
792
|
+
except (LookupError, TypeError):
|
793
|
+
# A LookupError is raised if the encoding was not found which could
|
794
|
+
# indicate a misspelling or similar mistake.
|
795
|
+
#
|
796
|
+
# A TypeError can be raised if encoding is None
|
797
|
+
#
|
798
|
+
# So we try blindly encoding.
|
799
|
+
content = str(self.content, errors='replace')
|
800
|
+
|
801
|
+
return content
|
802
|
+
|
803
|
+
def json(self, **kwargs):
|
804
|
+
"""Returns the json-encoded content of a response, if any.
|
805
|
+
|
806
|
+
:param \*\*kwargs: Optional arguments that ``json.loads`` takes.
|
807
|
+
"""
|
808
|
+
|
809
|
+
if not self.encoding and self.content and len(self.content) > 3:
|
810
|
+
# No encoding set. JSON RFC 4627 section 3 states we should expect
|
811
|
+
# UTF-8, -16 or -32. Detect which one to use; If the detection or
|
812
|
+
# decoding fails, fall back to `self.text` (using chardet to make
|
813
|
+
# a best guess).
|
814
|
+
encoding = guess_json_utf(self.content)
|
815
|
+
if encoding is not None:
|
816
|
+
try:
|
817
|
+
return complexjson.loads(
|
818
|
+
self.content.decode(encoding), **kwargs
|
819
|
+
)
|
820
|
+
except UnicodeDecodeError:
|
821
|
+
# Wrong UTF codec detected; usually because it's not UTF-8
|
822
|
+
# but some other 8-bit codec. This is an RFC violation,
|
823
|
+
# and the server didn't bother to tell us what codec *was*
|
824
|
+
# used.
|
825
|
+
pass
|
826
|
+
return complexjson.loads(self.text, **kwargs)
|
827
|
+
|
828
|
+
@property
|
829
|
+
def links(self):
|
830
|
+
"""Returns the parsed header links of the response, if any."""
|
831
|
+
|
832
|
+
header = self.headers.get('link')
|
833
|
+
|
834
|
+
# l = MultiDict()
|
835
|
+
l = {}
|
836
|
+
|
837
|
+
if header:
|
838
|
+
links = parse_header_links(header)
|
839
|
+
|
840
|
+
for link in links:
|
841
|
+
key = link.get('rel') or link.get('url')
|
842
|
+
l[key] = link
|
843
|
+
|
844
|
+
return l
|
845
|
+
|
846
|
+
def raise_for_status(self):
|
847
|
+
"""Raises stored :class:`HTTPError`, if one occurred."""
|
848
|
+
|
849
|
+
http_error_msg = ''
|
850
|
+
if isinstance(self.reason, bytes):
|
851
|
+
reason = self.reason.decode('utf-8', 'ignore')
|
852
|
+
else:
|
853
|
+
reason = self.reason
|
854
|
+
|
855
|
+
if 400 <= self.status_code < 500:
|
856
|
+
http_error_msg = u'%s Client Error: %s for url: %s' % (self.status_code, reason, self.url)
|
857
|
+
|
858
|
+
elif 500 <= self.status_code < 600:
|
859
|
+
http_error_msg = u'%s Server Error: %s for url: %s' % (self.status_code, reason, self.url)
|
860
|
+
|
861
|
+
if http_error_msg:
|
862
|
+
raise HTTPError(http_error_msg, response=self)
|
863
|
+
|
864
|
+
def close(self):
|
865
|
+
"""Releases the connection back to the pool. Once this method has been
|
866
|
+
called the underlying ``raw`` object must not be accessed again.
|
867
|
+
|
868
|
+
*Note: Should not normally need to be called explicitly.*
|
869
|
+
"""
|
870
|
+
if not self._content_consumed:
|
871
|
+
self.raw.close()
|
872
|
+
|
873
|
+
return self.raw.release_conn()
|