Compare commits
469 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a1a6a549a0 | ||
|
|
e253eba5ed | ||
|
|
f6c0619d89 | ||
|
|
33cf965f72 | ||
|
|
5351469472 | ||
|
|
24630743ce | ||
|
|
2ed84f55b2 | ||
|
|
33d448eb21 | ||
|
|
1466ad713c | ||
|
|
f6d43b03fb | ||
|
|
05a1a21593 | ||
|
|
c45a4dfe6b | ||
|
|
2c2138e811 | ||
|
|
c267415882 | ||
|
|
5433656878 | ||
|
|
f79d1ef42f | ||
|
|
4193b95db0 | ||
|
|
06462a6e79 | ||
|
|
913880c45a | ||
|
|
bdc00eb097 | ||
|
|
ef6ceffc1c | ||
|
|
8c211a96cd | ||
|
|
74b7280049 | ||
|
|
083aa67a0d | ||
|
|
f6072f1e14 | ||
|
|
c2b307dbef | ||
|
|
6de4f104cd | ||
|
|
b223291693 | ||
|
|
516f84f490 | ||
|
|
d3e0f73354 | ||
|
|
60ea7f0c2d | ||
|
|
5035827ba4 | ||
|
|
589c454733 | ||
|
|
5855dd711f | ||
|
|
d0359c9460 | ||
|
|
f02a80cbe8 | ||
|
|
d1ca591c0f | ||
|
|
2fddbe3606 | ||
|
|
4b66260cb7 | ||
|
|
9ce669e3ae | ||
|
|
0514dea6fc | ||
|
|
962c8986ca | ||
|
|
28cc1d237b | ||
|
|
78fdf4dd92 | ||
|
|
03957eb1c2 | ||
|
|
320a10d142 | ||
|
|
9cd2d33489 | ||
|
|
2f70990cd3 | ||
|
|
ba543713d3 | ||
|
|
1431502331 | ||
|
|
4840d4a376 | ||
|
|
4f6c018715 | ||
|
|
d09c0e0f24 | ||
|
|
941ac53ba0 | ||
|
|
799a97d360 | ||
|
|
ae6144599a | ||
|
|
333fa8d3f2 | ||
|
|
c3280d7844 | ||
|
|
967a05bfff | ||
|
|
1f7c88880b | ||
|
|
22b5a39098 | ||
|
|
2a7832b5b0 | ||
|
|
48237afd9d | ||
|
|
0b01355870 | ||
|
|
43ed689d97 | ||
|
|
551a0bf0df | ||
|
|
0830062100 | ||
|
|
533c384b87 | ||
|
|
02eb5a2cd3 | ||
|
|
2d39c0db05 | ||
|
|
1b41763472 | ||
|
|
8149e9fe54 | ||
|
|
9cae7be94f | ||
|
|
1ca1c52e69 | ||
|
|
0797c61fd5 | ||
|
|
daa2b297a3 | ||
|
|
7c71982260 | ||
|
|
71a05cf289 | ||
|
|
737dd0c3c6 | ||
|
|
8ac5929ae1 | ||
|
|
2b3436e0e7 | ||
|
|
fa2dbe9a91 | ||
|
|
9ed5db8ed2 | ||
|
|
427e8eb1e7 | ||
|
|
251f73f65d | ||
|
|
db47b9b4a0 | ||
|
|
bfb93d4b7d | ||
|
|
9ea85109a5 | ||
|
|
c577eb8d5f | ||
|
|
bebf5250b0 | ||
|
|
2758124a13 | ||
|
|
4fc7f4a255 | ||
|
|
65989ddfe9 | ||
|
|
0a760ff025 | ||
|
|
ca6f9af5db | ||
|
|
b7c6aba848 | ||
|
|
fd13816d01 | ||
|
|
24bcb9eab6 | ||
|
|
b15056d1d3 | ||
|
|
80011a7917 | ||
|
|
c46f55bd48 | ||
|
|
e11302018b | ||
|
|
23f6faa7cd | ||
|
|
ae0a497b0c | ||
|
|
b1631b03bc | ||
|
|
a9906536ee | ||
|
|
d5c4cac0f4 | ||
|
|
7b565d886c | ||
|
|
7138d8b0e3 | ||
|
|
9b95b4e7b4 | ||
|
|
d2f65af033 | ||
|
|
a9ee0eef5a | ||
|
|
782e94d141 | ||
|
|
ad18d14573 | ||
|
|
f462eecf48 | ||
|
|
eedd674628 | ||
|
|
4a540ff5f1 | ||
|
|
d2590ee46c | ||
|
|
4cd95aa496 | ||
|
|
56fd46f9bf | ||
|
|
2ff8106d62 | ||
|
|
fab1fd10d0 | ||
|
|
74b72ce426 | ||
|
|
6e05165a29 | ||
|
|
0178903841 | ||
|
|
0d180a5cbb | ||
|
|
8345819b70 | ||
|
|
5f824fb019 | ||
|
|
1311c96eae | ||
|
|
c4c60864f8 | ||
|
|
e8a9bd7415 | ||
|
|
729fd3cf42 | ||
|
|
1d3787a0ea | ||
|
|
0357b0724b | ||
|
|
189fea7a11 | ||
|
|
a5f4f3c9a3 | ||
|
|
e08981ee46 | ||
|
|
afb508f6a7 | ||
|
|
09fd857eb1 | ||
|
|
1462917951 | ||
|
|
2962c236c9 | ||
|
|
9d4fd3c968 | ||
|
|
12640ec242 | ||
|
|
5cb55a84a7 | ||
|
|
2cb3abea55 | ||
|
|
38d9a4f65f | ||
|
|
fbc5ed552e | ||
|
|
5099688bfc | ||
|
|
4cd65385f8 | ||
|
|
87f9a58d45 | ||
|
|
9369b5a37a | ||
|
|
23fe729356 | ||
|
|
1a7d1406cb | ||
|
|
92b88fcffb | ||
|
|
ac851d8ac3 | ||
|
|
a025522d08 | ||
|
|
a3735e2517 | ||
|
|
06826504da | ||
|
|
14c323492a | ||
|
|
c196511934 | ||
|
|
a9860c4fae | ||
|
|
f82382588f | ||
|
|
72176ab9ac | ||
|
|
eb2c14889f | ||
|
|
cfdd00f3a3 | ||
|
|
b15bccf35e | ||
|
|
f348d51818 | ||
|
|
dc1526f85d | ||
|
|
c21c039ec8 | ||
|
|
49acab8033 | ||
|
|
0f71067f64 | ||
|
|
9f35ebd795 | ||
|
|
de1c200dff | ||
|
|
458496d43e | ||
|
|
446911b853 | ||
|
|
3ed0f8fba0 | ||
|
|
d66ffdbb2b | ||
|
|
99197c2058 | ||
|
|
179f943300 | ||
|
|
75f062dcef | ||
|
|
a7944ba94f | ||
|
|
cf77263ad4 | ||
|
|
af85e68f1f | ||
|
|
536b583bc9 | ||
|
|
0f1251bc13 | ||
|
|
a29be8f9cc | ||
|
|
ac9f0d7c97 | ||
|
|
be2fe0c6af | ||
|
|
abe22b1da6 | ||
|
|
e11caeb39f | ||
|
|
30a16088c4 | ||
|
|
6831d2d8e4 | ||
|
|
a5bcc9c46e | ||
|
|
186dcee8a0 | ||
|
|
caf91bd175 | ||
|
|
80562c9f83 | ||
|
|
2256fd2bc4 | ||
|
|
316f748226 | ||
|
|
c6ab21c103 | ||
|
|
1d41e8dc97 | ||
|
|
80c7cbd46e | ||
|
|
775813aae7 | ||
|
|
cbccc5f07e | ||
|
|
26466b54ad | ||
|
|
042ccfcf99 | ||
|
|
24e46d0303 | ||
|
|
70cc902f5e | ||
|
|
091604455a | ||
|
|
b639f17705 | ||
|
|
33f41b8a13 | ||
|
|
73a65941ad | ||
|
|
2e992817d4 | ||
|
|
0f9bcfb86c | ||
|
|
fcde69193a | ||
|
|
b08073a7c3 | ||
|
|
e1eb569751 | ||
|
|
8d09a80a16 | ||
|
|
8074cc8bf5 | ||
|
|
8e19074296 | ||
|
|
30c128ade9 | ||
|
|
65a73bd0f7 | ||
|
|
e63d846b15 | ||
|
|
d6db3901cb | ||
|
|
355e288940 | ||
|
|
a08c421f7c | ||
|
|
e35ace77bf | ||
|
|
f3b62442be | ||
|
|
846c37c29d | ||
|
|
570dc15b52 | ||
|
|
4a87d1e62f | ||
|
|
2d3b68cf1e | ||
|
|
31a6e696bb | ||
|
|
33e402b21f | ||
|
|
60cffb076b | ||
|
|
bdc92c795f | ||
|
|
426a1c0120 | ||
|
|
bc8fa9c246 | ||
|
|
be7cbe1353 | ||
|
|
9ba6c5e638 | ||
|
|
762042260b | ||
|
|
2abe57458d | ||
|
|
e40a3d6094 | ||
|
|
c2479aeac7 | ||
|
|
7ce4691289 | ||
|
|
c5d9e1216e | ||
|
|
863542529d | ||
|
|
8072d4fda8 | ||
|
|
e820ac7c40 | ||
|
|
720f1ce61d | ||
|
|
6d37433c0e | ||
|
|
969783702d | ||
|
|
6fbbbc8c9e | ||
|
|
26b104ecb9 | ||
|
|
3f21a2d62e | ||
|
|
42926b5731 | ||
|
|
a7e2da804c | ||
|
|
2416c2dd47 | ||
|
|
b44d6fdf49 | ||
|
|
0859c01b16 | ||
|
|
c198cc0b2e | ||
|
|
4b9e5d0ef3 | ||
|
|
9b51d7c4f2 | ||
|
|
6b89c8752a | ||
|
|
59dac47346 | ||
|
|
bb2ae009bc | ||
|
|
11982c1f9f | ||
|
|
36cc7bbfc3 | ||
|
|
d675d83b1d | ||
|
|
4d2875da11 | ||
|
|
687ff0eb36 | ||
|
|
c51a9efa2b | ||
|
|
c386eebcf8 | ||
|
|
3423b51748 | ||
|
|
3ff2995c1d | ||
|
|
e231de6ddc | ||
|
|
54cefc901c | ||
|
|
2bc6aeb64e | ||
|
|
7c71cb9643 | ||
|
|
e0359b2725 | ||
|
|
25d1ffda8c | ||
|
|
537ac3cf22 | ||
|
|
5477208835 | ||
|
|
0b2517465d | ||
|
|
1c19e6148f | ||
|
|
55d3d8b3b2 | ||
|
|
5f3b95992b | ||
|
|
3e012c16c3 | ||
|
|
c13ccd11f6 | ||
|
|
266d17c4de | ||
|
|
6b639bbc08 | ||
|
|
6c322457a2 | ||
|
|
5090ba79ac | ||
|
|
da13fec6ce | ||
|
|
d7018e6d61 | ||
|
|
39b3dcf7d9 | ||
|
|
3d968ff34d | ||
|
|
b6b90f4d9b | ||
|
|
913adced21 | ||
|
|
e320f9e467 | ||
|
|
4070bcf1b9 | ||
|
|
3c01cd7080 | ||
|
|
bc81ee3af4 | ||
|
|
b1d584e899 | ||
|
|
b98be047f2 | ||
|
|
ced3779126 | ||
|
|
bedb1cd38f | ||
|
|
d258b20eba | ||
|
|
e2fce5e60c | ||
|
|
72ca1b7e31 | ||
|
|
7f3ce7eaac | ||
|
|
b248328eb3 | ||
|
|
10e5f874c7 | ||
|
|
7f2513fb81 | ||
|
|
04b5c83701 | ||
|
|
1f9ec06e22 | ||
|
|
00fa902c7d | ||
|
|
3393232304 | ||
|
|
d41fba6347 | ||
|
|
7ca0e86a67 | ||
|
|
428f7a2759 | ||
|
|
a71e2240df | ||
|
|
4bce5a0bc5 | ||
|
|
3e7d0a873f | ||
|
|
df918c066f | ||
|
|
ada50499a0 | ||
|
|
82c744b59c | ||
|
|
bbc3d43522 | ||
|
|
8086ffdbbf | ||
|
|
5eb7337494 | ||
|
|
48e1a3359e | ||
|
|
1b450d2038 | ||
|
|
67a7b2e833 | ||
|
|
42c5a4f622 | ||
|
|
11ed88bcb2 | ||
|
|
0fe6653eab | ||
|
|
dd15e52840 | ||
|
|
9bc49b5960 | ||
|
|
d79024f246 | ||
|
|
9cdf294107 | ||
|
|
9f55e4bc09 | ||
|
|
bf582192b8 | ||
|
|
408e576d33 | ||
|
|
7d57e8ec55 | ||
|
|
e8ff4897fe | ||
|
|
a4c18cd733 | ||
|
|
07005b0ffc | ||
|
|
989f702742 | ||
|
|
a0d58026e0 | ||
|
|
3922dcf2a1 | ||
|
|
589a822567 | ||
|
|
e8c9acc8a2 | ||
|
|
9a2e5df000 | ||
|
|
c79d61b953 | ||
|
|
f9ac75cab1 | ||
|
|
ebd3e36ad5 | ||
|
|
50daf9c005 | ||
|
|
fb7efcf3f1 | ||
|
|
5f576ad22f | ||
|
|
0b6c110a5c | ||
|
|
2da7fe0858 | ||
|
|
c8d8b4b513 | ||
|
|
45c2e679e0 | ||
|
|
27b24f974f | ||
|
|
6296df90b9 | ||
|
|
4983a9bde3 | ||
|
|
2e4329d153 | ||
|
|
47cb8bae1a | ||
|
|
d889b98eae | ||
|
|
dc75b3ca0b | ||
|
|
0becdca7e3 | ||
|
|
6f81e78dfe | ||
|
|
9c3c755abe | ||
|
|
d88240ba44 | ||
|
|
6d2a5072ca | ||
|
|
96ff7ca31f | ||
|
|
2e633471f1 | ||
|
|
67a0e90b6b | ||
|
|
4a59cd0950 | ||
|
|
be295ba4d4 | ||
|
|
d36f391957 | ||
|
|
a79a63390b | ||
|
|
86760daf23 | ||
|
|
8e26bfd86d | ||
|
|
aeda65bbe5 | ||
|
|
68e581f1b5 | ||
|
|
a91905d78e | ||
|
|
44256ffe7c | ||
|
|
4803716715 | ||
|
|
bd10047244 | ||
|
|
d91fe00983 | ||
|
|
b18f765774 | ||
|
|
b5b8c038a7 | ||
|
|
a694ab5c00 | ||
|
|
e52932c427 | ||
|
|
1f9425ca53 | ||
|
|
b4f76878fe | ||
|
|
a310b5ab34 | ||
|
|
e73a6c52d2 | ||
|
|
e3c3c0a8fe | ||
|
|
faafb5a043 | ||
|
|
663aa1162b | ||
|
|
d22d219d34 | ||
|
|
74289f420c | ||
|
|
749419ad0c | ||
|
|
7f438416e4 | ||
|
|
5d06354734 | ||
|
|
2d120e32db | ||
|
|
69856f3052 | ||
|
|
37011aaa3f | ||
|
|
8b773a4fed | ||
|
|
c19c394ac1 | ||
|
|
9742da7f91 | ||
|
|
76a89c3c9b | ||
|
|
6f6d0164a9 | ||
|
|
aa21dbe7fc | ||
|
|
a7969c5c42 | ||
|
|
a345b776fb | ||
|
|
63e7748fe5 | ||
|
|
f2409648ac | ||
|
|
7d7d9ebacf | ||
|
|
248211453d | ||
|
|
fd926e74c3 | ||
|
|
177f4dd2a4 | ||
|
|
fbe48fbb7c | ||
|
|
5add08fc84 | ||
|
|
19cff44ec1 | ||
|
|
9e27326d68 | ||
|
|
f507a3ef12 | ||
|
|
c9309e4c59 | ||
|
|
827bbe2a7e | ||
|
|
64bde6582d | ||
|
|
334be4d272 | ||
|
|
67a9ed47ae | ||
|
|
28208392cd | ||
|
|
5734f4fc4a | ||
|
|
4c320ac3a2 | ||
|
|
b49547f135 | ||
|
|
f1e48f4d0d | ||
|
|
f37daf2500 | ||
|
|
6dd410ff17 | ||
|
|
2aab9a9a39 | ||
|
|
ad9400ecfe | ||
|
|
5c1f72e80a | ||
|
|
c4d76800e8 | ||
|
|
c452e3b92d | ||
|
|
5a1e738ea9 | ||
|
|
8761e9736f | ||
|
|
abe950cfd3 | ||
|
|
c35f34263a | ||
|
|
0dd4752598 | ||
|
|
57d7284c1a | ||
|
|
fc9dfac2b9 | ||
|
|
bc3eddc6ed | ||
|
|
d911f27868 | ||
|
|
3da2f10290 | ||
|
|
5e0ebc9b9f | ||
|
|
75e2dd3094 | ||
|
|
9533df1f0b | ||
|
|
ce52825d12 | ||
|
|
398d1105b4 | ||
|
|
c15d2b6949 | ||
|
|
7d4fc04a6f | ||
|
|
086655e4fc | ||
|
|
779fd6e7f3 | ||
|
|
af63554106 | ||
|
|
bedd9284c9 | ||
|
|
e4974c7ff5 | ||
|
|
36412c5ae7 | ||
|
|
a7aa86a933 |
6
.github/CODE_OF_CONDUCT.md
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
# Treat each other well
|
||||
|
||||
Everyone participating in the _requests_ project, and in particular in the issue tracker,
|
||||
pull requests, and social media activity, is expected to treat other people with respect
|
||||
and more generally to follow the guidelines articulated in the
|
||||
[Python Community Code of Conduct](https://www.python.org/psf/codeofconduct/).
|
||||
7
CONTRIBUTING.md → .github/CONTRIBUTING.md
vendored
@@ -1,10 +1,7 @@
|
||||
# Contribution Guidelines
|
||||
|
||||
Before opening any issues or proposing any pull requests, please do the
|
||||
following:
|
||||
|
||||
1. Read our [Contributor's Guide](http://docs.python-requests.org/en/latest/dev/contributing/).
|
||||
2. Understand our [development philosophy](http://docs.python-requests.org/en/latest/dev/philosophy/).
|
||||
Before opening any issues or proposing any pull requests, please read
|
||||
our [Contributor's Guide](https://requests.readthedocs.io/en/latest/dev/contributing/).
|
||||
|
||||
To get the greatest chance of helpful responses, please also observe the
|
||||
following additional notes.
|
||||
1
.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1 @@
|
||||
custom: ['https://www.python.org/psf/sponsorship/']
|
||||
93
.github/SECURITY.md
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
# Vulnerability Disclosure
|
||||
|
||||
If you think you have found a potential security vulnerability in
|
||||
requests, please email [Nate](mailto:nate.prewitt@gmail.com)
|
||||
and [Seth](mailto:sethmichaellarson@gmail.com) directly.
|
||||
**Do not file a public issue.**
|
||||
|
||||
Our PGP Key fingerprints are:
|
||||
|
||||
- 8722 7E29 AD9C FF5C FAC3 EA6A 44D3 FF97 B80D C864 ([@nateprewitt](https://keybase.io/nateprewitt))
|
||||
|
||||
- EDD5 6765 A9D8 4653 CBC8 A134 51B0 6736 1740 F5FC ([@sethmlarson](https://keybase.io/sethmlarson))
|
||||
|
||||
You can also contact us on [Keybase](https://keybase.io) with the
|
||||
profiles above if desired.
|
||||
|
||||
If English is not your first language, please try to describe the
|
||||
problem and its impact to the best of your ability. For greater detail,
|
||||
please use your native language and we will try our best to translate it
|
||||
using online services.
|
||||
|
||||
Please also include the code you used to find the problem and the
|
||||
shortest amount of code necessary to reproduce it.
|
||||
|
||||
Please do not disclose this to anyone else. We will retrieve a CVE
|
||||
identifier if necessary and give you full credit under whatever name or
|
||||
alias you provide. We will only request an identifier when we have a fix
|
||||
and can publish it in a release.
|
||||
|
||||
We will respect your privacy and will only publicize your involvement if
|
||||
you grant us permission.
|
||||
|
||||
## Process
|
||||
|
||||
This following information discusses the process the requests project
|
||||
follows in response to vulnerability disclosures. If you are disclosing
|
||||
a vulnerability, this section of the documentation lets you know how we
|
||||
will respond to your disclosure.
|
||||
|
||||
### Timeline
|
||||
|
||||
When you report an issue, one of the project members will respond to you
|
||||
within two days *at the outside*. In most cases responses will be
|
||||
faster, usually within 12 hours. This initial response will at the very
|
||||
least confirm receipt of the report.
|
||||
|
||||
If we were able to rapidly reproduce the issue, the initial response
|
||||
will also contain confirmation of the issue. If we are not, we will
|
||||
often ask for more information about the reproduction scenario.
|
||||
|
||||
Our goal is to have a fix for any vulnerability released within two
|
||||
weeks of the initial disclosure. This may potentially involve shipping
|
||||
an interim release that simply disables function while a more mature fix
|
||||
can be prepared, but will in the vast majority of cases mean shipping a
|
||||
complete release as soon as possible.
|
||||
|
||||
Throughout the fix process we will keep you up to speed with how the fix
|
||||
is progressing. Once the fix is prepared, we will notify you that we
|
||||
believe we have a fix. Often we will ask you to confirm the fix resolves
|
||||
the problem in your environment, especially if we are not confident of
|
||||
our reproduction scenario.
|
||||
|
||||
At this point, we will prepare for the release. We will obtain a CVE
|
||||
number if one is required, providing you with full credit for the
|
||||
discovery. We will also decide on a planned release date, and let you
|
||||
know when it is. This release date will *always* be on a weekday.
|
||||
|
||||
At this point we will reach out to our major downstream packagers to
|
||||
notify them of an impending security-related patch so they can make
|
||||
arrangements. In addition, these packagers will be provided with the
|
||||
intended patch ahead of time, to ensure that they are able to promptly
|
||||
release their downstream packages. Currently the list of people we
|
||||
actively contact *ahead of a public release* is:
|
||||
|
||||
- Jeremy Cline, Red Hat (@jeremycline)
|
||||
- Daniele Tricoli, Debian (@eriol)
|
||||
|
||||
We will notify these individuals at least a week ahead of our planned
|
||||
release date to ensure that they have sufficient time to prepare. If you
|
||||
believe you should be on this list, please let one of the maintainers
|
||||
know at one of the email addresses at the top of this article.
|
||||
|
||||
On release day, we will push the patch to our public repository, along
|
||||
with an updated changelog that describes the issue and credits you. We
|
||||
will then issue a PyPI release containing the patch.
|
||||
|
||||
At this point, we will publicise the release. This will involve mails to
|
||||
mailing lists, Tweets, and all other communication mechanisms available
|
||||
to the core team.
|
||||
|
||||
We will also explicitly mention which commits contain the fix to make it
|
||||
easier for other distributors and users to easily patch their own
|
||||
versions of requests if upgrading is not an option.
|
||||
66
.github/workflows/codeql-analysis.yml
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
# For most projects, this workflow file will not need changing; you simply need
|
||||
# to commit it to your repository.
|
||||
#
|
||||
# You may wish to alter this file to override the set of languages analyzed,
|
||||
# or to provide custom queries or build logic.
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [master]
|
||||
schedule:
|
||||
- cron: '0 23 * * 0'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
# We must fetch at least the immediate parents so that if this is
|
||||
# a pull request then we can checkout the head.
|
||||
fetch-depth: 2
|
||||
|
||||
# If this run was triggered by a pull request event, then checkout
|
||||
# the head of the pull request instead of the merge commit.
|
||||
- run: git checkout HEAD^2
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v1
|
||||
with:
|
||||
languages: "python"
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v1
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
|
||||
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
||||
# and modify them (or add more) to build your code if your project
|
||||
# uses a compiled language
|
||||
|
||||
#- run: |
|
||||
# make bootstrap
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v1
|
||||
31
.github/workflows/run-tests.yml
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
name: Tests
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
python-version: [2.7, 3.6, 3.7, 3.8, 3.9]
|
||||
os: [ubuntu-18.04, macOS-latest, windows-latest]
|
||||
include:
|
||||
# pypy3 on Mac OS currently fails trying to compile
|
||||
# brotlipy. Moving pypy3 to only test linux.
|
||||
- python-version: pypy3
|
||||
os: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
make
|
||||
- name: Run tests
|
||||
run: |
|
||||
make ci
|
||||
12
.gitignore
vendored
@@ -14,9 +14,21 @@ requests.egg-info/
|
||||
*.swp
|
||||
*.egg
|
||||
env/
|
||||
.venv/
|
||||
.eggs/
|
||||
.tox/
|
||||
.pytest_cache/
|
||||
.vscode/
|
||||
.eggs/
|
||||
|
||||
.workon
|
||||
|
||||
# in case you work with IntelliJ/PyCharm
|
||||
.idea
|
||||
*.iml
|
||||
.python-version
|
||||
|
||||
|
||||
t.py
|
||||
|
||||
t2.py
|
||||
|
||||
42
.travis.yml
@@ -1,42 +0,0 @@
|
||||
sudo: false
|
||||
language: python
|
||||
# command to install dependencies
|
||||
install: "make"
|
||||
# command to run tests
|
||||
script:
|
||||
- |
|
||||
if [[ "$TRAVIS_PYTHON_VERSION" != "2.6" ]] ; then make test-readme; fi
|
||||
- make ci
|
||||
cache: pip
|
||||
jobs:
|
||||
include:
|
||||
- stage: test
|
||||
script:
|
||||
- make test-readme
|
||||
- make ci
|
||||
python: '2.7'
|
||||
- stage: test
|
||||
script:
|
||||
- make test-readme
|
||||
- make ci
|
||||
python: '3.4'
|
||||
- stage: test
|
||||
script:
|
||||
- make test-readme
|
||||
- make ci
|
||||
python: '3.5'
|
||||
- stage: test
|
||||
script:
|
||||
- make test-readme
|
||||
- make ci
|
||||
python: '3.6'
|
||||
- stage: test
|
||||
script:
|
||||
- make test-readme
|
||||
- make ci
|
||||
python: '3.7'
|
||||
dist: xenial
|
||||
sudo: true
|
||||
- stage: coverage
|
||||
python: 3.6
|
||||
script: codecov
|
||||
14
AUTHORS.rst
@@ -1,17 +1,16 @@
|
||||
Requests is written and maintained by Kenneth Reitz and
|
||||
various contributors:
|
||||
Requests was lovingly created by Kenneth Reitz.
|
||||
|
||||
Keepers of the Crystals
|
||||
```````````````````````
|
||||
|
||||
- Kenneth Reitz <me@kennethreitz.org> `@kennethreitz <https://github.com/kennethreitz>`_, Keeper of the Master Crystal.
|
||||
- Ian Cordasco <graffatcolmingov@gmail.com> `@sigmavirus24 <https://github.com/sigmavirus24>`_.
|
||||
- Nate Prewitt <nate.prewitt@gmail.com> `@nateprewitt <https://github.com/nateprewitt>`_.
|
||||
- Nate Prewitt `@nateprewitt <https://github.com/nateprewitt>`_.
|
||||
- Seth M. Larson `@sethmlarson <https://github.com/sethmlarson>`_.
|
||||
|
||||
Previous Keepers of Crystals
|
||||
````````````````````````````
|
||||
|
||||
- Kenneth Reitz <me@kennethreitz.org> `@ken-reitz <https://github.com/ken-reitz>`_, reluctant Keeper of the Master Crystal.
|
||||
- Cory Benfield <cory@lukasa.co.uk> `@lukasa <https://github.com/lukasa>`_
|
||||
- Ian Cordasco <graffatcolmingov@gmail.com> `@sigmavirus24 <https://github.com/sigmavirus24>`_.
|
||||
|
||||
|
||||
Patches and Suggestions
|
||||
@@ -189,3 +188,6 @@ Patches and Suggestions
|
||||
- Darren Dormer (`@ddormer <https://github.com/ddormer>`_)
|
||||
- Rajiv Mayani (`@mayani <https://github.com/mayani>`_)
|
||||
- Antti Kaihola (`@akaihola <https://github.com/akaihola>`_)
|
||||
- "Dull Bananas" <dull.bananas0@gmail.com> (`@dullbananas <https://github.com/dullbananas>`_)
|
||||
- Alessio Izzo (`@aless10 <https://github.com/aless10>`_)
|
||||
- Sylvain Marié (`@smarie <https://github.com/smarie>`_)
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
Be cordial or be on your way.
|
||||
|
||||
https://www.kennethreitz.org/essays/be-cordial-or-be-on-your-way
|
||||
146
HISTORY.md
@@ -4,9 +4,130 @@ Release History
|
||||
dev
|
||||
---
|
||||
|
||||
- \[Short description of non-trivial change.\]
|
||||
|
||||
2.26.0 (2021-07-13)
|
||||
-------------------
|
||||
|
||||
**Improvements**
|
||||
|
||||
- Requests now supports Brotli compression, if either the `brotli` or
|
||||
`brotlicffi` package is installed. (#5783)
|
||||
|
||||
- `Session.send` now correctly resolves proxy configurations from both
|
||||
the Session and Request. Behavior now matches `Session.request`. (#5681)
|
||||
|
||||
**Bugfixes**
|
||||
|
||||
- \[Short description of non-trivial change.\]
|
||||
- Fixed a race condition in zip extraction when using Requests in parallel
|
||||
from zip archive. (#5707)
|
||||
|
||||
**Dependencies**
|
||||
|
||||
- Instead of `chardet`, use the MIT-licensed `charset_normalizer` for Python3
|
||||
to remove license ambiguity for projects bundling requests. If `chardet`
|
||||
is already installed on your machine it will be used instead of `charset_normalizer`
|
||||
to keep backwards compatibility. (#5797)
|
||||
|
||||
You can also install `chardet` while installing requests by
|
||||
specifying `[use_chardet_on_py3]` extra as follows:
|
||||
|
||||
```shell
|
||||
pip install "requests[use_chardet_on_py3]"
|
||||
```
|
||||
|
||||
Python2 still depends upon the `chardet` module.
|
||||
|
||||
- Requests now supports `idna` 3.x on Python 3. `idna` 2.x will continue to
|
||||
be used on Python 2 installations. (#5711)
|
||||
|
||||
**Deprecations**
|
||||
|
||||
- The `requests[security]` extra has been converted to a no-op install.
|
||||
PyOpenSSL is no longer the recommended secure option for Requests. (#5867)
|
||||
|
||||
- Requests has officially dropped support for Python 3.5. (#5867)
|
||||
|
||||
2.25.1 (2020-12-16)
|
||||
-------------------
|
||||
|
||||
**Bugfixes**
|
||||
|
||||
- Requests now treats `application/json` as `utf8` by default. Resolving
|
||||
inconsistencies between `r.text` and `r.json` output. (#5673)
|
||||
|
||||
**Dependencies**
|
||||
|
||||
- Requests now supports chardet v4.x.
|
||||
|
||||
2.25.0 (2020-11-11)
|
||||
------------------
|
||||
|
||||
**Improvements**
|
||||
|
||||
- Added support for NETRC environment variable. (#5643)
|
||||
|
||||
**Dependencies**
|
||||
|
||||
- Requests now supports urllib3 v1.26.
|
||||
|
||||
**Deprecations**
|
||||
|
||||
- Requests v2.25.x will be the last release series with support for Python 3.5.
|
||||
- The `requests[security]` extra is officially deprecated and will be removed
|
||||
in Requests v2.26.0.
|
||||
|
||||
2.24.0 (2020-06-17)
|
||||
-------------------
|
||||
|
||||
**Improvements**
|
||||
|
||||
- pyOpenSSL TLS implementation is now only used if Python
|
||||
either doesn't have an `ssl` module or doesn't support
|
||||
SNI. Previously pyOpenSSL was unconditionally used if available.
|
||||
This applies even if pyOpenSSL is installed via the
|
||||
`requests[security]` extra (#5443)
|
||||
|
||||
- Redirect resolution should now only occur when
|
||||
`allow_redirects` is True. (#5492)
|
||||
|
||||
- No longer perform unnecessary Content-Length calculation for
|
||||
requests that won't use it. (#5496)
|
||||
|
||||
2.23.0 (2020-02-19)
|
||||
-------------------
|
||||
|
||||
**Improvements**
|
||||
|
||||
- Remove defunct reference to `prefetch` in Session `__attrs__` (#5110)
|
||||
|
||||
**Bugfixes**
|
||||
|
||||
- Requests no longer outputs password in basic auth usage warning. (#5099)
|
||||
|
||||
**Dependencies**
|
||||
|
||||
- Pinning for `chardet` and `idna` now uses major version instead of minor.
|
||||
This hopefully reduces the need for releases everytime a dependency is updated.
|
||||
|
||||
2.22.0 (2019-05-15)
|
||||
-------------------
|
||||
|
||||
**Dependencies**
|
||||
|
||||
- Requests now supports urllib3 v1.25.2.
|
||||
(note: 1.25.0 and 1.25.1 are incompatible)
|
||||
|
||||
**Deprecations**
|
||||
|
||||
- Requests has officially stopped support for Python 3.4.
|
||||
|
||||
2.21.0 (2018-12-10)
|
||||
-------------------
|
||||
|
||||
**Dependencies**
|
||||
|
||||
- Requests now supports idna v2.8.
|
||||
|
||||
2.20.1 (2018-11-08)
|
||||
-------------------
|
||||
@@ -530,7 +651,7 @@ Or, even better:
|
||||
|
||||
**Bugfixes**
|
||||
|
||||
- For file-like objects that are not seeked to the very beginning, we
|
||||
- For file-like objects that are not sought to the very beginning, we
|
||||
now send the content length for the number of bytes we will actually
|
||||
read, rather than the total size of the file, allowing partial file
|
||||
uploads.
|
||||
@@ -610,7 +731,7 @@ Or, even better:
|
||||
|
||||
This is the first release that follows our new release process. For
|
||||
more, see [our
|
||||
documentation](http://docs.python-requests.org/en/latest/community/release-process/).
|
||||
documentation](https://requests.readthedocs.io/en/latest/community/release-process/).
|
||||
|
||||
**Bugfixes**
|
||||
|
||||
@@ -774,7 +895,7 @@ documentation](http://docs.python-requests.org/en/latest/community/release-proce
|
||||
- Unicode URL improvements for Python 2.
|
||||
- Re-order JSON param for backwards compat.
|
||||
- Automatically defrag authentication schemes from host/pass URIs.
|
||||
([\#2249](https://github.com/requests/requests/issues/2249))
|
||||
([\#2249](https://github.com/psf/requests/issues/2249))
|
||||
|
||||
2.4.2 (2014-10-05)
|
||||
------------------
|
||||
@@ -782,26 +903,26 @@ documentation](http://docs.python-requests.org/en/latest/community/release-proce
|
||||
**Improvements**
|
||||
|
||||
- FINALLY! Add json parameter for uploads!
|
||||
([\#2258](https://github.com/requests/requests/pull/2258))
|
||||
([\#2258](https://github.com/psf/requests/pull/2258))
|
||||
- Support for bytestring URLs on Python 3.x
|
||||
([\#2238](https://github.com/requests/requests/pull/2238))
|
||||
([\#2238](https://github.com/psf/requests/pull/2238))
|
||||
|
||||
**Bugfixes**
|
||||
|
||||
- Avoid getting stuck in a loop
|
||||
([\#2244](https://github.com/requests/requests/pull/2244))
|
||||
([\#2244](https://github.com/psf/requests/pull/2244))
|
||||
- Multiple calls to iter\* fail with unhelpful error.
|
||||
([\#2240](https://github.com/requests/requests/issues/2240),
|
||||
[\#2241](https://github.com/requests/requests/issues/2241))
|
||||
([\#2240](https://github.com/psf/requests/issues/2240),
|
||||
[\#2241](https://github.com/psf/requests/issues/2241))
|
||||
|
||||
**Documentation**
|
||||
|
||||
- Correct redirection introduction
|
||||
([\#2245](https://github.com/requests/requests/pull/2245/))
|
||||
([\#2245](https://github.com/psf/requests/pull/2245/))
|
||||
- Added example of how to send multiple files in one request.
|
||||
([\#2227](https://github.com/requests/requests/pull/2227/))
|
||||
([\#2227](https://github.com/psf/requests/pull/2227/))
|
||||
- Clarify how to pass a custom set of CAs
|
||||
([\#2248](https://github.com/requests/requests/pull/2248/))
|
||||
([\#2248](https://github.com/psf/requests/pull/2248/))
|
||||
|
||||
2.4.1 (2014-09-09)
|
||||
------------------
|
||||
@@ -1628,4 +1749,3 @@ This is not a backwards compatible change.
|
||||
|
||||
- Frustration
|
||||
- Conception
|
||||
|
||||
|
||||
182
LICENSE
@@ -1,13 +1,175 @@
|
||||
Copyright 2018 Kenneth Reitz
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
include README.md LICENSE NOTICE HISTORY.md pytest.ini requirements.txt Pipfile Pipfile.lock
|
||||
include README.md LICENSE NOTICE HISTORY.md pytest.ini requirements-dev.txt
|
||||
recursive-include tests *.py
|
||||
|
||||
14
Makefile
@@ -1,21 +1,21 @@
|
||||
.PHONY: docs
|
||||
init:
|
||||
pip install pipenv --upgrade
|
||||
pipenv install --dev --skip-lock
|
||||
pip install -e .[socks]
|
||||
pip install -r requirements-dev.txt
|
||||
test:
|
||||
# This runs all of the tests, on both Python 2 and Python 3.
|
||||
detox
|
||||
ci:
|
||||
pipenv run py.test -n 8 --boxed --junitxml=report.xml
|
||||
pytest tests --junitxml=report.xml
|
||||
|
||||
test-readme:
|
||||
@pipenv run python setup.py check --restructuredtext --strict && ([ $$? -eq 0 ] && echo "README.rst and HISTORY.rst ok") || echo "Invalid markup in README.rst or HISTORY.rst!"
|
||||
python setup.py check --restructuredtext --strict && ([ $$? -eq 0 ] && echo "README.rst and HISTORY.rst ok") || echo "Invalid markup in README.rst or HISTORY.rst!"
|
||||
|
||||
flake8:
|
||||
pipenv run flake8 --ignore=E501,F401,E128,E402,E731,F821 requests
|
||||
flake8 --ignore=E501,F401,E128,E402,E731,F821 requests
|
||||
|
||||
coverage:
|
||||
pipenv run py.test --cov-config .coveragerc --verbose --cov-report term --cov-report xml --cov=requests tests
|
||||
pytest --cov-config .coveragerc --verbose --cov-report term --cov-report xml --cov=requests tests
|
||||
|
||||
publish:
|
||||
pip install 'twine>=1.5.0'
|
||||
@@ -25,4 +25,4 @@ publish:
|
||||
|
||||
docs:
|
||||
cd docs && make html
|
||||
@echo "\033[95m\n\nBuild successful! View the docs homepage at docs/_build/html/index.html.\n\033[0m"
|
||||
@echo "\033[95m\n\nBuild successful! View the docs homepage at docs/_build/html/index.html.\n\033[0m"
|
||||
|
||||
24
Pipfile
@@ -1,24 +0,0 @@
|
||||
[[source]]
|
||||
url = "https://pypi.org/simple/"
|
||||
verify_ssl = true
|
||||
name = "pypi"
|
||||
|
||||
[dev-packages]
|
||||
pytest = ">=2.8.0"
|
||||
codecov = "*"
|
||||
pytest-httpbin = ">=0.0.7"
|
||||
pytest-mock = "*"
|
||||
pytest-cov = "*"
|
||||
pytest-xdist = "*"
|
||||
alabaster = "*"
|
||||
readme-renderer = "*"
|
||||
sphinx = "<=1.5.5"
|
||||
pysocks = "*"
|
||||
docutils = "*"
|
||||
"flake8" = "*"
|
||||
tox = "*"
|
||||
detox = "*"
|
||||
httpbin = ">=0.7.0"
|
||||
|
||||
[packages]
|
||||
"e1839a8" = {path = ".", editable = true, extras = ["socks"]}
|
||||
641
Pipfile.lock
generated
@@ -1,641 +0,0 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "0735b243455d8e924fbd05188ed435bfd3917f4acdade9b9e8f14741f3fc47e9"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {},
|
||||
"sources": [
|
||||
{
|
||||
"name": "pypi",
|
||||
"url": "https://pypi.org/simple/",
|
||||
"verify_ssl": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"default": {
|
||||
"certifi": {
|
||||
"hashes": [
|
||||
"sha256:13e698f54293db9f89122b0581843a782ad0934a4fe0172d2a980ba77fc61bb7",
|
||||
"sha256:9fa520c1bacfb634fa7af20a76bcbd3d5fb390481724c597da32c719a7dca4b0"
|
||||
],
|
||||
"version": "==2018.4.16"
|
||||
},
|
||||
"chardet": {
|
||||
"hashes": [
|
||||
"sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae",
|
||||
"sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"
|
||||
],
|
||||
"version": "==3.0.4"
|
||||
},
|
||||
"e1839a8": {
|
||||
"editable": true,
|
||||
"extras": [
|
||||
"socks"
|
||||
],
|
||||
"path": "."
|
||||
},
|
||||
"idna": {
|
||||
"hashes": [
|
||||
"sha256:2c6a5de3089009e3da7c5dde64a141dbc8551d5b7f6cf4ed7c2568d0cc520a8f",
|
||||
"sha256:8c7309c718f94b3a625cb648ace320157ad16ff131ae0af362c9f21b80ef6ec4"
|
||||
],
|
||||
"version": "==2.6"
|
||||
},
|
||||
"pysocks": {
|
||||
"hashes": [
|
||||
"sha256:3fe52c55890a248676fd69dc9e3c4e811718b777834bcaab7a8125cf9deac672"
|
||||
],
|
||||
"version": "==1.6.8"
|
||||
},
|
||||
"urllib3": {
|
||||
"hashes": [
|
||||
"sha256:06330f386d6e4b195fbfc736b297f58c5a892e4440e54d294d7004e3a9bbea1b",
|
||||
"sha256:cc44da8e1145637334317feebd728bd869a35285b93cbb4cca2577da7e62db4f"
|
||||
],
|
||||
"version": "==1.22"
|
||||
}
|
||||
},
|
||||
"develop": {
|
||||
"alabaster": {
|
||||
"hashes": [
|
||||
"sha256:2eef172f44e8d301d25aff8068fddd65f767a3f04b5f15b0f4922f113aa1c732",
|
||||
"sha256:37cdcb9e9954ed60912ebc1ca12a9d12178c26637abdf124e3cde2341c257fe0"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.7.10"
|
||||
},
|
||||
"apipkg": {
|
||||
"hashes": [
|
||||
"sha256:2e38399dbe842891fe85392601aab8f40a8f4cc5a9053c326de35a1cc0297ac6",
|
||||
"sha256:65d2aa68b28e7d31233bb2ba8eb31cda40e4671f8ac2d6b241e358c9652a74b9"
|
||||
],
|
||||
"version": "==1.4"
|
||||
},
|
||||
"attrs": {
|
||||
"hashes": [
|
||||
"sha256:4b90b09eeeb9b88c35bc642cbac057e45a5fd85367b985bd2809c62b7b939265",
|
||||
"sha256:e0d0eb91441a3b53dab4d9b743eafc1ac44476296a2053b6ca3af0b139faf87b"
|
||||
],
|
||||
"version": "==18.1.0"
|
||||
},
|
||||
"babel": {
|
||||
"hashes": [
|
||||
"sha256:8ce4cb6fdd4393edd323227cba3a077bceb2a6ce5201c902c65e730046f41f14",
|
||||
"sha256:ad209a68d7162c4cff4b29cdebe3dec4cef75492df501b0049a9433c96ce6f80"
|
||||
],
|
||||
"version": "==2.5.3"
|
||||
},
|
||||
"bleach": {
|
||||
"hashes": [
|
||||
"sha256:b8fa79e91f96c2c2cd9fd1f9eda906efb1b88b483048978ba62fef680e962b34",
|
||||
"sha256:eb7386f632349d10d9ce9d4a838b134d4731571851149f9cc2c05a9a837a9a44"
|
||||
],
|
||||
"version": "==2.1.3"
|
||||
},
|
||||
"blinker": {
|
||||
"hashes": [
|
||||
"sha256:471aee25f3992bd325afa3772f1063dbdbbca947a041b8b89466dc00d606f8b6"
|
||||
],
|
||||
"version": "==1.4"
|
||||
},
|
||||
"brotlipy": {
|
||||
"hashes": [
|
||||
"sha256:07194f4768eb62a4f4ea76b6d0df6ade185e24ebd85877c351daa0a069f1111a",
|
||||
"sha256:091b299bf36dd6ef7a06570dbc98c0f80a504a56c5b797f31934d2ad01ae7d17",
|
||||
"sha256:09ec3e125d16749b31c74f021aba809541b3564e5359f8c265cbae442810b41a",
|
||||
"sha256:0be698678a114addcf87a4b9496c552c68a2c99bf93cf8e08f5738b392e82057",
|
||||
"sha256:0fa6088a9a87645d43d7e21e32b4a6bf8f7c3939015a50158c10972aa7f425b7",
|
||||
"sha256:1ea4e578241504b58f2456a6c69952c88866c794648bdc74baee74839da61d44",
|
||||
"sha256:2699945a0a992c04fc7dc7fa2f1d0575a2c8b4b769f2874a08e8eae46bef36ae",
|
||||
"sha256:2a80319ae13ea8dd60ecdc4f5ccf6da3ae64787765923256b62c598c5bba4121",
|
||||
"sha256:2e5c64522364a9ebcdf47c5744a5ddeb3f934742d31e61ebfbbc095460b47162",
|
||||
"sha256:36def0b859beaf21910157b4c33eb3b06d8ce459c942102f16988cca6ea164df",
|
||||
"sha256:3a3e56ced8b15fbbd363380344f70f3b438e0fd1fcf27b7526b6172ea950e867",
|
||||
"sha256:3c1d5e2cf945a46975bdb11a19257fa057b67591eb232f393d260e7246d9e571",
|
||||
"sha256:50ca336374131cfad20612f26cc43c637ac0bfd2be3361495e99270883b52962",
|
||||
"sha256:5de6f7d010b7558f72f4b061a07395c5c3fd57f0285c5af7f126a677b976a868",
|
||||
"sha256:637847560d671657f993313ecc6c6c6666a936b7a925779fd044065c7bc035b9",
|
||||
"sha256:653faef61241bf8bf99d73ca7ec4baa63401ba7b2a2aa88958394869379d67c7",
|
||||
"sha256:786afc8c9bd67de8d31f46e408a3386331e126829114e4db034f91eacb05396d",
|
||||
"sha256:79aaf217072840f3e9a3b641cccc51f7fc23037496bd71e26211856b93f4b4cb",
|
||||
"sha256:7e31f7adcc5851ca06134705fcf3478210da45d35ad75ec181e1ce9ce345bb38",
|
||||
"sha256:8b39abc3256c978f575df5cd7893153277216474f303e26f0e43ba3d3969ef96",
|
||||
"sha256:9448227b0df082e574c45c983fa5cd4bda7bfb11ea6b59def0940c1647be0c3c",
|
||||
"sha256:96bc59ff9b5b5552843dc67999486a220e07a0522dddd3935da05dc194fa485c",
|
||||
"sha256:a07647886e24e2fb2d68ca8bf3ada398eb56fd8eac46c733d4d95c64d17f743b",
|
||||
"sha256:af65d2699cb9f13b26ec3ba09e75e80d31ff422c03675fcb36ee4dabe588fdc2",
|
||||
"sha256:b4c98b0d2c9c7020a524ca5bbff42027db1004c6571f8bc7b747f2b843128e7a",
|
||||
"sha256:c6cc0036b1304dd0073eec416cb2f6b9e37ac8296afd9e481cac3b1f07f9db25",
|
||||
"sha256:d2c1c724c4ac375feb2110f1af98ecdc0e5a8ea79d068efb5891f621a5b235cb",
|
||||
"sha256:dc6c5ee0df9732a44d08edab32f8a616b769cc5a4155a12d2d010d248eb3fb07",
|
||||
"sha256:fd1d1c64214af5d90014d82cee5d8141b13d44c92ada7a0c0ec0679c6f15a471"
|
||||
],
|
||||
"version": "==0.7.0"
|
||||
},
|
||||
"certifi": {
|
||||
"hashes": [
|
||||
"sha256:13e698f54293db9f89122b0581843a782ad0934a4fe0172d2a980ba77fc61bb7",
|
||||
"sha256:9fa520c1bacfb634fa7af20a76bcbd3d5fb390481724c597da32c719a7dca4b0"
|
||||
],
|
||||
"version": "==2018.4.16"
|
||||
},
|
||||
"cffi": {
|
||||
"hashes": [
|
||||
"sha256:151b7eefd035c56b2b2e1eb9963c90c6302dc15fbd8c1c0a83a163ff2c7d7743",
|
||||
"sha256:1553d1e99f035ace1c0544050622b7bc963374a00c467edafac50ad7bd276aef",
|
||||
"sha256:1b0493c091a1898f1136e3f4f991a784437fac3673780ff9de3bcf46c80b6b50",
|
||||
"sha256:2ba8a45822b7aee805ab49abfe7eec16b90587f7f26df20c71dd89e45a97076f",
|
||||
"sha256:3c85641778460581c42924384f5e68076d724ceac0f267d66c757f7535069c93",
|
||||
"sha256:3eb6434197633b7748cea30bf0ba9f66727cdce45117a712b29a443943733257",
|
||||
"sha256:4c91af6e967c2015729d3e69c2e51d92f9898c330d6a851bf8f121236f3defd3",
|
||||
"sha256:770f3782b31f50b68627e22f91cb182c48c47c02eb405fd689472aa7b7aa16dc",
|
||||
"sha256:79f9b6f7c46ae1f8ded75f68cf8ad50e5729ed4d590c74840471fc2823457d04",
|
||||
"sha256:7a33145e04d44ce95bcd71e522b478d282ad0eafaf34fe1ec5bbd73e662f22b6",
|
||||
"sha256:857959354ae3a6fa3da6651b966d13b0a8bed6bbc87a0de7b38a549db1d2a359",
|
||||
"sha256:87f37fe5130574ff76c17cab61e7d2538a16f843bb7bca8ebbc4b12de3078596",
|
||||
"sha256:95d5251e4b5ca00061f9d9f3d6fe537247e145a8524ae9fd30a2f8fbce993b5b",
|
||||
"sha256:9d1d3e63a4afdc29bd76ce6aa9d58c771cd1599fbba8cf5057e7860b203710dd",
|
||||
"sha256:a36c5c154f9d42ec176e6e620cb0dd275744aa1d804786a71ac37dc3661a5e95",
|
||||
"sha256:ae5e35a2c189d397b91034642cb0eab0e346f776ec2eb44a49a459e6615d6e2e",
|
||||
"sha256:b0f7d4a3df8f06cf49f9f121bead236e328074de6449866515cea4907bbc63d6",
|
||||
"sha256:b75110fb114fa366b29a027d0c9be3709579602ae111ff61674d28c93606acca",
|
||||
"sha256:ba5e697569f84b13640c9e193170e89c13c6244c24400fc57e88724ef610cd31",
|
||||
"sha256:be2a9b390f77fd7676d80bc3cdc4f8edb940d8c198ed2d8c0be1319018c778e1",
|
||||
"sha256:d5d8555d9bfc3f02385c1c37e9f998e2011f0db4f90e250e5bc0c0a85a813085",
|
||||
"sha256:e55e22ac0a30023426564b1059b035973ec82186ddddbac867078435801c7801",
|
||||
"sha256:e90f17980e6ab0f3c2f3730e56d1fe9bcba1891eeea58966e89d352492cc74f4",
|
||||
"sha256:ecbb7b01409e9b782df5ded849c178a0aa7c906cf8c5a67368047daab282b184",
|
||||
"sha256:ed01918d545a38998bfa5902c7c00e0fee90e957ce036a4000a88e3fe2264917",
|
||||
"sha256:edabd457cd23a02965166026fd9bfd196f4324fe6032e866d0f3bd0301cd486f",
|
||||
"sha256:fdf1c1dc5bafc32bc5d08b054f94d659422b05aba244d6be4ddc1c72d9aa70fb"
|
||||
],
|
||||
"version": "==1.11.5"
|
||||
},
|
||||
"chardet": {
|
||||
"hashes": [
|
||||
"sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae",
|
||||
"sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"
|
||||
],
|
||||
"version": "==3.0.4"
|
||||
},
|
||||
"click": {
|
||||
"hashes": [
|
||||
"sha256:29f99fc6125fbc931b758dc053b3114e55c77a6e4c6c3a2674a2dc986016381d",
|
||||
"sha256:f15516df478d5a56180fbf80e68f206010e6d160fc39fa508b65e035fd75130b"
|
||||
],
|
||||
"version": "==6.7"
|
||||
},
|
||||
"cmarkgfm": {
|
||||
"hashes": [
|
||||
"sha256:0186dccca79483e3405217993b83b914ba4559fe9a8396efc4eea56561b74061",
|
||||
"sha256:1a625afc6f62da428df96ec325dc30866cc5781520cbd904ff4ec44cf018171c",
|
||||
"sha256:275905bb371a99285c74931700db3f0c078e7603bed383e8cf1a09f3ee05a3de",
|
||||
"sha256:50098f1c4950722521f0671e54139e0edc1837d63c990cf0f3d2c49607bb51a2",
|
||||
"sha256:50ed116d0b60a07df0dc7b180c28569064b9d37d1578d4c9021cff04d725cb63",
|
||||
"sha256:61a72def110eed903cd1848245897bcb80d295cd9d13944d4f9f30cba5b76655",
|
||||
"sha256:64186fb75d973a06df0e6ea12879533b71f6e7ba1ab01ffee7fc3e7534758889",
|
||||
"sha256:665303d34d7f14f10d7b0651082f25ebf7107f29ef3d699490cac16cdc0fc8ce",
|
||||
"sha256:70b18f843aec58e4e64aadce48a897fe7c50426718b7753aaee399e72df64190",
|
||||
"sha256:761ee7b04d1caee2931344ac6bfebf37102ffb203b136b676b0a71a3f0ea3c87",
|
||||
"sha256:811527e9b7280b136734ed6cb6845e5fbccaeaa132ddf45f0246cbe544016957",
|
||||
"sha256:987b0e157f70c72a84f3c2f9ef2d7ab0f26c08f2bf326c12c087ff9eebcb3ff5",
|
||||
"sha256:9fc6a2183d0a9b0974ec7cdcdad42bd78a3be674cc3e65f87dd694419b3b0ab7",
|
||||
"sha256:c573ea89dd95d41b6d8cf36799c34b6d5b1eac4aed0212dee0f0a11fb7b01e8f",
|
||||
"sha256:c5f1b9e8592d2c448c44e6bc0d91224b16ea5f8293908b1561de1f6d2d0658b1",
|
||||
"sha256:cbe581456357d8f0674d6a590b1aaf46c11d01dd0a23af147a51a798c3818034",
|
||||
"sha256:cf219bec69e601fe27e3974b7307d2f06082ab385d42752738ad2eb630a47d65",
|
||||
"sha256:d08bad67fa18f7e8ff738c090628ee0cbf0505d74a991c848d6d04abfe67b697",
|
||||
"sha256:d6f716d7b1182bf35862b5065112f933f43dd1aa4f8097c9bcfb246f71528a34",
|
||||
"sha256:e08e479102627641c7cb4ece421c6ed4124820b1758765db32201136762282d9",
|
||||
"sha256:e20ac21418af0298437d29599f7851915497ce9f2866bc8e86b084d8911ee061",
|
||||
"sha256:e25f53c37e319241b9a412382140dffac98ca756ba8f360ac7ab5e30cad9670a",
|
||||
"sha256:f20900f16377f2109783ae9348d34bc80530808439591c3d3df73d5c7ef1a00c"
|
||||
],
|
||||
"version": "==0.4.2"
|
||||
},
|
||||
"codecov": {
|
||||
"hashes": [
|
||||
"sha256:8ed8b7c6791010d359baed66f84f061bba5bd41174bf324c31311e8737602788",
|
||||
"sha256:ae00d68e18d8a20e9c3288ba3875ae03db3a8e892115bf9b83ef20507732bed4"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.0.15"
|
||||
},
|
||||
"configparser": {
|
||||
"hashes": [
|
||||
"sha256:5308b47021bc2340965c371f0f058cc6971a04502638d4244225c49d80db273a"
|
||||
],
|
||||
"markers": "python_version < '3.2'",
|
||||
"version": "==3.5.0"
|
||||
},
|
||||
"contextlib2": {
|
||||
"hashes": [
|
||||
"sha256:509f9419ee91cdd00ba34443217d5ca51f5a364a404e1dce9e8979cea969ca48",
|
||||
"sha256:f5260a6e679d2ff42ec91ec5252f4eeffdcf21053db9113bd0a8e4d953769c00"
|
||||
],
|
||||
"markers": "python_version < '3.2'",
|
||||
"version": "==0.5.5"
|
||||
},
|
||||
"coverage": {
|
||||
"hashes": [
|
||||
"sha256:03481e81d558d30d230bc12999e3edffe392d244349a90f4ef9b88425fac74ba",
|
||||
"sha256:0b136648de27201056c1869a6c0d4e23f464750fd9a9ba9750b8336a244429ed",
|
||||
"sha256:104ab3934abaf5be871a583541e8829d6c19ce7bde2923b2751e0d3ca44db60a",
|
||||
"sha256:15b111b6a0f46ee1a485414a52a7ad1d703bdf984e9ed3c288a4414d3871dcbd",
|
||||
"sha256:198626739a79b09fa0a2f06e083ffd12eb55449b5f8bfdbeed1df4910b2ca640",
|
||||
"sha256:1c383d2ef13ade2acc636556fd544dba6e14fa30755f26812f54300e401f98f2",
|
||||
"sha256:28b2191e7283f4f3568962e373b47ef7f0392993bb6660d079c62bd50fe9d162",
|
||||
"sha256:2eb564bbf7816a9d68dd3369a510be3327f1c618d2357fa6b1216994c2e3d508",
|
||||
"sha256:337ded681dd2ef9ca04ef5d93cfc87e52e09db2594c296b4a0a3662cb1b41249",
|
||||
"sha256:3a2184c6d797a125dca8367878d3b9a178b6fdd05fdc2d35d758c3006a1cd694",
|
||||
"sha256:3c79a6f7b95751cdebcd9037e4d06f8d5a9b60e4ed0cd231342aa8ad7124882a",
|
||||
"sha256:3d72c20bd105022d29b14a7d628462ebdc61de2f303322c0212a054352f3b287",
|
||||
"sha256:3eb42bf89a6be7deb64116dd1cc4b08171734d721e7a7e57ad64cc4ef29ed2f1",
|
||||
"sha256:4635a184d0bbe537aa185a34193898eee409332a8ccb27eea36f262566585000",
|
||||
"sha256:56e448f051a201c5ebbaa86a5efd0ca90d327204d8b059ab25ad0f35fbfd79f1",
|
||||
"sha256:5a13ea7911ff5e1796b6d5e4fbbf6952381a611209b736d48e675c2756f3f74e",
|
||||
"sha256:69bf008a06b76619d3c3f3b1983f5145c75a305a0fea513aca094cae5c40a8f5",
|
||||
"sha256:6bc583dc18d5979dc0f6cec26a8603129de0304d5ae1f17e57a12834e7235062",
|
||||
"sha256:701cd6093d63e6b8ad7009d8a92425428bc4d6e7ab8d75efbb665c806c1d79ba",
|
||||
"sha256:7608a3dd5d73cb06c531b8925e0ef8d3de31fed2544a7de6c63960a1e73ea4bc",
|
||||
"sha256:76ecd006d1d8f739430ec50cc872889af1f9c1b6b8f48e29941814b09b0fd3cc",
|
||||
"sha256:7aa36d2b844a3e4a4b356708d79fd2c260281a7390d678a10b91ca595ddc9e99",
|
||||
"sha256:7d3f553904b0c5c016d1dad058a7554c7ac4c91a789fca496e7d8347ad040653",
|
||||
"sha256:7e1fe19bd6dce69d9fd159d8e4a80a8f52101380d5d3a4d374b6d3eae0e5de9c",
|
||||
"sha256:8c3cb8c35ec4d9506979b4cf90ee9918bc2e49f84189d9bf5c36c0c1119c6558",
|
||||
"sha256:9d6dd10d49e01571bf6e147d3b505141ffc093a06756c60b053a859cb2128b1f",
|
||||
"sha256:9e112fcbe0148a6fa4f0a02e8d58e94470fc6cb82a5481618fea901699bf34c4",
|
||||
"sha256:ac4fef68da01116a5c117eba4dd46f2e06847a497de5ed1d64bb99a5fda1ef91",
|
||||
"sha256:b8815995e050764c8610dbc82641807d196927c3dbed207f0a079833ffcf588d",
|
||||
"sha256:be6cfcd8053d13f5f5eeb284aa8a814220c3da1b0078fa859011c7fffd86dab9",
|
||||
"sha256:c1bb572fab8208c400adaf06a8133ac0712179a334c09224fb11393e920abcdd",
|
||||
"sha256:de4418dadaa1c01d497e539210cb6baa015965526ff5afc078c57ca69160108d",
|
||||
"sha256:e05cb4d9aad6233d67e0541caa7e511fa4047ed7750ec2510d466e806e0255d6",
|
||||
"sha256:e4d96c07229f58cb686120f168276e434660e4358cc9cf3b0464210b04913e77",
|
||||
"sha256:f3f501f345f24383c0000395b26b726e46758b71393267aeae0bd36f8b3ade80",
|
||||
"sha256:f8a923a85cb099422ad5a2e345fe877bbc89a8a8b23235824a93488150e45f6e"
|
||||
],
|
||||
"version": "==4.5.1"
|
||||
},
|
||||
"decorator": {
|
||||
"hashes": [
|
||||
"sha256:2c51dff8ef3c447388fe5e4453d24a2bf128d3a4c32af3fabef1f01c6851ab82",
|
||||
"sha256:c39efa13fbdeb4506c476c9b3babf6a718da943dab7811c206005a4a956c080c"
|
||||
],
|
||||
"version": "==4.3.0"
|
||||
},
|
||||
"detox": {
|
||||
"hashes": [
|
||||
"sha256:cb24895a0e4f95c0bcb1087a201c453600e075568af00848e91518fb2b984568",
|
||||
"sha256:f3119bca4444f1e8a1d7189b064c52cfdd9a89ad3a1c921d78b49bf7f5dc5b1b"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.12"
|
||||
},
|
||||
"docutils": {
|
||||
"hashes": [
|
||||
"sha256:02aec4bd92ab067f6ff27a38a38a41173bf01bed8f89157768c1573f53e474a6",
|
||||
"sha256:51e64ef2ebfb29cae1faa133b3710143496eca21c530f3f71424d77687764274",
|
||||
"sha256:7a4bd47eaf6596e1295ecb11361139febe29b084a87bf005bf899f9a42edc3c6"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.14"
|
||||
},
|
||||
"enum34": {
|
||||
"hashes": [
|
||||
"sha256:2d81cbbe0e73112bdfe6ef8576f2238f2ba27dd0d55752a776c41d38b7da2850",
|
||||
"sha256:644837f692e5f550741432dd3f223bbb9852018674981b1664e5dc339387588a",
|
||||
"sha256:6bd0f6ad48ec2aa117d3d141940d484deccda84d4fcd884f5c3d93c23ecd8c79",
|
||||
"sha256:8ad8c4783bf61ded74527bffb48ed9b54166685e4230386a9ed9b1279e2df5b1"
|
||||
],
|
||||
"markers": "python_version < '3.4'",
|
||||
"version": "==1.1.6"
|
||||
},
|
||||
"eventlet": {
|
||||
"hashes": [
|
||||
"sha256:06cffa55b335cc4fc32d0079242a81e8a9cddf2581d64d5f0543e2d412b26ca8",
|
||||
"sha256:554a50dad7abee0a9775b0780ce9d9c0bd9123dda4743c46d4314170267c6c47"
|
||||
],
|
||||
"version": "==0.23.0"
|
||||
},
|
||||
"execnet": {
|
||||
"hashes": [
|
||||
"sha256:a7a84d5fa07a089186a329528f127c9d73b9de57f1a1131b82bb5320ee651f6a",
|
||||
"sha256:fc155a6b553c66c838d1a22dba1dc9f5f505c43285a878c6f74a79c024750b83"
|
||||
],
|
||||
"version": "==1.5.0"
|
||||
},
|
||||
"flake8": {
|
||||
"hashes": [
|
||||
"sha256:7253265f7abd8b313e3892944044a365e3f4ac3fcdcfb4298f55ee9ddf188ba0",
|
||||
"sha256:c7841163e2b576d435799169b78703ad6ac1bbb0f199994fc05f700b2a90ea37"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==3.5.0"
|
||||
},
|
||||
"flask": {
|
||||
"hashes": [
|
||||
"sha256:2271c0070dbcb5275fad4a82e29f23ab92682dc45f9dfbc22c02ba9b9322ce48",
|
||||
"sha256:a080b744b7e345ccfcbc77954861cb05b3c63786e93f2b3875e0913d44b43f05"
|
||||
],
|
||||
"version": "==1.0.2"
|
||||
},
|
||||
"funcsigs": {
|
||||
"hashes": [
|
||||
"sha256:330cc27ccbf7f1e992e69fef78261dc7c6569012cf397db8d3de0234e6c937ca",
|
||||
"sha256:a7bb0f2cf3a3fd1ab2732cb49eba4252c2af4240442415b4abce3b87022a8f50"
|
||||
],
|
||||
"markers": "python_version < '3.3'",
|
||||
"version": "==1.0.2"
|
||||
},
|
||||
"future": {
|
||||
"hashes": [
|
||||
"sha256:e39ced1ab767b5936646cedba8bcce582398233d6a627067d4c6a454c90cfedb"
|
||||
],
|
||||
"version": "==0.16.0"
|
||||
},
|
||||
"greenlet": {
|
||||
"hashes": [
|
||||
"sha256:09ef2636ea35782364c830f07127d6c7a70542b178268714a9a9ba16318e7e8b",
|
||||
"sha256:0fef83d43bf87a5196c91e73cb9772f945a4caaff91242766c5916d1dd1381e4",
|
||||
"sha256:1b7df09c6598f5cfb40f843ade14ed1eb40596e75cd79b6fa2efc750ba01bb01",
|
||||
"sha256:1fff21a2da5f9e03ddc5bd99131a6b8edf3d7f9d6bc29ba21784323d17806ed7",
|
||||
"sha256:42118bf608e0288e35304b449a2d87e2ba77d1e373e8aa221ccdea073de026fa",
|
||||
"sha256:50643fd6d54fd919f9a0a577c5f7b71f5d21f0959ab48767bd4bb73ae0839500",
|
||||
"sha256:58798b5d30054bb4f6cf0f712f08e6092df23a718b69000786634a265e8911a9",
|
||||
"sha256:5b49b3049697aeae17ef7bf21267e69972d9e04917658b4e788986ea5cc518e8",
|
||||
"sha256:75c413551a436b462d5929255b6dc9c0c3c2b25cbeaee5271a56c7fda8ca49c0",
|
||||
"sha256:769b740aeebd584cd59232be84fdcaf6270b8adc356596cdea5b2152c82caaac",
|
||||
"sha256:ad2383d39f13534f3ca5c48fe1fc0975676846dc39c2cece78c0f1f9891418e0",
|
||||
"sha256:b417bb7ff680d43e7bd7a13e2e08956fa6acb11fd432f74c97b7664f8bdb6ec1",
|
||||
"sha256:b6ef0cabaf5a6ecb5ac122e689d25ba12433a90c7b067b12e5f28bdb7fb78254",
|
||||
"sha256:c2de19c88bdb0366c976cc125dca1002ec1b346989d59524178adfd395e62421",
|
||||
"sha256:c7b04a6dc74087b1598de8d713198de4718fa30ec6cbb84959b26426c198e041",
|
||||
"sha256:f8f2a0ae8de0b49c7b5b2daca4f150fdd9c1173e854df2cce3b04123244f9f45",
|
||||
"sha256:fcfadaf4bf68a27e5dc2f42cbb2f4b4ceea9f05d1d0b8f7787e640bed2801634"
|
||||
],
|
||||
"version": "==0.4.13"
|
||||
},
|
||||
"html5lib": {
|
||||
"hashes": [
|
||||
"sha256:20b159aa3badc9d5ee8f5c647e5efd02ed2a66ab8d354930bd9ff139fc1dc0a3",
|
||||
"sha256:66cb0dcfdbbc4f9c3ba1a63fdb511ffdbd4f513b2b6d81b80cd26ce6b3fb3736"
|
||||
],
|
||||
"version": "==1.0.1"
|
||||
},
|
||||
"httpbin": {
|
||||
"hashes": [
|
||||
"sha256:7a04b5904c80b7aa04dd0a6af6520d68ce17a5db175e66a64b971f8e93d73a26",
|
||||
"sha256:cbb37790c91575f4f15757f42ad41d9f729eb227d5edbe89e4ec175486db8dfa"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.7.0"
|
||||
},
|
||||
"idna": {
|
||||
"hashes": [
|
||||
"sha256:2c6a5de3089009e3da7c5dde64a141dbc8551d5b7f6cf4ed7c2568d0cc520a8f",
|
||||
"sha256:8c7309c718f94b3a625cb648ace320157ad16ff131ae0af362c9f21b80ef6ec4"
|
||||
],
|
||||
"version": "==2.6"
|
||||
},
|
||||
"imagesize": {
|
||||
"hashes": [
|
||||
"sha256:3620cc0cadba3f7475f9940d22431fc4d407269f1be59ec9b8edcca26440cf18",
|
||||
"sha256:5b326e4678b6925158ccc66a9fa3122b6106d7c876ee32d7de6ce59385b96315"
|
||||
],
|
||||
"version": "==1.0.0"
|
||||
},
|
||||
"itsdangerous": {
|
||||
"hashes": [
|
||||
"sha256:cbb3fcf8d3e33df861709ecaf89d9e6629cff0a217bc2848f1b41cd30d360519"
|
||||
],
|
||||
"version": "==0.24"
|
||||
},
|
||||
"jinja2": {
|
||||
"hashes": [
|
||||
"sha256:74c935a1b8bb9a3947c50a54766a969d4846290e1e788ea44c1392163723c3bd",
|
||||
"sha256:f84be1bb0040caca4cea721fcbbbbd61f9be9464ca236387158b0feea01914a4"
|
||||
],
|
||||
"version": "==2.10"
|
||||
},
|
||||
"markupsafe": {
|
||||
"hashes": [
|
||||
"sha256:a6be69091dac236ea9c6bc7d012beab42010fa914c459791d627dad4910eb665"
|
||||
],
|
||||
"version": "==1.0"
|
||||
},
|
||||
"mccabe": {
|
||||
"hashes": [
|
||||
"sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42",
|
||||
"sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"
|
||||
],
|
||||
"version": "==0.6.1"
|
||||
},
|
||||
"mock": {
|
||||
"hashes": [
|
||||
"sha256:5ce3c71c5545b472da17b72268978914d0252980348636840bd34a00b5cc96c1",
|
||||
"sha256:b158b6df76edd239b8208d481dc46b6afd45a846b7812ff0ce58971cf5bc8bba"
|
||||
],
|
||||
"markers": "python_version < '3.0'",
|
||||
"version": "==2.0.0"
|
||||
},
|
||||
"more-itertools": {
|
||||
"hashes": [
|
||||
"sha256:0dd8f72eeab0d2c3bd489025bb2f6a1b8342f9b198f6fc37b52d15cfa4531fea",
|
||||
"sha256:11a625025954c20145b37ff6309cd54e39ca94f72f6bb9576d1195db6fa2442e",
|
||||
"sha256:c9ce7eccdcb901a2c75d326ea134e0886abfbea5f93e91cc95de9507c0816c44"
|
||||
],
|
||||
"version": "==4.1.0"
|
||||
},
|
||||
"pbr": {
|
||||
"hashes": [
|
||||
"sha256:680bf5ba9b28dd56e08eb7c267991a37c7a5f90a92c2e07108829931a50ff80a",
|
||||
"sha256:6874feb22334a1e9a515193cba797664e940b763440c88115009ec323a7f2df5"
|
||||
],
|
||||
"version": "==4.0.3"
|
||||
},
|
||||
"pluggy": {
|
||||
"hashes": [
|
||||
"sha256:7f8ae7f5bdf75671a718d2daf0a64b7885f74510bcd98b1a0bb420eb9a9d0cff",
|
||||
"sha256:d345c8fe681115900d6da8d048ba67c25df42973bda370783cd58826442dcd7c",
|
||||
"sha256:e160a7fcf25762bb60efc7e171d4497ff1d8d2d75a3d0df7a21b76821ecbf5c5"
|
||||
],
|
||||
"version": "==0.6.0"
|
||||
},
|
||||
"py": {
|
||||
"hashes": [
|
||||
"sha256:29c9fab495d7528e80ba1e343b958684f4ace687327e6f789a94bf3d1915f881",
|
||||
"sha256:983f77f3331356039fdd792e9220b7b8ee1aa6bd2b25f567a963ff1de5a64f6a"
|
||||
],
|
||||
"version": "==1.5.3"
|
||||
},
|
||||
"pycodestyle": {
|
||||
"hashes": [
|
||||
"sha256:682256a5b318149ca0d2a9185d365d8864a768a28db66a84a2ea946bcc426766",
|
||||
"sha256:6c4245ade1edfad79c3446fadfc96b0de2759662dc29d07d80a6f27ad1ca6ba9"
|
||||
],
|
||||
"version": "==2.3.1"
|
||||
},
|
||||
"pycparser": {
|
||||
"hashes": [
|
||||
"sha256:99a8ca03e29851d96616ad0404b4aad7d9ee16f25c9f9708a11faf2810f7b226"
|
||||
],
|
||||
"version": "==2.18"
|
||||
},
|
||||
"pyflakes": {
|
||||
"hashes": [
|
||||
"sha256:08bd6a50edf8cffa9fa09a463063c425ecaaf10d1eb0335a7e8b1401aef89e6f",
|
||||
"sha256:8d616a382f243dbf19b54743f280b80198be0bca3a5396f1d2e1fca6223e8805"
|
||||
],
|
||||
"version": "==1.6.0"
|
||||
},
|
||||
"pygments": {
|
||||
"hashes": [
|
||||
"sha256:78f3f434bcc5d6ee09020f92ba487f95ba50f1e3ef83ae96b9d5ffa1bab25c5d",
|
||||
"sha256:dbae1046def0efb574852fab9e90209b23f556367b5a320c0bcb871c77c3e8cc"
|
||||
],
|
||||
"version": "==2.2.0"
|
||||
},
|
||||
"pysocks": {
|
||||
"hashes": [
|
||||
"sha256:3fe52c55890a248676fd69dc9e3c4e811718b777834bcaab7a8125cf9deac672"
|
||||
],
|
||||
"version": "==1.6.8"
|
||||
},
|
||||
"pytest": {
|
||||
"hashes": [
|
||||
"sha256:54713b26c97538db6ff0703a12b19aeaeb60b5e599de542e7fca0ec83b9038e8",
|
||||
"sha256:829230122facf05a5f81a6d4dfe6454a04978ea3746853b2b84567ecf8e5c526"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==3.5.1"
|
||||
},
|
||||
"pytest-cov": {
|
||||
"hashes": [
|
||||
"sha256:03aa752cf11db41d281ea1d807d954c4eda35cfa1b21d6971966cc041bbf6e2d",
|
||||
"sha256:890fe5565400902b0c78b5357004aab1c814115894f4f21370e2433256a3eeec"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.5.1"
|
||||
},
|
||||
"pytest-forked": {
|
||||
"hashes": [
|
||||
"sha256:e4500cd0509ec4a26535f7d4112a8cc0f17d3a41c29ffd4eab479d2a55b30805",
|
||||
"sha256:f275cb48a73fc61a6710726348e1da6d68a978f0ec0c54ece5a5fae5977e5a08"
|
||||
],
|
||||
"version": "==0.2"
|
||||
},
|
||||
"pytest-httpbin": {
|
||||
"hashes": [
|
||||
"sha256:8cd57e27418a7d7d205fcc9802eea246ed06170e3065abfa76c6d9b40553592c",
|
||||
"sha256:d3919c5df0b644454129c0066a8ae62db40ac54bacb4cfd89d8cfa58615a4b42"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.3.0"
|
||||
},
|
||||
"pytest-mock": {
|
||||
"hashes": [
|
||||
"sha256:53801e621223d34724926a5c98bd90e8e417ce35264365d39d6c896388dcc928",
|
||||
"sha256:d89a8209d722b8307b5e351496830d5cc5e192336003a485443ae9adeb7dd4c0"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.10.0"
|
||||
},
|
||||
"pytest-xdist": {
|
||||
"hashes": [
|
||||
"sha256:be2662264b035920ba740ed6efb1c816a83c8a22253df7766d129f6a7bfdbd35",
|
||||
"sha256:e8f5744acc270b3e7d915bdb4d5f471670f049b6fbd163d4cbd52203b075d30f"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.22.2"
|
||||
},
|
||||
"pytz": {
|
||||
"hashes": [
|
||||
"sha256:65ae0c8101309c45772196b21b74c46b2e5d11b6275c45d251b150d5da334555",
|
||||
"sha256:c06425302f2cf668f1bba7a0a03f3c1d34d4ebeef2c72003da308b3947c7f749"
|
||||
],
|
||||
"version": "==2018.4"
|
||||
},
|
||||
"raven": {
|
||||
"hashes": [
|
||||
"sha256:1c641e5ebc2d4185560608e253970ca0d4b98475f4edf67735015a415f9e1d48",
|
||||
"sha256:95aecf76c414facaddbb056f3e98c7936318123e467728f2e50b3a66b65a6ef7"
|
||||
],
|
||||
"version": "==6.8.0"
|
||||
},
|
||||
"readme-renderer": {
|
||||
"hashes": [
|
||||
"sha256:bde909eaa84d65b7942f7e6998c8b427b90b568b2630ff0306f4ca75f6d2a909",
|
||||
"sha256:e7e43a7ba49f08c3cb660d0f2e25b561f6b10b36c63f029060230aab2dc2875e"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==20.0"
|
||||
},
|
||||
"requests": {
|
||||
"hashes": [
|
||||
"sha256:6a1b267aa90cac58ac3a765d067950e7dbbf75b1da07e895d1f594193a40a38b",
|
||||
"sha256:9c443e7324ba5b85070c4a818ade28bfabedf16ea10206da1132edaa6dda237e"
|
||||
],
|
||||
"version": "==2.18.4"
|
||||
},
|
||||
"six": {
|
||||
"hashes": [
|
||||
"sha256:70e8a77beed4562e7f14fe23a786b54f6296e34344c23bc42f07b15018ff98e9",
|
||||
"sha256:832dc0e10feb1aa2c68dcc57dbb658f1c7e65b9b61af69048abc87a2db00a0eb"
|
||||
],
|
||||
"version": "==1.11.0"
|
||||
},
|
||||
"snowballstemmer": {
|
||||
"hashes": [
|
||||
"sha256:919f26a68b2c17a7634da993d91339e288964f93c274f1343e3bbbe2096e1128",
|
||||
"sha256:9f3bcd3c401c3e862ec0ebe6d2c069ebc012ce142cce209c098ccb5b09136e89"
|
||||
],
|
||||
"version": "==1.2.1"
|
||||
},
|
||||
"sphinx": {
|
||||
"hashes": [
|
||||
"sha256:11f271e7a9398385ed730e90f0bb41dc3815294bdcd395b46ed2d033bc2e7d87",
|
||||
"sha256:4064ea6c56feeb268838cb8fbbee507d0c3d5d92fa63a7df935a916b52c9e2f5"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.5.5"
|
||||
},
|
||||
"tox": {
|
||||
"hashes": [
|
||||
"sha256:96efa09710a3daeeb845561ebbe1497641d9cef2ee0aea30db6969058b2bda2f",
|
||||
"sha256:9ee7de958a43806402a38c0d2aa07fa8553f4d2c20a15b140e9f771c2afeade0"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==3.0.0"
|
||||
},
|
||||
"urllib3": {
|
||||
"hashes": [
|
||||
"sha256:06330f386d6e4b195fbfc736b297f58c5a892e4440e54d294d7004e3a9bbea1b",
|
||||
"sha256:cc44da8e1145637334317feebd728bd869a35285b93cbb4cca2577da7e62db4f"
|
||||
],
|
||||
"version": "==1.22"
|
||||
},
|
||||
"virtualenv": {
|
||||
"hashes": [
|
||||
"sha256:1d7e241b431e7afce47e77f8843a276f652699d1fa4f93b9d8ce0076fd7b0b54",
|
||||
"sha256:e8e05d4714a1c51a2f5921e62f547fcb0f713ebbe959e0a7f585cc8bef71d11f"
|
||||
],
|
||||
"version": "==15.2.0"
|
||||
},
|
||||
"webencodings": {
|
||||
"hashes": [
|
||||
"sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78",
|
||||
"sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"
|
||||
],
|
||||
"version": "==0.5.1"
|
||||
},
|
||||
"werkzeug": {
|
||||
"hashes": [
|
||||
"sha256:c3fd7a7d41976d9f44db327260e263132466836cef6f91512889ed60ad26557c",
|
||||
"sha256:d5da73735293558eb1651ee2fddc4d0dedcfa06538b8813a2e20011583c9e49b"
|
||||
],
|
||||
"version": "==0.14.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
135
README.md
@@ -1,23 +1,9 @@
|
||||
Requests: HTTP for Humans™
|
||||
==========================
|
||||
# Requests
|
||||
|
||||
[](https://pypi.org/project/requests/)
|
||||
[](https://pypi.org/project/requests/)
|
||||
[](https://pypi.org/project/requests/)
|
||||
[](https://codecov.io/github/requests/requests)
|
||||
[](https://github.com/requests/requests/graphs/contributors)
|
||||
[](https://saythanks.io/to/kennethreitz)
|
||||
**Requests** is a simple, yet elegant, HTTP library.
|
||||
|
||||
**If you're interested in financially supporting Kenneth Reitz open source, consider [visiting this link](https://cash.me/$KennethReitz). Your support helps tremendously with sustainability of motivation, as Open Source is no longer part of my day job.**
|
||||
|
||||
Requests is the only *Non-GMO* HTTP library for Python, safe for human
|
||||
consumption.
|
||||
|
||||

|
||||
|
||||
Behold, the power of Requests:
|
||||
|
||||
``` {.sourceCode .python}
|
||||
```python
|
||||
>>> import requests
|
||||
>>> r = requests.get('https://api.github.com/user', auth=('user', 'pass'))
|
||||
>>> r.status_code
|
||||
200
|
||||
@@ -26,82 +12,67 @@ Behold, the power of Requests:
|
||||
>>> r.encoding
|
||||
'utf-8'
|
||||
>>> r.text
|
||||
u'{"type":"User"...'
|
||||
'{"type":"User"...'
|
||||
>>> r.json()
|
||||
{u'disk_usage': 368627, u'private_gists': 484, ...}
|
||||
{'disk_usage': 368627, 'private_gists': 484, ...}
|
||||
```
|
||||
|
||||
See [the similar code, sans Requests](https://gist.github.com/973705).
|
||||
Requests allows you to send HTTP/1.1 requests extremely easily. There’s no need to manually add query strings to your URLs, or to form-encode your `PUT` & `POST` data — but nowadays, just use the `json` method!
|
||||
|
||||
[](http://docs.python-requests.org/)
|
||||
Requests is one of the most downloaded Python package today, pulling in around `14M downloads / week`— according to GitHub, Requests is currently [depended upon](https://github.com/psf/requests/network/dependents?package_id=UGFja2FnZS01NzA4OTExNg%3D%3D) by `500,000+` repositories. You may certainly put your trust in this code.
|
||||
|
||||
Requests allows you to send *organic, grass-fed* HTTP/1.1 requests,
|
||||
without the need for manual labor. There's no need to manually add query
|
||||
strings to your URLs, or to form-encode your POST data. Keep-alive and
|
||||
HTTP connection pooling are 100% automatic, thanks to
|
||||
[urllib3](https://github.com/shazow/urllib3).
|
||||
[](https://pepy.tech/project/requests/month)
|
||||
[](https://pypi.org/project/requests)
|
||||
[](https://github.com/psf/requests/graphs/contributors)
|
||||
|
||||
Besides, all the cool kids are doing it. Requests is one of the most
|
||||
downloaded Python packages of all time, pulling in over 11,000,000
|
||||
downloads every month. You don't want to be left out!
|
||||
## Installing Requests and Supported Versions
|
||||
|
||||
Feature Support
|
||||
---------------
|
||||
Requests is available on PyPI:
|
||||
|
||||
Requests is ready for today's web.
|
||||
|
||||
- International Domains and URLs
|
||||
- Keep-Alive & Connection Pooling
|
||||
- Sessions with Cookie Persistence
|
||||
- Browser-style SSL Verification
|
||||
- Basic/Digest Authentication
|
||||
- Elegant Key/Value Cookies
|
||||
- Automatic Decompression
|
||||
- Automatic Content Decoding
|
||||
- Unicode Response Bodies
|
||||
- Multipart File Uploads
|
||||
- HTTP(S) Proxy Support
|
||||
- Connection Timeouts
|
||||
- Streaming Downloads
|
||||
- `.netrc` Support
|
||||
- Chunked Requests
|
||||
|
||||
Requests officially supports Python 2.7 & 3.4–3.7, and runs great on
|
||||
PyPy.
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
To install Requests, simply use [pipenv](http://pipenv.org/) (or pip, of
|
||||
course):
|
||||
|
||||
``` {.sourceCode .bash}
|
||||
$ pipenv install requests
|
||||
✨🍰✨
|
||||
```console
|
||||
$ python -m pip install requests
|
||||
```
|
||||
|
||||
Satisfaction guaranteed.
|
||||
Requests officially supports Python 2.7 & 3.6+.
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
## Supported Features & Best–Practices
|
||||
|
||||
Fantastic documentation is available at
|
||||
<http://docs.python-requests.org/>, for a limited time only.
|
||||
Requests is ready for the demands of building robust and reliable HTTP–speaking applications, for the needs of today.
|
||||
|
||||
How to Contribute
|
||||
-----------------
|
||||
- Keep-Alive & Connection Pooling
|
||||
- International Domains and URLs
|
||||
- Sessions with Cookie Persistence
|
||||
- Browser-style TLS/SSL Verification
|
||||
- Basic & Digest Authentication
|
||||
- Familiar `dict`–like Cookies
|
||||
- Automatic Content Decompression and Decoding
|
||||
- Multi-part File Uploads
|
||||
- SOCKS Proxy Support
|
||||
- Connection Timeouts
|
||||
- Streaming Downloads
|
||||
- Automatic honoring of `.netrc`
|
||||
- Chunked HTTP Requests
|
||||
|
||||
1. Check for open issues or open a fresh issue to start a discussion
|
||||
around a feature idea or a bug. There is a [Contributor
|
||||
Friendly](https://github.com/requests/requests/issues?direction=desc&labels=Contributor+Friendly&page=1&sort=updated&state=open)
|
||||
tag for issues that should be ideal for people who are not very
|
||||
familiar with the codebase yet.
|
||||
2. Fork [the repository](https://github.com/requests/requests) on
|
||||
GitHub to start making your changes to the **master** branch (or
|
||||
branch off of it).
|
||||
3. Write a test which shows that the bug was fixed or that the feature
|
||||
works as expected.
|
||||
4. Send a pull request and bug the maintainer until it gets merged and
|
||||
published. :) Make sure to add yourself to
|
||||
[AUTHORS](https://github.com/requests/requests/blob/master/AUTHORS.rst).
|
||||
## API Reference and User Guide available on [Read the Docs](https://requests.readthedocs.io)
|
||||
|
||||
[](https://requests.readthedocs.io)
|
||||
|
||||
## Cloning the repository
|
||||
|
||||
When cloning the Requests repository, you may need to add the `-c
|
||||
fetch.fsck.badTimezone=ignore` flag to avoid an error about a bad commit (see
|
||||
[this issue](https://github.com/psf/requests/issues/2690) for more background):
|
||||
|
||||
```shell
|
||||
git clone -c fetch.fsck.badTimezone=ignore https://github.com/psf/requests.git
|
||||
```
|
||||
|
||||
You can also apply this setting to your global Git config:
|
||||
|
||||
```shell
|
||||
git config --global fetch.fsck.badTimezone ignore
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
[](https://kennethreitz.org) [](https://www.python.org/psf)
|
||||
|
||||
@@ -1,229 +0,0 @@
|
||||
# Sample script to install Python and pip under Windows
|
||||
# Authors: Olivier Grisel, Jonathan Helmus, Kyle Kastner, and Alex Willmer
|
||||
# License: CC0 1.0 Universal: http://creativecommons.org/publicdomain/zero/1.0/
|
||||
|
||||
$MINICONDA_URL = "http://repo.continuum.io/miniconda/"
|
||||
$BASE_URL = "https://www.python.org/ftp/python/"
|
||||
$GET_PIP_URL = "https://bootstrap.pypa.io/get-pip.py"
|
||||
$GET_PIP_PATH = "C:\get-pip.py"
|
||||
|
||||
$PYTHON_PRERELEASE_REGEX = @"
|
||||
(?x)
|
||||
(?<major>\d+)
|
||||
\.
|
||||
(?<minor>\d+)
|
||||
\.
|
||||
(?<micro>\d+)
|
||||
(?<prerelease>[a-z]{1,2}\d+)
|
||||
"@
|
||||
|
||||
|
||||
function Download ($filename, $url) {
|
||||
$webclient = New-Object System.Net.WebClient
|
||||
|
||||
$basedir = $pwd.Path + "\"
|
||||
$filepath = $basedir + $filename
|
||||
if (Test-Path $filename) {
|
||||
Write-Host "Reusing" $filepath
|
||||
return $filepath
|
||||
}
|
||||
|
||||
# Download and retry up to 3 times in case of network transient errors.
|
||||
Write-Host "Downloading" $filename "from" $url
|
||||
$retry_attempts = 2
|
||||
for ($i = 0; $i -lt $retry_attempts; $i++) {
|
||||
try {
|
||||
$webclient.DownloadFile($url, $filepath)
|
||||
break
|
||||
}
|
||||
Catch [Exception]{
|
||||
Start-Sleep 1
|
||||
}
|
||||
}
|
||||
if (Test-Path $filepath) {
|
||||
Write-Host "File saved at" $filepath
|
||||
} else {
|
||||
# Retry once to get the error message if any at the last try
|
||||
$webclient.DownloadFile($url, $filepath)
|
||||
}
|
||||
return $filepath
|
||||
}
|
||||
|
||||
|
||||
function ParsePythonVersion ($python_version) {
|
||||
if ($python_version -match $PYTHON_PRERELEASE_REGEX) {
|
||||
return ([int]$matches.major, [int]$matches.minor, [int]$matches.micro,
|
||||
$matches.prerelease)
|
||||
}
|
||||
$version_obj = [version]$python_version
|
||||
return ($version_obj.major, $version_obj.minor, $version_obj.build, "")
|
||||
}
|
||||
|
||||
|
||||
function DownloadPython ($python_version, $platform_suffix) {
|
||||
$major, $minor, $micro, $prerelease = ParsePythonVersion $python_version
|
||||
|
||||
if (($major -le 2 -and $micro -eq 0) `
|
||||
-or ($major -eq 3 -and $minor -le 2 -and $micro -eq 0) `
|
||||
) {
|
||||
$dir = "$major.$minor"
|
||||
$python_version = "$major.$minor$prerelease"
|
||||
} else {
|
||||
$dir = "$major.$minor.$micro"
|
||||
}
|
||||
|
||||
if ($prerelease) {
|
||||
if (($major -le 2) `
|
||||
-or ($major -eq 3 -and $minor -eq 1) `
|
||||
-or ($major -eq 3 -and $minor -eq 2) `
|
||||
-or ($major -eq 3 -and $minor -eq 3) `
|
||||
) {
|
||||
$dir = "$dir/prev"
|
||||
}
|
||||
}
|
||||
|
||||
if (($major -le 2) -or ($major -le 3 -and $minor -le 4)) {
|
||||
$ext = "msi"
|
||||
if ($platform_suffix) {
|
||||
$platform_suffix = ".$platform_suffix"
|
||||
}
|
||||
} else {
|
||||
$ext = "exe"
|
||||
if ($platform_suffix) {
|
||||
$platform_suffix = "-$platform_suffix"
|
||||
}
|
||||
}
|
||||
|
||||
$filename = "python-$python_version$platform_suffix.$ext"
|
||||
$url = "$BASE_URL$dir/$filename"
|
||||
$filepath = Download $filename $url
|
||||
return $filepath
|
||||
}
|
||||
|
||||
|
||||
function InstallPython ($python_version, $architecture, $python_home) {
|
||||
Write-Host "Installing Python" $python_version "for" $architecture "bit architecture to" $python_home
|
||||
if (Test-Path $python_home) {
|
||||
Write-Host $python_home "already exists, skipping."
|
||||
return $false
|
||||
}
|
||||
if ($architecture -eq "32") {
|
||||
$platform_suffix = ""
|
||||
} else {
|
||||
$platform_suffix = "amd64"
|
||||
}
|
||||
$installer_path = DownloadPython $python_version $platform_suffix
|
||||
$installer_ext = [System.IO.Path]::GetExtension($installer_path)
|
||||
Write-Host "Installing $installer_path to $python_home"
|
||||
$install_log = $python_home + ".log"
|
||||
if ($installer_ext -eq '.msi') {
|
||||
InstallPythonMSI $installer_path $python_home $install_log
|
||||
} else {
|
||||
InstallPythonEXE $installer_path $python_home $install_log
|
||||
}
|
||||
if (Test-Path $python_home) {
|
||||
Write-Host "Python $python_version ($architecture) installation complete"
|
||||
} else {
|
||||
Write-Host "Failed to install Python in $python_home"
|
||||
Get-Content -Path $install_log
|
||||
Exit 1
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function InstallPythonEXE ($exepath, $python_home, $install_log) {
|
||||
$install_args = "/quiet InstallAllUsers=1 TargetDir=$python_home"
|
||||
RunCommand $exepath $install_args
|
||||
}
|
||||
|
||||
|
||||
function InstallPythonMSI ($msipath, $python_home, $install_log) {
|
||||
$install_args = "/qn /log $install_log /i $msipath TARGETDIR=$python_home"
|
||||
$uninstall_args = "/qn /x $msipath"
|
||||
RunCommand "msiexec.exe" $install_args
|
||||
if (-not(Test-Path $python_home)) {
|
||||
Write-Host "Python seems to be installed else-where, reinstalling."
|
||||
RunCommand "msiexec.exe" $uninstall_args
|
||||
RunCommand "msiexec.exe" $install_args
|
||||
}
|
||||
}
|
||||
|
||||
function RunCommand ($command, $command_args) {
|
||||
Write-Host $command $command_args
|
||||
Start-Process -FilePath $command -ArgumentList $command_args -Wait -Passthru
|
||||
}
|
||||
|
||||
|
||||
function InstallPip ($python_home) {
|
||||
$pip_path = $python_home + "\Scripts\pip.exe"
|
||||
$python_path = $python_home + "\python.exe"
|
||||
if (-not(Test-Path $pip_path)) {
|
||||
Write-Host "Installing pip..."
|
||||
$webclient = New-Object System.Net.WebClient
|
||||
$webclient.DownloadFile($GET_PIP_URL, $GET_PIP_PATH)
|
||||
Write-Host "Executing:" $python_path $GET_PIP_PATH
|
||||
& $python_path $GET_PIP_PATH
|
||||
} else {
|
||||
Write-Host "pip already installed."
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function DownloadMiniconda ($python_version, $platform_suffix) {
|
||||
if ($python_version -eq "3.4") {
|
||||
$filename = "Miniconda3-3.5.5-Windows-" + $platform_suffix + ".exe"
|
||||
} else {
|
||||
$filename = "Miniconda-3.5.5-Windows-" + $platform_suffix + ".exe"
|
||||
}
|
||||
$url = $MINICONDA_URL + $filename
|
||||
$filepath = Download $filename $url
|
||||
return $filepath
|
||||
}
|
||||
|
||||
|
||||
function InstallMiniconda ($python_version, $architecture, $python_home) {
|
||||
Write-Host "Installing Python" $python_version "for" $architecture "bit architecture to" $python_home
|
||||
if (Test-Path $python_home) {
|
||||
Write-Host $python_home "already exists, skipping."
|
||||
return $false
|
||||
}
|
||||
if ($architecture -eq "32") {
|
||||
$platform_suffix = "x86"
|
||||
} else {
|
||||
$platform_suffix = "x86_64"
|
||||
}
|
||||
$filepath = DownloadMiniconda $python_version $platform_suffix
|
||||
Write-Host "Installing" $filepath "to" $python_home
|
||||
$install_log = $python_home + ".log"
|
||||
$args = "/S /D=$python_home"
|
||||
Write-Host $filepath $args
|
||||
Start-Process -FilePath $filepath -ArgumentList $args -Wait -Passthru
|
||||
if (Test-Path $python_home) {
|
||||
Write-Host "Python $python_version ($architecture) installation complete"
|
||||
} else {
|
||||
Write-Host "Failed to install Python in $python_home"
|
||||
Get-Content -Path $install_log
|
||||
Exit 1
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function InstallMinicondaPip ($python_home) {
|
||||
$pip_path = $python_home + "\Scripts\pip.exe"
|
||||
$conda_path = $python_home + "\Scripts\conda.exe"
|
||||
if (-not(Test-Path $pip_path)) {
|
||||
Write-Host "Installing pip..."
|
||||
$args = "install --yes pip"
|
||||
Write-Host $conda_path $args
|
||||
Start-Process -FilePath "$conda_path" -ArgumentList $args -Wait -Passthru
|
||||
} else {
|
||||
Write-Host "pip already installed."
|
||||
}
|
||||
}
|
||||
|
||||
function main () {
|
||||
InstallPython $env:PYTHON_VERSION $env:PYTHON_ARCH $env:PYTHON
|
||||
InstallPip $env:PYTHON
|
||||
}
|
||||
|
||||
main
|
||||
57
appveyor.yml
@@ -1,57 +0,0 @@
|
||||
# AppVeyor.yml from https://github.com/ogrisel/python-appveyor-demo
|
||||
# License: CC0 1.0 Universal: https://creativecommons.org/publicdomain/zero/1.0/
|
||||
|
||||
build: off
|
||||
|
||||
environment:
|
||||
matrix:
|
||||
- PYTHON: "C:\\Python27-x64"
|
||||
PYTHON_VERSION: "2.7.x"
|
||||
PYTHON_ARCH: "64"
|
||||
TOXENV: "py27"
|
||||
|
||||
- PYTHON: "C:\\Python34-x64"
|
||||
PYTHON_VERSION: "3.4.x"
|
||||
PYTHON_ARCH: "64"
|
||||
TOXENV: "py34"
|
||||
|
||||
- PYTHON: "C:\\Python35-x64"
|
||||
PYTHON_VERSION: "3.5.x"
|
||||
PYTHON_ARCH: "64"
|
||||
TOXENV: "py35"
|
||||
|
||||
- PYTHON: "C:\\Python36-x64"
|
||||
PYTHON_VERSION: "3.6.x"
|
||||
PYTHON_ARCH: "64"
|
||||
TOXENV: "py36"
|
||||
|
||||
- PYTHON: "C:\\Python37-x64"
|
||||
PYTHON_VERSION: "3.7.x"
|
||||
PYTHON_ARCH: "64"
|
||||
TOXENV: "py37"
|
||||
|
||||
install:
|
||||
# Install Python (from the official .msi of https://www.python.org/) and pip when
|
||||
# not already installed.
|
||||
- ps: if (-not(Test-Path($env:PYTHON))) { & _appveyor\install.ps1 }
|
||||
|
||||
# Prepend newly installed Python to the PATH of this build (this cannot be
|
||||
# done from inside the powershell script as it would require to restart
|
||||
# the parent CMD process).
|
||||
- "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%"
|
||||
|
||||
# Check that we have the expected version and architecture for Python
|
||||
- "python --version"
|
||||
- "python -c \"import struct; print(struct.calcsize('P') * 8)\""
|
||||
|
||||
# Upgrade to the latest version of pip to avoid it displaying warnings
|
||||
# about it being out of date.
|
||||
- "python -m pip install --upgrade pip wheel"
|
||||
- "C:\\MinGW\\bin\\mingw32-make"
|
||||
- "pipenv install -e .[socks] --skip-lock"
|
||||
|
||||
test_script:
|
||||
- "C:\\MinGW\\bin\\mingw32-make coverage"
|
||||
|
||||
on_success:
|
||||
- "pipenv run codecov -f coverage.xml"
|
||||
1
docs/.nojekyll
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
45
docs/_static/custom.css
vendored
@@ -50,29 +50,21 @@ body > div.document > div.sphinxsidebar > div > form > table > tbody > tr:nth-ch
|
||||
|
||||
/* Native CPC by BuySellAds */
|
||||
|
||||
.native-js {
|
||||
visibility: hidden;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
|
||||
Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", Helvetica, Arial,
|
||||
sans-serif;
|
||||
opacity: 0;
|
||||
#native-ribbon #_custom_ {
|
||||
position: fixed;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
box-shadow: 0 -1px 4px 1px hsla(0, 0%, 0%, .15);
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu,
|
||||
Cantarell, "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
transition: all .25s ease-in-out;
|
||||
transform: translateY(calc(100% - 35px));
|
||||
|
||||
flex-flow: column nowrap;
|
||||
}
|
||||
|
||||
.native-js[data-state=visible] {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
visibility: visible;
|
||||
box-shadow: 0 -1px 4px 1px hsla(0, 0%, 0%, .15);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.native-js[data-state=visible]:hover {
|
||||
#native-ribbon #_custom_:hover {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
@@ -92,7 +84,7 @@ body > div.document > div.sphinxsidebar > div > form > table > tbody > tr:nth-ch
|
||||
transform-origin: left;
|
||||
}
|
||||
|
||||
.native-js[data-state=visible]:hover .native-sponsor {
|
||||
#native-ribbon #_custom_:hover .native-sponsor {
|
||||
margin: 0 20px;
|
||||
opacity: 0;
|
||||
transform: scaleY(0);
|
||||
@@ -100,17 +92,14 @@ body > div.document > div.sphinxsidebar > div > form > table > tbody > tr:nth-ch
|
||||
|
||||
.native-flex {
|
||||
display: flex;
|
||||
padding: 0 20px 30px;
|
||||
padding: 10px 20px 25px;
|
||||
text-decoration: none;
|
||||
|
||||
flex-flow: row nowrap;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.native-flex:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.native-main {
|
||||
display: flex;
|
||||
|
||||
@@ -135,6 +124,7 @@ body > div.document > div.sphinxsidebar > div > form > table > tbody > tr:nth-ch
|
||||
.native-desc {
|
||||
letter-spacing: 1px;
|
||||
font-weight: 300;
|
||||
font-size: 14px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
@@ -158,6 +148,7 @@ body > div.document > div.sphinxsidebar > div > form > table > tbody > tr:nth-ch
|
||||
|
||||
@media only screen and (min-width: 320px) and (max-width: 759px) {
|
||||
.native-flex {
|
||||
padding: 5px 5px 15px;
|
||||
flex-direction: column;
|
||||
|
||||
flex-wrap: wrap;
|
||||
@@ -165,6 +156,7 @@ body > div.document > div.sphinxsidebar > div > form > table > tbody > tr:nth-ch
|
||||
|
||||
.native-img {
|
||||
margin: 0;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.native-details {
|
||||
@@ -173,10 +165,13 @@ body > div.document > div.sphinxsidebar > div > form > table > tbody > tr:nth-ch
|
||||
|
||||
.native-main {
|
||||
flex-direction: column;
|
||||
margin-bottom: 20px;
|
||||
text-align: center;
|
||||
text-align: left;
|
||||
|
||||
flex-wrap: wrap;
|
||||
align-content: center;
|
||||
}
|
||||
|
||||
.native-cta {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
116
docs/_static/konami.js
vendored
@@ -1,116 +0,0 @@
|
||||
/*
|
||||
* Konami-JS ~
|
||||
* :: Now with support for touch events and multiple instances for
|
||||
* :: those situations that call for multiple easter eggs!
|
||||
* Code: http://konami-js.googlecode.com/
|
||||
* Examples: http://www.snaptortoise.com/konami-js
|
||||
* Copyright (c) 2009 George Mandis (georgemandis.com, snaptortoise.com)
|
||||
* Version: 1.4.2 (9/2/2013)
|
||||
* Licensed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
* Tested in: Safari 4+, Google Chrome 4+, Firefox 3+, IE7+, Mobile Safari 2.2.1 and Dolphin Browser
|
||||
*/
|
||||
|
||||
var Konami = function (callback) {
|
||||
var konami = {
|
||||
addEvent: function (obj, type, fn, ref_obj) {
|
||||
if (obj.addEventListener)
|
||||
obj.addEventListener(type, fn, false);
|
||||
else if (obj.attachEvent) {
|
||||
// IE
|
||||
obj["e" + type + fn] = fn;
|
||||
obj[type + fn] = function () {
|
||||
obj["e" + type + fn](window.event, ref_obj);
|
||||
};
|
||||
obj.attachEvent("on" + type, obj[type + fn]);
|
||||
}
|
||||
},
|
||||
input: "",
|
||||
pattern: "38384040373937396665",
|
||||
load: function (link) {
|
||||
this.addEvent(document, "keydown", function (e, ref_obj) {
|
||||
if (ref_obj) konami = ref_obj; // IE
|
||||
konami.input += e ? e.keyCode : event.keyCode;
|
||||
if (konami.input.length > konami.pattern.length)
|
||||
konami.input = konami.input.substr((konami.input.length - konami.pattern.length));
|
||||
if (konami.input == konami.pattern) {
|
||||
konami.code(link);
|
||||
konami.input = "";
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
}, this);
|
||||
this.iphone.load(link);
|
||||
},
|
||||
code: function (link) {
|
||||
window.location = link
|
||||
},
|
||||
iphone: {
|
||||
start_x: 0,
|
||||
start_y: 0,
|
||||
stop_x: 0,
|
||||
stop_y: 0,
|
||||
tapTolerance: 8,
|
||||
capture: false,
|
||||
orig_keys: "",
|
||||
keys: ["UP", "UP", "DOWN", "DOWN", "LEFT", "RIGHT", "LEFT", "RIGHT", "TAP", "TAP"],
|
||||
code: function (link) {
|
||||
konami.code(link);
|
||||
},
|
||||
touchCapture: function(evt) {
|
||||
konami.iphone.start_x = evt.changedTouches[0].pageX;
|
||||
konami.iphone.start_y = evt.changedTouches[0].pageY;
|
||||
konami.iphone.capture = true;
|
||||
},
|
||||
load: function (link) {
|
||||
this.orig_keys = this.keys;
|
||||
konami.addEvent(document, "touchmove", function (e) {
|
||||
if (e.touches.length == 1 && konami.iphone.capture == true) {
|
||||
var touch = e.touches[0];
|
||||
konami.iphone.stop_x = touch.pageX;
|
||||
konami.iphone.stop_y = touch.pageY;
|
||||
konami.iphone.check_direction();
|
||||
}
|
||||
});
|
||||
konami.addEvent(document, "touchend", function (evt) {
|
||||
konami.touchCapture(evt);
|
||||
konami.iphone.check_direction(link);
|
||||
}, false);
|
||||
konami.addEvent(document, "touchstart", function (evt) {
|
||||
konami.touchCapture(evt);
|
||||
});
|
||||
},
|
||||
check_direction: function (link) {
|
||||
var x_magnitude = Math.abs(this.start_x - this.stop_x);
|
||||
var y_magnitude = Math.abs(this.start_y - this.stop_y);
|
||||
var hasMoved = (x_magnitude > this.tapTolerance || y_magnitude > this.tapTolerance);
|
||||
var result;
|
||||
if (this.capture === true && hasMoved) {
|
||||
this.capture = false;
|
||||
var x = ((this.start_x - this.stop_x) < 0) ? "RIGHT" : "LEFT";
|
||||
var y = ((this.start_y - this.stop_y) < 0) ? "DOWN" : "UP";
|
||||
var result = (x_magnitude > y_magnitude) ? x : y;
|
||||
}
|
||||
else if (this.capture === false && !hasMoved) {
|
||||
result = (this.tap == true) ? "TAP" : result;
|
||||
result = "TAP";
|
||||
}
|
||||
if (result) {
|
||||
if (result == this.keys[0]) this.keys = this.keys.slice(1, this.keys.length);
|
||||
else this.keys = this.orig_keys;
|
||||
}
|
||||
if (this.keys.length == 0) {
|
||||
this.keys = this.orig_keys;
|
||||
this.code(link);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typeof callback === "string" && konami.load(callback);
|
||||
if (typeof callback === "function") {
|
||||
konami.code = callback;
|
||||
konami.load();
|
||||
}
|
||||
|
||||
return konami;
|
||||
};
|
||||
131
docs/_static/native.js
vendored
@@ -1,131 +0,0 @@
|
||||
var _native = (function () {
|
||||
var _options = {}
|
||||
var _construct = function (e) {
|
||||
var defaultOptions = {
|
||||
carbonZoneKey: '',
|
||||
fallback: '',
|
||||
ignore: 'false',
|
||||
placement: '',
|
||||
prefix: 'native',
|
||||
targetClass: 'native-ad'
|
||||
}
|
||||
|
||||
if (typeof e === 'undefined') return defaultOptions
|
||||
Object.keys(defaultOptions).forEach((key, index) => {
|
||||
if (typeof e[key] === 'undefined') {
|
||||
e[key] = defaultOptions[key]
|
||||
}
|
||||
})
|
||||
return e
|
||||
}
|
||||
|
||||
var init = function (zone, options) {
|
||||
_options = _construct(options)
|
||||
|
||||
let jsonUrl = `https://srv.buysellads.com/ads/${zone}.json?callback=_native_go`
|
||||
if (_options['placement'] !== '') {
|
||||
jsonUrl += '&segment=placement:' + _options['placement']
|
||||
}
|
||||
if (_options['ignore'] === 'true') {
|
||||
jsonUrl += '&ignore=yes'
|
||||
}
|
||||
|
||||
let srv = document.createElement('script')
|
||||
srv.src = jsonUrl
|
||||
document.getElementsByTagName('head')[0].appendChild(srv)
|
||||
}
|
||||
|
||||
var carbon = function (e) {
|
||||
let srv = document.createElement('script')
|
||||
srv.src = '//cdn.carbonads.com/carbon.js?serve=' + e['carbonZoneKey'] + '&placement=' + e['placement']
|
||||
srv.id = '_carbonads_js'
|
||||
|
||||
return srv
|
||||
}
|
||||
|
||||
var sanitize = function (ads) {
|
||||
return ads
|
||||
.filter(ad => {
|
||||
return Object.keys(ad).length > 0
|
||||
})
|
||||
.filter(ad => {
|
||||
return ad.hasOwnProperty('statlink')
|
||||
})
|
||||
}
|
||||
|
||||
var pixel = function (p, timestamp) {
|
||||
let c = ''
|
||||
if (p) {
|
||||
p.split('||').forEach((pixel, index) => {
|
||||
c += `<img src="${pixel.replace('[timestamp]', timestamp)}" style="display:none;" height="0" width="0" />`
|
||||
})
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
var options = function () {
|
||||
return _options
|
||||
}
|
||||
|
||||
return {
|
||||
carbon: carbon,
|
||||
init: init,
|
||||
options: options,
|
||||
pixel: pixel,
|
||||
sanitize: sanitize
|
||||
}
|
||||
})({})
|
||||
|
||||
var _native_go = function (json) {
|
||||
let options = _native.options()
|
||||
let ads = _native.sanitize(json['ads'])
|
||||
let selectedClass = document.querySelectorAll('.' + options['targetClass'])
|
||||
|
||||
if (ads.length < 1) {
|
||||
selectedClass.forEach((className, index) => {
|
||||
let selectedTarget = document.getElementsByClassName(options['targetClass'])[index]
|
||||
|
||||
if (options['fallback'] !== '' || options['carbonZoneKey'] !== '') selectedTarget.setAttribute('data-state', 'visible')
|
||||
selectedTarget.innerHTML = options['fallback']
|
||||
if (options['carbonZoneKey'] !== '') selectedTarget.appendChild(_native.carbon(options))
|
||||
})
|
||||
|
||||
// End at this line if no ads are found, avoiding unnecessary steps
|
||||
return
|
||||
}
|
||||
|
||||
selectedClass.forEach((className, index) => {
|
||||
let selectedTarget = document.getElementsByClassName(options['targetClass'])[index]
|
||||
let adElement = selectedTarget.innerHTML
|
||||
let prefix = options['prefix']
|
||||
let ad = ads[index]
|
||||
|
||||
if (ad && className) {
|
||||
let adInnerHtml = adElement
|
||||
.replace(new RegExp('#' + prefix + '_bg_color#', 'g'), ad['backgroundColor'])
|
||||
.replace(new RegExp('#' + prefix + '_bg_color_hover#', 'g'), ad['backgroundHoverColor'])
|
||||
.replace(new RegExp('#' + prefix + '_company#', 'g'), ad['company'])
|
||||
.replace(new RegExp('#' + prefix + '_cta#', 'g'), ad['callToAction'])
|
||||
.replace(new RegExp('#' + prefix + '_cta_bg_color#', 'g'), ad['ctaBackgroundColor'])
|
||||
.replace(new RegExp('#' + prefix + '_cta_bg_color_hover#', 'g'), ad['ctaBackgroundHoverColor'])
|
||||
.replace(new RegExp('#' + prefix + '_cta_color#', 'g'), ad['ctaTextColor'])
|
||||
.replace(new RegExp('#' + prefix + '_cta_color_hover#', 'g'), ad['ctaTextColorHover'])
|
||||
.replace(new RegExp('#' + prefix + '_desc#', 'g'), ad['description'])
|
||||
.replace(new RegExp('#' + prefix + '_index#', 'g'), prefix + '-' + ad['i'])
|
||||
.replace(new RegExp('#' + prefix + '_img#', 'g'), ad['image'])
|
||||
.replace(new RegExp('#' + prefix + '_small_img#', 'g'), ad['smallImage'])
|
||||
.replace(new RegExp('#' + prefix + '_link#', 'g'), ad['statlink'])
|
||||
.replace(new RegExp('#' + prefix + '_logo#', 'g'), ad['logo'])
|
||||
.replace(new RegExp('#' + prefix + '_color#', 'g'), ad['textColor'])
|
||||
.replace(new RegExp('#' + prefix + '_color_hover#', 'g'), ad['textColorHover'])
|
||||
.replace(new RegExp('#' + prefix + '_title#', 'g'), ad['title'])
|
||||
|
||||
selectedTarget.innerHTML = null
|
||||
selectedTarget.innerHTML += adInnerHtml + _native.pixel(ad['pixel'], ad['timestamp'])
|
||||
selectedTarget.setAttribute('data-state', 'visible')
|
||||
} else {
|
||||
selectedTarget.innerHTML = null
|
||||
selectedTarget.style.display = 'none'
|
||||
}
|
||||
})
|
||||
}
|
||||
BIN
docs/_static/requests-logo-small.png
vendored
|
Before Width: | Height: | Size: 155 KiB |
BIN
docs/_static/requests-sidebar.png
vendored
|
Before Width: | Height: | Size: 299 KiB |
99
docs/_templates/hacks.html
vendored
@@ -23,81 +23,58 @@
|
||||
/* Have code blocks escape the document right-margin. */
|
||||
div.highlight pre {margin-right: -30px;}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
|
||||
<!-- Analytics tracking for Kenneth. -->
|
||||
<script type="text/javascript">
|
||||
var _gauges = _gauges || [];
|
||||
(function() {
|
||||
var t = document.createElement('script');
|
||||
t.type = 'text/javascript';
|
||||
t.async = true;
|
||||
t.id = 'gauges-tracker';
|
||||
t.setAttribute('data-site-id', '56ca7a57c88d9011080024dd');
|
||||
t.setAttribute('data-track-path', 'https://track.gaug.es/track.gif');
|
||||
t.src = 'https://d36ee2fcip1434.cloudfront.net/track.js';
|
||||
var s = document.getElementsByTagName('script')[0];
|
||||
s.parentNode.insertBefore(t, s);
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
<!-- There are no more hacks. -->
|
||||
<!-- இڿڰۣ-ڰۣ— -->
|
||||
<!-- Love, Kenneth Reitz -->
|
||||
|
||||
<script src="{{ pathto('_static/', 1) }}/konami.js"></script>
|
||||
<script>
|
||||
var easter_egg = new Konami('http://fortunes.herokuapp.com/random/raw');
|
||||
</script>
|
||||
|
||||
<!-- That was not a hack. That was art. -->
|
||||
|
||||
<!-- Native CPC by BuySellAds -->
|
||||
|
||||
<script src="{{ pathto('_static/', 1) }}/native.js"></script>
|
||||
<script type="text/javascript" src="//m.servedby-buysellads.com/monetization.js"></script>
|
||||
|
||||
<div id="native-ribbon">
|
||||
</div>
|
||||
|
||||
<script>
|
||||
_native.init("CK7D62JU", {
|
||||
targetClass: 'native-js'
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="native-js">
|
||||
<div class="native-sponsor">Sponsored Ad by #native_company# — Learn More</div>
|
||||
<a href="#native_link#" class="native-flex">
|
||||
_bsa.init('custom', 'CK7D62JU', 'placement:pythonrequestsorg',
|
||||
{
|
||||
target: '#native-ribbon',
|
||||
template: `
|
||||
<div class="native-sponsor">Sponsored by ##company## — Learn More</div>
|
||||
<a href="##link##" class="native-flex">
|
||||
<style>
|
||||
.native-js {
|
||||
background: linear-gradient(-30deg, #native_bg_color#E5, #native_bg_color#E5 45%, #native_bg_color# 45%) #fff;
|
||||
}
|
||||
#native-ribbon #_custom_ {
|
||||
background: linear-gradient(-30deg, ##backgroundColor##E5, ##backgroundColor##E5 45%, ##backgroundColor## 45%) #fff;
|
||||
}
|
||||
|
||||
.native-details,
|
||||
.native-sponsor {
|
||||
color: #native_color# !important;
|
||||
}
|
||||
.native-details,
|
||||
.native-sponsor,
|
||||
.native-bsa {
|
||||
color: ##textColor## !important;
|
||||
}
|
||||
|
||||
.native-details:hover {
|
||||
color: #native_color_hover# !important;
|
||||
}
|
||||
.native-details:hover {
|
||||
color: ##textColorHover## !important;
|
||||
}
|
||||
|
||||
.native-cta {
|
||||
color: #native_cta_color#;
|
||||
background-color: #native_cta_bg_color#;
|
||||
}
|
||||
.native-cta {
|
||||
color: ##ctaTextColor##;
|
||||
background-color: ##ctaBackgroundColor##;
|
||||
}
|
||||
|
||||
.native-cta:hover {
|
||||
color: #native_cta_color_hover;
|
||||
background-color: #native_cta_bg_color_hover#;
|
||||
}
|
||||
.native-cta:hover {
|
||||
color: ##ctaTextColorHover##;
|
||||
background-color: ##ctaBackgroundColorHover##;
|
||||
}
|
||||
</style>
|
||||
<div class="native-main">
|
||||
<img class="native-img" src="#native_logo#">
|
||||
<img class="native-img" src="##logo##">
|
||||
<div class="native-details">
|
||||
<span class="native-company">#native_title#</span>
|
||||
<span class="native-desc">#native_desc#</span>
|
||||
<span class="native-company">##title##</span>
|
||||
<span class="native-desc">##description##</span>
|
||||
</div>
|
||||
<span class="native-cta">#native_cta#</span>
|
||||
</div>
|
||||
<span class="native-cta">##callToAction##</span>
|
||||
</a>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
132
docs/_templates/sidebarintro.html
vendored
@@ -1,109 +1,73 @@
|
||||
<p class="logo">
|
||||
<a href="{{ pathto(master_doc) }}">
|
||||
<img class="logo" src="{{ pathto('_static/requests-sidebar.png', 1) }}" title="https://kennethreitz.org/tattoos"/>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<iframe src="https://ghbtns.com/github-btn.html?user=requests&repo=requests&type=watch&count=true&size=large"
|
||||
<iframe src="https://ghbtns.com/github-btn.html?user=psf&repo=requests&type=watch&count=true&size=large"
|
||||
allowtransparency="true" frameborder="0" scrolling="0" width="200px" height="35px"></iframe>
|
||||
</p>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.css" />
|
||||
<style>
|
||||
.algolia-autocomplete {
|
||||
width: 100%;
|
||||
height: 1.5em
|
||||
}
|
||||
|
||||
.algolia-autocomplete a {
|
||||
border-bottom: none !important;
|
||||
}
|
||||
|
||||
#doc_search {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
<input id="doc_search" placeholder="Search the doc" autofocus />
|
||||
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.js" onload="docsearch({
|
||||
apiKey: 'f177061e2354c50a97bfc635e827ffab',
|
||||
indexName: 'python-requests',
|
||||
inputSelector: '#doc_search',
|
||||
debug: false // Set debug to true if you want to inspect the dropdown
|
||||
})" async></script>
|
||||
|
||||
<p>
|
||||
Requests is an elegant and simple HTTP library for Python, built for
|
||||
human beings.
|
||||
</p>
|
||||
<p>Sponsored by <strong><a href="https://linode.com/">Linode</a></strong> and <a href="http://docs.python-requests.org/en/master/community/sponsors/#patron-sponsors">other wonderful organizations</a>.</p>
|
||||
|
||||
|
||||
<script async type="text/javascript" src="//cdn.carbonads.com/carbon.js?zoneid=1673&serve=CKYI5K3E&placement=pythonrequestsorg" id="_carbonads_js"></script>
|
||||
|
||||
<h3>Stay Informed</h3>
|
||||
<p>Receive updates on new releases and upcoming projects.</p>
|
||||
|
||||
<p><iframe src="https://ghbtns.com/github-btn.html?user=kennethreitz&type=follow&count=false"
|
||||
allowtransparency="true" frameborder="0" scrolling="0" width="200" height="20"></iframe></p>
|
||||
|
||||
<p><a href="https://twitter.com/kennethreitz" class="twitter-follow-button" data-show-count="false">Follow @kennethreitz</a> <script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script></p>
|
||||
<p><a href="https://tinyletter.com/kennethreitz">Join Mailing List</a>.</p>
|
||||
<h3>Other Projects</h3>
|
||||
|
||||
<p>More <a href="https://www.kennethreitz.org/">Kenneth Reitz</a> projects:</p>
|
||||
<ul>
|
||||
<li><a href="https://html.python-requests.org/">Requests-HTML</a></li>
|
||||
<li><a href="http://howtopython.org/">howtopython.org</a></li>
|
||||
<li><a href="http://pipenv.org/">pipenv</a></li>
|
||||
<li><a href="https://pep8.org/">pep8.org</a></li>
|
||||
<li><a href="https://httpbin.org/">httpbin.org</a></li>
|
||||
<li><a href="https://docs.python-guide.org/">The Python Guide</a></li>
|
||||
<li><a href="https://github.com/kennethreitz/maya">Maya: Datetimes for Humans</a></li>
|
||||
<li><a href="https://github.com/kennethreitz/records">Records: SQL for Humans</a></li>
|
||||
<li><a href="http://www.git-legit.org">Legit: Git for Humans</a></li>
|
||||
<li><a href="http://docs.python-tablib.org/en/latest/">Tablib: Tabular Datasets</a></li>
|
||||
</ul>
|
||||
<p>Sponsored by <strong><a href="https://www.govcert.lu">CERT Gouvernemental - GOVCERT.LU</a></strong>.</p>
|
||||
|
||||
<script async type="text/javascript"
|
||||
src="//cdn.carbonads.com/carbon.js?zoneid=1673&serve=CKYI5K3E&placement=pythonrequestsorg"
|
||||
id="_carbonads_js"></script>
|
||||
|
||||
<h3>Useful Links</h3>
|
||||
<ul>
|
||||
<li><a href="http://docs.python-requests.org/en/latest/community/recommended/">Recommended Packages and Extensions</a></li>
|
||||
<li><a href="https://requests.readthedocs.io/en/latest/user/quickstart/">Quickstart</a></li>
|
||||
<li><a href="https://requests.readthedocs.io/en/latest/user/advanced/">Advanced Usage</a></li>
|
||||
<li><a href="https://requests.readthedocs.io/en/latest/api/">API Reference</a></li>
|
||||
<li><a href="https://requests.readthedocs.io/en/latest/community/updates/#release-history">Release History</a></li>
|
||||
<li><a href="https://requests.readthedocs.io/en/latest/dev/contributing/">Contributors Guide</a></li>
|
||||
|
||||
<p></p>
|
||||
|
||||
<li><a href="https://github.com/requests/requests">Requests @ GitHub</a></li>
|
||||
<li><a href="https://requests.readthedocs.io/en/latest/community/recommended/">Recommended Packages and Extensions</a></li>
|
||||
|
||||
<p></p>
|
||||
|
||||
<li><a href="https://github.com/psf/requests">Requests @ GitHub</a></li>
|
||||
<li><a href="https://pypi.org/project/requests/">Requests @ PyPI</a></li>
|
||||
<li><a href="https://github.com/requests/requests/issues">Issue Tracker</a></li>
|
||||
<li><a href="http://docs.python-requests.org/en/latest/community/updates/#software-updates">Release History</a></li>
|
||||
<li><a href="https://github.com/psf/requests/issues">Issue Tracker</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h3>Translations</h3>
|
||||
|
||||
<ul>
|
||||
<li><a href="http://docs.python-requests.org/">English</a></li>
|
||||
<li><a href="http://fr.python-requests.org/">French</a></li>
|
||||
<li><a href="http://de.python-requests.org/">German</a></li>
|
||||
<li><a href="http://jp.python-requests.org/">Japanese</a></li>
|
||||
<li><a href="http://cn.python-requests.org/">Chinese</a></li>
|
||||
<li><a href="http://pt.python-requests.org/">Portuguese</a></li>
|
||||
<li><a href="http://it.python-requests.org/">Italian</a></li>
|
||||
<li><a href="http://es.python-requests.org/">Spanish</a></li>
|
||||
<li><a href="https://requests.readthedocs.io/">English</a></li>
|
||||
<li><a href="https://fr.python-requests.org/">French</a></li>
|
||||
<li><a href="https://de.python-requests.org/">German</a></li>
|
||||
<li><a href="https://jp.python-requests.org/">Japanese</a></li>
|
||||
<li><a href="https://cn.python-requests.org/">Chinese</a></li>
|
||||
<li><a href="https://pt.python-requests.org/">Portuguese</a></li>
|
||||
<li><a href="https://it.python-requests.org/">Italian</a></li>
|
||||
<li><a href="https://es.python-requests.org/">Spanish</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="native-js">
|
||||
<div class="native-sponsor">Sponsored by #native_company# — Learn More</div>
|
||||
<a href="#native_link#" class="native-flex">
|
||||
<style>
|
||||
.native-js {
|
||||
background: linear-gradient(-30deg, #native_bg_color#E5, #native_bg_color#E5 45%, #native_bg_color# 45%) #fff;
|
||||
}
|
||||
|
||||
.native-details,
|
||||
.native-sponsor,
|
||||
.native-bsa {
|
||||
color: #native_color# !important;
|
||||
}
|
||||
|
||||
.native-details:hover {
|
||||
color: #native_color_hover# !important;
|
||||
}
|
||||
|
||||
.native-cta {
|
||||
color: #native_cta_color#;
|
||||
background-color: #native_cta_bg_color#;
|
||||
}
|
||||
|
||||
.native-cta:hover {
|
||||
color: #native_cta_color_hover;
|
||||
background-color: #native_cta_bg_color_hover#;
|
||||
}
|
||||
</style>
|
||||
<div class="native-main">
|
||||
<img class="native-img" src="#native_logo#">
|
||||
<div class="native-details">
|
||||
<span class="native-company">#native_title#</span>
|
||||
<span class="native-desc">#native_desc#</span>
|
||||
</div>
|
||||
</div>
|
||||
<span class="native-cta">#native_cta#</span>
|
||||
</a>
|
||||
<div id="native-ribbon">
|
||||
</div>
|
||||
|
||||
102
docs/_templates/sidebarlogo.html
vendored
@@ -1,13 +1,30 @@
|
||||
<p class="logo">
|
||||
<a href="{{ pathto(master_doc) }}">
|
||||
<img class="logo" src="{{ pathto('_static/requests-sidebar.png', 1) }}" title="https://kennethreitz.org/tattoos"/>
|
||||
</a>
|
||||
</p>
|
||||
<p>
|
||||
<iframe src="https://ghbtns.com/github-btn.html?user=requests&repo=requests&type=watch&count=true&size=large"
|
||||
allowtransparency="true" frameborder="0" scrolling="0" width="200px" height="35px"></iframe>
|
||||
<iframe src="https://ghbtns.com/github-btn.html?user=psf&repo=requests&type=watch&count=true&size=large"
|
||||
allowtransparency="true" frameborder="0" scrolling="0" width="200px" height="35px"></iframe>
|
||||
</p>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.css" />
|
||||
<style>
|
||||
.algolia-autocomplete {
|
||||
width: 100%;
|
||||
height: 1.5em
|
||||
}
|
||||
|
||||
.algolia-autocomplete a {
|
||||
border-bottom: none !important;
|
||||
}
|
||||
|
||||
#doc_search {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
<input id="doc_search" placeholder="Search the doc" autofocus />
|
||||
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.js" onload="docsearch({
|
||||
apiKey: 'f177061e2354c50a97bfc635e827ffab',
|
||||
indexName: 'python-requests',
|
||||
inputSelector: '#doc_search',
|
||||
debug: false // Set debug to true if you want to inspect the dropdown
|
||||
})" async></script>
|
||||
|
||||
<p>
|
||||
Requests is an elegant and simple HTTP library for Python, built for
|
||||
@@ -15,49 +32,40 @@
|
||||
development release.
|
||||
</p>
|
||||
|
||||
<p>Sponsored by <strong><a href="https://linode.com/">Linode</a></strong> and <a href="http://docs.python-requests.org/en/master/community/sponsors/#patron-sponsors">other wonderful organizations</a>.</p>
|
||||
<p>Sponsored by <strong><a href="https://www.govcert.lu">CERT Gouvernemental - GOVCERT.LU</a></strong>.</p>
|
||||
|
||||
<h3>Stay Informed</h3>
|
||||
<p>Receive updates on new releases and upcoming projects.</p>
|
||||
<script async type="text/javascript"
|
||||
src="//cdn.carbonads.com/carbon.js?zoneid=1673&serve=C6AILKT&placement=pythonrequestsorg"
|
||||
id="_carbonads_js"></script>
|
||||
|
||||
<p><a href="https://tinyletter.com/kennethreitz">Join Mailing List</a>.</p>
|
||||
|
||||
<hr/>
|
||||
|
||||
<script async type="text/javascript" src="//cdn.carbonads.com/carbon.js?zoneid=1673&serve=C6AILKT&placement=pythonrequestsorg" id="_carbonads_js"></script>
|
||||
|
||||
<p><iframe src="https://ghbtns.com/github-btn.html?user=kennethreitz&type=follow&count=false"
|
||||
allowtransparency="true" frameborder="0" scrolling="0" width="200" height="20"></iframe></p>
|
||||
|
||||
<p><a href="https://twitter.com/kennethreitz" class="twitter-follow-button" data-show-count="false">Follow @kennethreitz</a> <script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script></p>
|
||||
|
||||
|
||||
<h3>Other Projects</h3>
|
||||
|
||||
<p>More <a href="https://www.kennethreitz.org/">Kenneth Reitz</a> projects:</p>
|
||||
<h3>Useful Links</h3>
|
||||
<ul>
|
||||
<li><a href="https://html.python-requests.org/">Requests-HTML</a></li>
|
||||
<li><a href="http://howtopython.org/">howtopython.org</a></li>
|
||||
<li><a href="http://pipenv.org/">pipenv</a></li>
|
||||
<li><a href="https://pep8.org/">pep8.org</a></li>
|
||||
<li><a href="https://httpbin.org/">httpbin.org</a></li>
|
||||
<li><a href="https://docs.python-guide.org/">The Python Guide</a></li>
|
||||
<li><a href="https://github.com/kennethreitz/maya">Maya: Datetimes for Humans</a></li>
|
||||
<li><a href="https://github.com/kennethreitz/records">Records: SQL for Humans</a></li>
|
||||
<li><a href="http://www.git-legit.org">Legit: Git for Humans</a></li>
|
||||
<li><a href="http://docs.python-tablib.org/en/latest/">Tablib: Tabular Datasets</a></li>
|
||||
<li><a href="https://requests.readthedocs.io/en/latest/user/quickstart/">Quickstart</a></li>
|
||||
<li><a href="https://requests.readthedocs.io/en/latest/user/advanced/">Advanced Usage</a></li>
|
||||
<li><a href="https://requests.readthedocs.io/en/latest/api/">API Reference</a></li>
|
||||
<li><a href="https://requests.readthedocs.io/en/latest/community/updates/#release-history">Release History</a></li>
|
||||
<li><a href="https://requests.readthedocs.io/en/latest/dev/contributing/">Contributors Guide</a></li>
|
||||
|
||||
<p></p>
|
||||
|
||||
<li><a href="https://requests.readthedocs.io/en/latest/community/recommended/">Recommended Packages and Extensions</a></li>
|
||||
|
||||
<p></p>
|
||||
|
||||
<li><a href="https://github.com/psf/requests">Requests @ GitHub</a></li>
|
||||
<li><a href="https://pypi.org/project/requests/">Requests @ PyPI</a></li>
|
||||
<li><a href="https://github.com/psf/requests/issues">Issue Tracker</a></li>
|
||||
</ul>
|
||||
|
||||
<h3>Translations</h3>
|
||||
|
||||
<h3>Translations</h3>
|
||||
|
||||
<ul>
|
||||
<li><a href="http://docs.python-requests.org/">English</a></li>
|
||||
<li><a href="http://fr.python-requests.org/">French</a></li>
|
||||
<li><a href="http://de.python-requests.org/">German</a></li>
|
||||
<li><a href="http://jp.python-requests.org/">Japanese</a></li>
|
||||
<li><a href="http://cn.python-requests.org/">Chinese</a></li>
|
||||
<li><a href="http://pt.python-requests.org/">Portuguese</a></li>
|
||||
<li><a href="http://it.python-requests.org/">Italian</a></li>
|
||||
<li><a href="http://es.python-requests.org/">Spanish</a></li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a href="https://requests.readthedocs.io/">English</a></li>
|
||||
<li><a href="https://fr.python-requests.org/">French</a></li>
|
||||
<li><a href="https://de.python-requests.org/">German</a></li>
|
||||
<li><a href="https://jp.python-requests.org/">Japanese</a></li>
|
||||
<li><a href="https://cn.python-requests.org/">Chinese</a></li>
|
||||
<li><a href="https://pt.python-requests.org/">Portuguese</a></li>
|
||||
<li><a href="https://it.python-requests.org/">Italian</a></li>
|
||||
<li><a href="https://es.python-requests.org/">Spanish</a></li>
|
||||
</ul>
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
Frequently Asked Questions
|
||||
==========================
|
||||
|
||||
.. image:: https://farm5.staticflickr.com/4290/35294660055_42c02b2316_k_d.jpg
|
||||
|
||||
This part of the documentation answers common questions about Requests.
|
||||
|
||||
Encoded Data?
|
||||
@@ -13,6 +11,9 @@ Encoded Data?
|
||||
Requests automatically decompresses gzip-encoded responses, and does
|
||||
its best to decode response content to unicode when possible.
|
||||
|
||||
When either the `brotli <https://pypi.org/project/Brotli/>`_ or `brotlicffi <https://pypi.org/project/brotlicffi/>`_
|
||||
package is installed, requests also decodes Brotli-encoded responses.
|
||||
|
||||
You can get direct access to the raw response (and even the socket),
|
||||
if needed as well.
|
||||
|
||||
@@ -21,7 +22,8 @@ Custom User-Agents?
|
||||
-------------------
|
||||
|
||||
Requests allows you to easily override User-Agent strings, along with
|
||||
any other HTTP Header.
|
||||
any other HTTP Header. See `documentation about headers <https://requests.readthedocs.io/en/master/user/quickstart/#custom-headers>`_.
|
||||
|
||||
|
||||
|
||||
Why not Httplib2?
|
||||
@@ -53,15 +55,20 @@ Chris Adams gave an excellent summary on
|
||||
Python 3 Support?
|
||||
-----------------
|
||||
|
||||
Yes! Here's a list of Python platforms that are officially
|
||||
supported:
|
||||
Yes! Requests officially supports Python 2.7 & 3.6+ and PyPy.
|
||||
|
||||
* Python 2.7
|
||||
* Python 3.4
|
||||
* Python 3.5
|
||||
* Python 3.6
|
||||
* Python 3.7
|
||||
* PyPy
|
||||
Python 2 Support?
|
||||
-----------------
|
||||
|
||||
Yes! We do not have immediate plans to `sunset
|
||||
<https://www.python.org/doc/sunset-python-2/>`_ our support for Python
|
||||
2.7. We understand that we have a large user base with varying needs,
|
||||
and intend to maintain Python 2.7 support within Requests until `pip
|
||||
stops supporting Python 2.7 (there's no estimated date on that yet)
|
||||
<https://pip.pypa.io/en/latest/development/release-process/#python-2-support>`_.
|
||||
|
||||
That said, it is *highly* recommended users migrate to Python 3.6+ since Python
|
||||
2.7 is no longer receiving bug fixes or security updates as of January 1, 2020.
|
||||
|
||||
What are "hostname doesn't match" errors?
|
||||
-----------------------------------------
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
Integrations
|
||||
============
|
||||
|
||||
.. image:: https://farm5.staticflickr.com/4239/34450900674_15863ddea0_k_d.jpg
|
||||
|
||||
Python for iOS
|
||||
--------------
|
||||
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
Recommended Packages and Extensions
|
||||
===================================
|
||||
|
||||
.. image:: https://farm5.staticflickr.com/4218/35224319272_cfc0e621fb_k_d.jpg
|
||||
|
||||
Requests has a great variety of powerful and useful third-party extensions.
|
||||
This page provides an overview of some of the best of them.
|
||||
|
||||
@@ -40,7 +38,7 @@ requested by users within the community.
|
||||
Requests-Threads
|
||||
----------------
|
||||
|
||||
`Requests-Threads` is a Requests session that returns the amazing Twisted's awaitable Deferreds instead of Response objects. This allows the use of ``async``/``await`` keyword usage on Python 3, or Twisted's style of programming, if desired.
|
||||
`Requests-Threads`_ is a Requests session that returns the amazing Twisted's awaitable Deferreds instead of Response objects. This allows the use of ``async``/``await`` keyword usage on Python 3, or Twisted's style of programming, if desired.
|
||||
|
||||
.. _Requests-Threads: https://github.com/requests/requests-threads
|
||||
|
||||
@@ -61,4 +59,4 @@ Betamax
|
||||
`Betamax`_ records your HTTP interactions so the NSA does not have to.
|
||||
A VCR imitation designed only for Python-Requests.
|
||||
|
||||
.. _betamax: https://github.com/sigmavirus24/betamax
|
||||
.. _betamax: https://github.com/betamaxpy/betamax
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
Release Process and Rules
|
||||
=========================
|
||||
|
||||
.. image:: https://farm5.staticflickr.com/4215/34450901614_b74ae720db_k_d.jpg
|
||||
|
||||
.. versionadded:: v2.6.2
|
||||
|
||||
Starting with the version to be released after ``v2.6.2``, the following rules
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
Community Sponsors
|
||||
==================
|
||||
|
||||
**tl;dr**: Requests development is currently `funded by the Python community <https://www.kennethreitz.org/requests3>`_, and
|
||||
some wonderful organizations that utilize the software in their businesses.
|
||||
|
||||
|
||||
-------------------
|
||||
|
||||
|
||||
Requests is one of the most heavily–utilized Python packages in the world.
|
||||
|
||||
It is used by major corporations worldwide for all tasks, both small and large — from writing one–off scripts to orchestrating millions of dollars of critical infrastructure.
|
||||
|
||||
It's even embedded within pip, that tool that you use to install packages and deploy with every day!
|
||||
|
||||
After losing our primary open source maintainer (who was sponsored by a company to work on Requests, and other projects, full–time), we are seeking community financial contributions towards the development of Requests 3.0.
|
||||
|
||||
Patron Sponsors
|
||||
----------------
|
||||
|
||||
|
||||
`Linode — SSD Cloud Hosting & Linux Servers <https://www.linode.com>`_
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
Whether you’re just getting started or deploying a complex system, launching a Linode cloud server has never been easier. They offer the fastest hardware and network in the industry with scalable environments, and their 24x7 customer support team is always standing by to help with any questions.
|
||||
|
||||
✨🍰✨
|
||||
//////
|
||||
|
||||
----------------------------------
|
||||
|
||||
This slot is reserved for ethical organizations willing to invest $10,000 or more in Requests per year.
|
||||
|
||||
By becoming a patron–level sponsor, your organization will receive the following benefits:
|
||||
|
||||
- Prominent placement on the Requests documentation sidebar (~11,000 uniques / day).
|
||||
- Honorable mention here, with logo.
|
||||
- Peace of mind knowing that the infrastructure you rely on is being actively maintained.
|
||||
|
||||
Organizations that sign up will be listed in order — first come first serve!
|
||||
|
||||
Major Sponsors
|
||||
--------------
|
||||
|
||||
The following organizations have significantly contributed towards Requests' sustainability:
|
||||
|
||||
`Slack — Bring your team together <https://slack.com>`_
|
||||
///////////////////////////////////////////////////////
|
||||
|
||||
Slack was extremely kind to be the first organization to generously donate a large sum towards the `2018 Requests 3.0 fundraiser <https://www.kennethreitz.org/requests3>`_, surpassing our entire fundraising goal immediately! They are helping the world become a better place through connectiveness, and reducing the amount of email we all have
|
||||
to deal with on a daily basis.
|
||||
|
||||
P.S. They're `hiring <https://slack.com/careers#openings>`_!
|
||||
|
||||
|
||||
`Twilio — Voice, SMS, and Video for Humans <https://www.twilio.com>`_
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
Twilio was the second organization to generously donate a large sum towards the `2018 Requests 3.0 fundraiser <https://www.kennethreitz.org/requests3>`_, matching the donation of Slack! They are helping the world become a better place through interconnectivity,
|
||||
providing easy–to–use APIs, and empowering developers world-over to help humans communicate in meaningful and effictive ways.
|
||||
|
||||
|
||||
`Azure Cloud Developer Advocates <https://developer.microsoft.com/en-us/advocates/>`_
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Azure was the third organization to generously donate a large sum towards the `2018 Requests 3.0 fundraiser <https://www.kennethreitz.org/requests3>`_, matching the donation of Twilio! Awesome group of generous folks :)
|
||||
|
||||
|
||||
`Niteo — Web Systems Development <https://www.niteoweb.com>`_
|
||||
/////////////////////////////////////////////////////////////
|
||||
|
||||
Niteo was the fourth company to generously donate towards the `2018 Requests 3.0 fundraiser <https://www.kennethreitz.org/requests3>`_. Niteo is a company employing tech enthusiasts from all over the world
|
||||
who love to build great stuff.
|
||||
|
||||
|
||||
`Heroku <https://heroku.com/python>`_
|
||||
/////////////////////////////////////
|
||||
|
||||
Heroku has allowed Kenneth Reitz to work on some open source projects during work hours,
|
||||
including Requests (but mostly Pipenv), from time–to–time, so they are listed
|
||||
here as an honorable mention.
|
||||
|
||||
----------------
|
||||
|
||||
If your organization is interested in becoming either a sponsor or a patron, please `send us an email <mailto:me@kennethreitz.org>`_.
|
||||
|
||||
|
||||
Individual Sponsors
|
||||
-------------------
|
||||
|
||||
Countless individuals, too many to list here, have individually contributed towards the sustainability of the Requests
|
||||
project over the years. Some, financially, others, with code. Contributions (from humans) of all kinds are greatly
|
||||
appreciated.
|
||||
|
||||
✨🍰✨
|
||||
@@ -3,52 +3,29 @@
|
||||
Support
|
||||
=======
|
||||
|
||||
.. image:: https://farm5.staticflickr.com/4198/34080352913_5c13ffb336_k_d.jpg
|
||||
|
||||
If you have questions or issues about Requests, there are several options:
|
||||
|
||||
Stack Overflow
|
||||
-------------
|
||||
--------------
|
||||
|
||||
If your question does not contain sensitive (possibly proprietary)
|
||||
information or can be properly anonymized, please ask a question on
|
||||
`Stack Overflow <https://stackoverflow.com/questions/tagged/python-requests>`_
|
||||
and use the tag ``python-requests``.
|
||||
|
||||
Send a Tweet
|
||||
------------
|
||||
|
||||
If your question is less than 280 characters, feel free to send a tweet to
|
||||
`@kennethreitz <https://twitter.com/kennethreitz>`_,
|
||||
`@sigmavirus24 <https://twitter.com/sigmavirus24>`_,
|
||||
`@lukasaoz <https://twitter.com/lukasaoz>`_, or
|
||||
`@nateprewitt <https://twitter.com/nateprewitt>`_.
|
||||
|
||||
File an Issue
|
||||
-------------
|
||||
|
||||
If you notice some unexpected behaviour in Requests, or want to see support
|
||||
for a new feature,
|
||||
`file an issue on GitHub <https://github.com/requests/requests/issues>`_.
|
||||
`file an issue on GitHub <https://github.com/psf/requests/issues>`_.
|
||||
|
||||
|
||||
E-mail
|
||||
------
|
||||
Send a Tweet
|
||||
------------
|
||||
|
||||
I'm more than happy to answer any personal or in-depth questions about
|
||||
Requests. Feel free to email
|
||||
`requests@kennethreitz.com <mailto:requests@kennethreitz.com>`_.
|
||||
|
||||
|
||||
IRC
|
||||
---
|
||||
|
||||
The official Freenode channel for Requests is
|
||||
`#python-requests <irc://irc.freenode.net/python-requests>`_
|
||||
|
||||
The core developers of requests are on IRC throughout the day.
|
||||
You can find them in ``#python-requests`` as:
|
||||
|
||||
- kennethreitz
|
||||
- lukasa
|
||||
- sigmavirus24
|
||||
If your question is less than 280 characters, feel free to send a tweet to
|
||||
`@nateprewitt <https://twitter.com/nateprewitt>`_,
|
||||
`@sethmlarson <https://twitter.com/sethmlarson>`_, or
|
||||
`@sigmavirus24 <https://twitter.com/sigmavirus24>`_.
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
Community Updates
|
||||
=================
|
||||
|
||||
.. image:: https://farm5.staticflickr.com/4244/34080354873_516c283ad0_k_d.jpg
|
||||
|
||||
If you'd like to stay up to date on the community and development of Requests,
|
||||
there are several options:
|
||||
|
||||
@@ -14,18 +12,7 @@ GitHub
|
||||
------
|
||||
|
||||
The best way to track the development of Requests is through
|
||||
`the GitHub repo <https://github.com/requests/requests>`_.
|
||||
`the GitHub repo <https://github.com/psf/requests>`_.
|
||||
|
||||
Twitter
|
||||
-------
|
||||
|
||||
The author, Kenneth Reitz, often tweets about new features and releases of Requests.
|
||||
|
||||
Follow `@kennethreitz <https://twitter.com/kennethreitz>`_ for updates.
|
||||
|
||||
|
||||
|
||||
Release and Version History
|
||||
===========================
|
||||
|
||||
.. include:: ../../HISTORY.md
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
Vulnerability Disclosure
|
||||
========================
|
||||
|
||||
.. image:: https://farm5.staticflickr.com/4211/34709353644_b041e9e1c2_k_d.jpg
|
||||
|
||||
If you think you have found a potential security vulnerability in requests,
|
||||
please email `sigmavirus24 <mailto:graffatcolmingov@gmail.com>`_ and
|
||||
`Nate <mailto:nate.prewitt@gmail.com>`_ directly. **Do not file a public issue.**
|
||||
please email `Nate <mailto:nate.prewitt@gmail.com>`_ and `Seth <mailto:@sethmichaellarson@gmail.com>`_ directly. **Do not file a public issue.**
|
||||
|
||||
Our PGP Key fingerprints are:
|
||||
|
||||
- 0161 BB7E B208 B5E0 4FDC 9F81 D9DA 0A04 9113 F853 (@sigmavirus24)
|
||||
- 8722 7E29 AD9C FF5C FAC3 EA6A 44D3 FF97 B80D C864 (`@nateprewitt <https://keybase.io/nateprewitt>`_)
|
||||
|
||||
- 8722 7E29 AD9C FF5C FAC3 EA6A 44D3 FF97 B80D C864 (@nateprewitt)
|
||||
- EDD5 6765 A9D8 4653 CBC8 A134 51B0 6736 1740 F5FC (`@sethmlarson <https://keybase.io/sethmlarson>`_)
|
||||
|
||||
You can also contact us on `Keybase <https://keybase.io/>`_ with the
|
||||
profiles above if desired.
|
||||
|
||||
If English is not your first language, please try to describe the problem and
|
||||
its impact to the best of your ability. For greater detail, please use your
|
||||
|
||||
210
docs/conf.py
@@ -18,11 +18,11 @@ import os
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
#sys.path.insert(0, os.path.abspath('.'))
|
||||
# sys.path.insert(0, os.path.abspath('.'))
|
||||
|
||||
# Insert Requests' path into the system.
|
||||
sys.path.insert(0, os.path.abspath('..'))
|
||||
sys.path.insert(0, os.path.abspath('_themes'))
|
||||
sys.path.insert(0, os.path.abspath(".."))
|
||||
sys.path.insert(0, os.path.abspath("_themes"))
|
||||
|
||||
import requests
|
||||
|
||||
@@ -30,36 +30,36 @@ import requests
|
||||
# -- General configuration ------------------------------------------------
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
#needs_sphinx = '1.0'
|
||||
# needs_sphinx = '1.0'
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = [
|
||||
'sphinx.ext.autodoc',
|
||||
'sphinx.ext.intersphinx',
|
||||
'sphinx.ext.todo',
|
||||
'sphinx.ext.viewcode',
|
||||
"sphinx.ext.autodoc",
|
||||
"sphinx.ext.intersphinx",
|
||||
"sphinx.ext.todo",
|
||||
"sphinx.ext.viewcode",
|
||||
]
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
templates_path = ["_templates"]
|
||||
|
||||
# The suffix(es) of source filenames.
|
||||
# You can specify multiple suffix as a list of string:
|
||||
# source_suffix = ['.rst', '.md']
|
||||
source_suffix = '.rst'
|
||||
source_suffix = ".rst"
|
||||
|
||||
# The encoding of source files.
|
||||
#source_encoding = 'utf-8-sig'
|
||||
# source_encoding = 'utf-8-sig'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
master_doc = "index"
|
||||
|
||||
# General information about the project.
|
||||
project = u'Requests'
|
||||
copyright = u'MMXVIII. A <a href="http://kennethreitz.com/pages/open-projects.html">Kenneth Reitz</a> Project'
|
||||
author = u'Kenneth Reitz'
|
||||
project = u"Requests"
|
||||
copyright = u'MMXVIX. A <a href="https://kenreitz.org/projects">Kenneth Reitz</a> Project'
|
||||
author = u"Kenneth Reitz"
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
@@ -79,17 +79,17 @@ language = None
|
||||
|
||||
# There are two options for replacing |today|: either, you set today to some
|
||||
# non-false value, then it is used:
|
||||
#today = ''
|
||||
# today = ''
|
||||
# Else, today_fmt is used as the format for a strftime call.
|
||||
#today_fmt = '%B %d, %Y'
|
||||
# today_fmt = '%B %d, %Y'
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
exclude_patterns = ['_build']
|
||||
exclude_patterns = ["_build"]
|
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all
|
||||
# documents.
|
||||
#default_role = None
|
||||
# default_role = None
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
add_function_parentheses = False
|
||||
@@ -100,16 +100,16 @@ add_module_names = True
|
||||
|
||||
# If true, sectionauthor and moduleauthor directives will be shown in the
|
||||
# output. They are ignored by default.
|
||||
#show_authors = False
|
||||
# show_authors = False
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'flask_theme_support.FlaskyStyle'
|
||||
pygments_style = "flask_theme_support.FlaskyStyle"
|
||||
|
||||
# A list of ignored prefixes for module index sorting.
|
||||
#modindex_common_prefix = []
|
||||
# modindex_common_prefix = []
|
||||
|
||||
# If true, keep warnings as "system message" paragraphs in the built documents.
|
||||
#keep_warnings = False
|
||||
# keep_warnings = False
|
||||
|
||||
# If true, `todo` and `todoList` produce output, else they produce nothing.
|
||||
todo_include_todos = True
|
||||
@@ -119,52 +119,52 @@ todo_include_todos = True
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
html_theme = 'alabaster'
|
||||
html_theme = "alabaster"
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
# documentation.
|
||||
html_theme_options = {
|
||||
'show_powered_by': False,
|
||||
'github_user': 'requests',
|
||||
'github_repo': 'requests',
|
||||
'github_banner': True,
|
||||
'show_related': False,
|
||||
'note_bg': '#FFF59C'
|
||||
"show_powered_by": False,
|
||||
"github_user": "requests",
|
||||
"github_repo": "requests",
|
||||
"github_banner": True,
|
||||
"show_related": False,
|
||||
"note_bg": "#FFF59C",
|
||||
}
|
||||
|
||||
# Add any paths that contain custom themes here, relative to this directory.
|
||||
#html_theme_path = []
|
||||
# html_theme_path = []
|
||||
|
||||
# The name for this set of Sphinx documents. If None, it defaults to
|
||||
# "<project> v<release> documentation".
|
||||
#html_title = None
|
||||
# html_title = None
|
||||
|
||||
# A shorter title for the navigation bar. Default is the same as html_title.
|
||||
#html_short_title = None
|
||||
# html_short_title = None
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top
|
||||
# of the sidebar.
|
||||
#html_logo = None
|
||||
# html_logo = None
|
||||
|
||||
# The name of an image file (within the static path) to use as favicon of the
|
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
# pixels large.
|
||||
#html_favicon = None
|
||||
# html_favicon = None
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['_static']
|
||||
html_static_path = ["_static"]
|
||||
|
||||
# Add any extra paths that contain custom files (such as robots.txt or
|
||||
# .htaccess) here, relative to this directory. These files are copied
|
||||
# directly to the root of the documentation.
|
||||
#html_extra_path = []
|
||||
# html_extra_path = []
|
||||
|
||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||||
# using the given strftime format.
|
||||
#html_last_updated_fmt = '%b %d, %Y'
|
||||
# html_last_updated_fmt = '%b %d, %Y'
|
||||
|
||||
# If true, SmartyPants will be used to convert quotes and dashes to
|
||||
# typographically correct entities.
|
||||
@@ -172,24 +172,29 @@ html_use_smartypants = False
|
||||
|
||||
# Custom sidebar templates, maps document names to template names.
|
||||
html_sidebars = {
|
||||
'index': ['sidebarintro.html', 'sourcelink.html', 'searchbox.html',
|
||||
'hacks.html'],
|
||||
'**': ['sidebarlogo.html', 'localtoc.html', 'relations.html',
|
||||
'sourcelink.html', 'searchbox.html', 'hacks.html']
|
||||
"index": ["sidebarintro.html", "sourcelink.html", "searchbox.html", "hacks.html"],
|
||||
"**": [
|
||||
"sidebarlogo.html",
|
||||
"localtoc.html",
|
||||
"relations.html",
|
||||
"sourcelink.html",
|
||||
"searchbox.html",
|
||||
"hacks.html",
|
||||
],
|
||||
}
|
||||
|
||||
# Additional templates that should be rendered to pages, maps page names to
|
||||
# template names.
|
||||
#html_additional_pages = {}
|
||||
# html_additional_pages = {}
|
||||
|
||||
# If false, no module index is generated.
|
||||
#html_domain_indices = True
|
||||
# html_domain_indices = True
|
||||
|
||||
# If false, no index is generated.
|
||||
#html_use_index = True
|
||||
# html_use_index = True
|
||||
|
||||
# If true, the index is split into individual pages for each letter.
|
||||
#html_split_index = False
|
||||
# html_split_index = False
|
||||
|
||||
# If true, links to the reST sources are added to the pages.
|
||||
html_show_sourcelink = False
|
||||
@@ -203,84 +208,77 @@ html_show_copyright = True
|
||||
# If true, an OpenSearch description file will be output, and all pages will
|
||||
# contain a <link> tag referring to it. The value of this option must be the
|
||||
# base URL from which the finished HTML is served.
|
||||
#html_use_opensearch = ''
|
||||
# html_use_opensearch = ''
|
||||
|
||||
# This is the file name suffix for HTML files (e.g. ".xhtml").
|
||||
#html_file_suffix = None
|
||||
# html_file_suffix = None
|
||||
|
||||
# Language to be used for generating the HTML full-text search index.
|
||||
# Sphinx supports the following languages:
|
||||
# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'
|
||||
# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr'
|
||||
#html_search_language = 'en'
|
||||
# html_search_language = 'en'
|
||||
|
||||
# A dictionary with options for the search language support, empty by default.
|
||||
# Now only 'ja' uses this config value
|
||||
#html_search_options = {'type': 'default'}
|
||||
# html_search_options = {'type': 'default'}
|
||||
|
||||
# The name of a javascript file (relative to the configuration directory) that
|
||||
# implements a search results scorer. If empty, the default will be used.
|
||||
#html_search_scorer = 'scorer.js'
|
||||
# html_search_scorer = 'scorer.js'
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'Requestsdoc'
|
||||
htmlhelp_basename = "Requestsdoc"
|
||||
|
||||
# -- Options for LaTeX output ---------------------------------------------
|
||||
|
||||
latex_elements = {
|
||||
# The paper size ('letterpaper' or 'a4paper').
|
||||
#'papersize': 'letterpaper',
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#'pointsize': '10pt',
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#'preamble': '',
|
||||
|
||||
# Latex figure (float) alignment
|
||||
#'figure_align': 'htbp',
|
||||
# The paper size ('letterpaper' or 'a4paper').
|
||||
#'papersize': 'letterpaper',
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#'pointsize': '10pt',
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#'preamble': '',
|
||||
# Latex figure (float) alignment
|
||||
#'figure_align': 'htbp',
|
||||
}
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title,
|
||||
# author, documentclass [howto, manual, or own class]).
|
||||
latex_documents = [
|
||||
(master_doc, 'Requests.tex', u'Requests Documentation',
|
||||
u'Kenneth Reitz', 'manual'),
|
||||
(master_doc, "Requests.tex", u"Requests Documentation", u"Kenneth Reitz", "manual")
|
||||
]
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
# the title page.
|
||||
#latex_logo = None
|
||||
# latex_logo = None
|
||||
|
||||
# For "manual" documents, if this is true, then toplevel headings are parts,
|
||||
# not chapters.
|
||||
#latex_use_parts = False
|
||||
# latex_use_parts = False
|
||||
|
||||
# If true, show page references after internal links.
|
||||
#latex_show_pagerefs = False
|
||||
# latex_show_pagerefs = False
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#latex_show_urls = False
|
||||
# latex_show_urls = False
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#latex_appendices = []
|
||||
# latex_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#latex_domain_indices = True
|
||||
# latex_domain_indices = True
|
||||
|
||||
|
||||
# -- Options for manual page output ---------------------------------------
|
||||
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
(master_doc, 'requests', u'Requests Documentation',
|
||||
[author], 1)
|
||||
]
|
||||
man_pages = [(master_doc, "requests", u"Requests Documentation", [author], 1)]
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#man_show_urls = False
|
||||
# man_show_urls = False
|
||||
|
||||
|
||||
# -- Options for Texinfo output -------------------------------------------
|
||||
@@ -289,22 +287,28 @@ man_pages = [
|
||||
# (source start file, target name, title, author,
|
||||
# dir menu entry, description, category)
|
||||
texinfo_documents = [
|
||||
(master_doc, 'Requests', u'Requests Documentation',
|
||||
author, 'Requests', 'One line description of project.',
|
||||
'Miscellaneous'),
|
||||
(
|
||||
master_doc,
|
||||
"Requests",
|
||||
u"Requests Documentation",
|
||||
author,
|
||||
"Requests",
|
||||
"One line description of project.",
|
||||
"Miscellaneous",
|
||||
)
|
||||
]
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#texinfo_appendices = []
|
||||
# texinfo_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#texinfo_domain_indices = True
|
||||
# texinfo_domain_indices = True
|
||||
|
||||
# How to display URL addresses: 'footnote', 'no', or 'inline'.
|
||||
#texinfo_show_urls = 'footnote'
|
||||
# texinfo_show_urls = 'footnote'
|
||||
|
||||
# If true, do not generate a @detailmenu in the "Top" node's menu.
|
||||
#texinfo_no_detailmenu = False
|
||||
# texinfo_no_detailmenu = False
|
||||
|
||||
|
||||
# -- Options for Epub output ----------------------------------------------
|
||||
@@ -316,67 +320,67 @@ epub_publisher = author
|
||||
epub_copyright = copyright
|
||||
|
||||
# The basename for the epub file. It defaults to the project name.
|
||||
#epub_basename = project
|
||||
# epub_basename = project
|
||||
|
||||
# The HTML theme for the epub output. Since the default themes are not
|
||||
# optimized for small screen space, using the same theme for HTML and epub
|
||||
# output is usually not wise. This defaults to 'epub', a theme designed to save
|
||||
# visual space.
|
||||
#epub_theme = 'epub'
|
||||
# epub_theme = 'epub'
|
||||
|
||||
# The language of the text. It defaults to the language option
|
||||
# or 'en' if the language is not set.
|
||||
#epub_language = ''
|
||||
# epub_language = ''
|
||||
|
||||
# The scheme of the identifier. Typical schemes are ISBN or URL.
|
||||
#epub_scheme = ''
|
||||
# epub_scheme = ''
|
||||
|
||||
# The unique identifier of the text. This can be a ISBN number
|
||||
# or the project homepage.
|
||||
#epub_identifier = ''
|
||||
# epub_identifier = ''
|
||||
|
||||
# A unique identification for the text.
|
||||
#epub_uid = ''
|
||||
# epub_uid = ''
|
||||
|
||||
# A tuple containing the cover image and cover page html template filenames.
|
||||
#epub_cover = ()
|
||||
# epub_cover = ()
|
||||
|
||||
# A sequence of (type, uri, title) tuples for the guide element of content.opf.
|
||||
#epub_guide = ()
|
||||
# epub_guide = ()
|
||||
|
||||
# HTML files that should be inserted before the pages created by sphinx.
|
||||
# The format is a list of tuples containing the path and title.
|
||||
#epub_pre_files = []
|
||||
# epub_pre_files = []
|
||||
|
||||
# HTML files that should be inserted after the pages created by sphinx.
|
||||
# The format is a list of tuples containing the path and title.
|
||||
#epub_post_files = []
|
||||
# epub_post_files = []
|
||||
|
||||
# A list of files that should not be packed into the epub file.
|
||||
epub_exclude_files = ['search.html']
|
||||
epub_exclude_files = ["search.html"]
|
||||
|
||||
# The depth of the table of contents in toc.ncx.
|
||||
#epub_tocdepth = 3
|
||||
# epub_tocdepth = 3
|
||||
|
||||
# Allow duplicate toc entries.
|
||||
#epub_tocdup = True
|
||||
# epub_tocdup = True
|
||||
|
||||
# Choose between 'default' and 'includehidden'.
|
||||
#epub_tocscope = 'default'
|
||||
# epub_tocscope = 'default'
|
||||
|
||||
# Fix unsupported image types using the Pillow.
|
||||
#epub_fix_images = False
|
||||
# epub_fix_images = False
|
||||
|
||||
# Scale large images.
|
||||
#epub_max_image_width = 0
|
||||
# epub_max_image_width = 0
|
||||
|
||||
# How to display URL addresses: 'footnote', 'no', or 'inline'.
|
||||
#epub_show_urls = 'inline'
|
||||
# epub_show_urls = 'inline'
|
||||
|
||||
# If false, no index is generated.
|
||||
#epub_use_index = True
|
||||
# epub_use_index = True
|
||||
|
||||
intersphinx_mapping = {
|
||||
'python': ('https://docs.python.org/3/', None),
|
||||
'urllib3': ('https://urllib3.readthedocs.io/en/latest', None),
|
||||
"python": ("https://docs.python.org/3/", None),
|
||||
"urllib3": ("https://urllib3.readthedocs.io/en/latest", None),
|
||||
}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
Authors
|
||||
=======
|
||||
|
||||
.. image:: https://static1.squarespace.com/static/533ad9bde4b098d084a846b1/t/534f6e1ce4b09b70f38ee6c1/1432265542589/DSCF3147.jpg?format=2500w
|
||||
|
||||
.. include:: ../../AUTHORS.rst
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
Contributor's Guide
|
||||
===================
|
||||
|
||||
.. image:: https://farm5.staticflickr.com/4237/35550408335_7671fde302_k_d.jpg
|
||||
|
||||
If you're reading this, you're probably interested in contributing to Requests.
|
||||
Thank you very much! Open source projects live-and-die based on the support
|
||||
they receive from others, and the fact that you're even considering
|
||||
@@ -13,23 +11,17 @@ contributing to the Requests project is *very* generous of you.
|
||||
This document lays out guidelines and advice for contributing to this project.
|
||||
If you're thinking of contributing, please start by reading this document and
|
||||
getting a feel for how contributing to this project works. If you have any
|
||||
questions, feel free to reach out to either `Ian Cordasco`_, `Cory Benfield`_,
|
||||
or `Nate Prewitt`_, the primary maintainers.
|
||||
questions, feel free to reach out to either `Nate Prewitt`_, `Ian Cordasco`_,
|
||||
or `Seth Michael Larson`_, the primary maintainers.
|
||||
|
||||
.. _Ian Cordasco: http://www.coglib.com/~icordasc/
|
||||
.. _Cory Benfield: https://lukasa.co.uk/about
|
||||
.. _Nate Prewitt: https://www.nateprewitt.com/
|
||||
|
||||
If you have non-technical feedback, philosophical ponderings, crazy ideas, or
|
||||
other general thoughts about Requests or its position within the Python
|
||||
ecosystem, the BDFL, `Kenneth Reitz`_, would love to hear from you.
|
||||
.. _Seth Michael Larson: https://sethmlarson.dev/
|
||||
|
||||
The guide is split into sections based on the type of contribution you're
|
||||
thinking of making, with a section that covers general guidelines for all
|
||||
contributors.
|
||||
|
||||
.. _Kenneth Reitz: mailto:me@kennethreitz.org
|
||||
|
||||
Be Cordial
|
||||
----------
|
||||
|
||||
@@ -42,7 +34,7 @@ including reporting bugs or requesting features. This golden rule is
|
||||
**All contributions are welcome**, as long as
|
||||
everyone involved is treated with respect.
|
||||
|
||||
.. _be cordial or be on your way: https://www.kennethreitz.org/essays/be-cordial-or-be-on-your-way
|
||||
.. _be cordial or be on your way: https://kenreitz.org/essays/2013/01/27/be-cordial-or-be-on-your-way
|
||||
|
||||
.. _early-feedback:
|
||||
|
||||
@@ -130,7 +122,14 @@ the Requests codebase::
|
||||
foo = long_function_name(var_one, var_two,
|
||||
var_three, var_four)
|
||||
|
||||
No. Just don't. Please.
|
||||
No. Just don't. Please. This is much better::
|
||||
|
||||
foo = long_function_name(
|
||||
var_one,
|
||||
var_two,
|
||||
var_three,
|
||||
var_four,
|
||||
)
|
||||
|
||||
Docstrings are to follow the following syntaxes::
|
||||
|
||||
@@ -190,7 +189,7 @@ through the `GitHub issues`_, **both open and closed**, to confirm that the bug
|
||||
hasn't been reported before. Duplicate bug reports are a huge drain on the time
|
||||
of other contributors, and should be avoided as much as possible.
|
||||
|
||||
.. _GitHub issues: https://github.com/requests/requests/issues
|
||||
.. _GitHub issues: https://github.com/psf/requests/issues
|
||||
|
||||
|
||||
Feature Requests
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
Development Philosophy
|
||||
======================
|
||||
|
||||
.. image:: https://farm5.staticflickr.com/4231/34484831073_636008a23d_k_d.jpg
|
||||
|
||||
Requests is an open but opinionated library, created by an open but opinionated developer.
|
||||
|
||||
|
||||
Management Style
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
`Kenneth Reitz <https://www.kennethreitz.org/>`_ is the BDFL. He has final say in any decision related to the Requests project. Kenneth is responsible for the direction and form of the library, as well as its presentation. In addition to making decisions based on technical merit, he is responsible for making decisions based on the development philosophy of Requests.
|
||||
|
||||
`Ian Cordasco <http://www.coglib.com/~icordasc/>`_, `Cory Benfield <https://lukasa.co.uk/about/>`_, and `Nate Prewitt <https://www.nateprewitt.com/>`_ are the core contributors. They are responsible for triaging bug reports, reviewing pull requests and ensuring that Kenneth is kept up to speed with developments around the library. The day-to-day managing of the project is done by the core contributors. They are responsible for making judgements about whether or not a feature request is likely to be accepted by Kenneth. Their word is, in some ways, more final than Kenneth's.
|
||||
|
||||
Values
|
||||
~~~~~~
|
||||
|
||||
- Simplicity is always better than functionality.
|
||||
- Listen to everyone, then disregard it.
|
||||
- The API is all that matters. Everything else is secondary.
|
||||
- Fit the 90% use-case. Ignore the nay-sayers.
|
||||
|
||||
Semantic Versioning
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
For many years, the open source community has been plagued with version number dystonia. Numbers vary so greatly from project to project, they are practically meaningless.
|
||||
|
||||
Requests uses `Semantic Versioning <https://semver.org/>`_. This specification seeks to put an end to this madness with a small set of practical guidelines for you and your colleagues to use in your next project.
|
||||
|
||||
Standard Library?
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
Requests has no *active* plans to be included in the standard library. This decision has been discussed at length with Guido as well as numerous core developers.
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<script async class="speakerdeck-embed" data-id="68f22f0841734d848315c618111b13ea" data-ratio="1.33333333333333" src="//speakerdeck.com/assets/embed.js"></script>
|
||||
|
||||
Essentially, the standard library is where a library goes to die. It is appropriate for a module to be included when active development is no longer necessary.
|
||||
|
||||
Linux Distro Packages
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Distributions have been made for many Linux repositories, including: Ubuntu, Debian, RHEL, and Arch.
|
||||
|
||||
These distributions are sometimes divergent forks, or are otherwise not kept up-to-date with the latest code and bugfixes. PyPI (and its mirrors) and GitHub are the official distribution sources; alternatives are not supported by the Requests project.
|
||||
@@ -1,64 +0,0 @@
|
||||
How to Help
|
||||
===========
|
||||
|
||||
.. image:: https://farm5.staticflickr.com/4290/34450900104_bc1d424213_k_d.jpg
|
||||
|
||||
Requests is under active development, and contributions are more than welcome!
|
||||
|
||||
#. Check for open issues or open a fresh issue to start a discussion around a bug.
|
||||
There is a Contributor Friendly tag for issues that should be ideal for people who are not very
|
||||
familiar with the codebase yet.
|
||||
#. Fork `the repository <https://github.com/requests/requests>`_ on GitHub and start making your
|
||||
changes to a new branch.
|
||||
#. Write a test which shows that the bug was fixed.
|
||||
#. Send a pull request and bug the maintainer until it gets merged and published. :)
|
||||
Make sure to add yourself to `AUTHORS <https://github.com/requests/requests/blob/master/AUTHORS.rst>`_.
|
||||
|
||||
Feature Freeze
|
||||
--------------
|
||||
|
||||
As of v1.0.0, Requests has now entered a feature freeze. Requests for new
|
||||
features and Pull Requests implementing those features will not be accepted.
|
||||
|
||||
Development Dependencies
|
||||
------------------------
|
||||
|
||||
You'll need to install py.test in order to run the Requests' test suite::
|
||||
|
||||
$ venv .venv
|
||||
$ source .venv/bin/activate
|
||||
|
||||
$ make
|
||||
$ python setup.py test
|
||||
============================= test session starts ==============================
|
||||
platform darwin -- Python 3.4.4, pytest-3.0.6, py-1.4.32, pluggy-0.4.0
|
||||
...
|
||||
collected 445 items
|
||||
|
||||
tests/test_hooks.py ...
|
||||
tests/test_lowlevel.py ............
|
||||
tests/test_requests.py ...........................................................
|
||||
tests/test_structures.py ....................
|
||||
tests/test_testserver.py ...........
|
||||
tests/test_utils.py ..s...........................................................
|
||||
|
||||
============== 442 passed, 1 skipped, 2 xpassed in 46.48 seconds ===============
|
||||
|
||||
You can also run ``$ make tests`` to run against all supported Python versions, using tox/detox.
|
||||
|
||||
Runtime Environments
|
||||
--------------------
|
||||
|
||||
Requests currently supports the following versions of Python:
|
||||
|
||||
- Python 2.7
|
||||
- Python 3.4
|
||||
- Python 3.5
|
||||
- Python 3.6
|
||||
- Python 3.7
|
||||
- PyPy
|
||||
|
||||
Google AppEngine is not officially supported although support is available
|
||||
with the `Requests-Toolbelt`_.
|
||||
|
||||
.. _Requests-Toolbelt: https://toolbelt.readthedocs.io/
|
||||
@@ -8,6 +8,10 @@ Requests: HTTP for Humans™
|
||||
|
||||
Release v\ |version|. (:ref:`Installation <install>`)
|
||||
|
||||
|
||||
.. image:: https://pepy.tech/badge/requests
|
||||
:target: https://pepy.tech/project/requests
|
||||
|
||||
.. image:: https://img.shields.io/pypi/l/requests.svg
|
||||
:target: https://pypi.org/project/requests/
|
||||
|
||||
@@ -17,23 +21,7 @@ Release v\ |version|. (:ref:`Installation <install>`)
|
||||
.. image:: https://img.shields.io/pypi/pyversions/requests.svg
|
||||
:target: https://pypi.org/project/requests/
|
||||
|
||||
.. image:: https://codecov.io/github/requests/requests/coverage.svg?branch=master
|
||||
:target: https://codecov.io/github/requests/requests
|
||||
:alt: codecov.io
|
||||
|
||||
.. image:: https://img.shields.io/badge/Say%20Thanks!-🦉-1EAEDB.svg
|
||||
:target: https://saythanks.io/to/kennethreitz
|
||||
|
||||
|
||||
**Requests** is the only *Non-GMO* HTTP library for Python, safe for human
|
||||
consumption.
|
||||
|
||||
.. note:: The use of **Python 3** is *highly* preferred over Python 2. Consider upgrading your applications and infrastructure if you find yourself *still* using Python 2 in production today. If you are using Python 3, congratulations — you are indeed a person of excellent taste.
|
||||
—*Kenneth Reitz*
|
||||
|
||||
|
||||
If you're interested in financially supporting Kenneth Reitz open source, consider visiting `this link <https://cash.me/kennethreitz>`_. Your support helps tremendously with sustainability of motivation, as Open Source is no longer part of my day job.
|
||||
|
||||
**Requests** is an elegant and simple HTTP library for Python, built for human beings.
|
||||
|
||||
-------------------
|
||||
|
||||
@@ -47,48 +35,17 @@ If you're interested in financially supporting Kenneth Reitz open source, consid
|
||||
>>> r.encoding
|
||||
'utf-8'
|
||||
>>> r.text
|
||||
u'{"type":"User"...'
|
||||
'{"type":"User"...'
|
||||
>>> r.json()
|
||||
{u'private_gists': 419, u'total_private_repos': 77, ...}
|
||||
{'private_gists': 419, 'total_private_repos': 77, ...}
|
||||
|
||||
See `similar code, sans Requests <https://gist.github.com/973705>`_.
|
||||
|
||||
|
||||
**Requests** allows you to send *organic, grass-fed* HTTP/1.1 requests, without the
|
||||
need for manual labor. There's no need to manually add query strings to your
|
||||
**Requests** allows you to send HTTP/1.1 requests extremely easily.
|
||||
There's no need to manually add query strings to your
|
||||
URLs, or to form-encode your POST data. Keep-alive and HTTP connection pooling
|
||||
are 100% automatic, thanks to `urllib3 <https://github.com/shazow/urllib3>`_.
|
||||
|
||||
User Testimonials
|
||||
-----------------
|
||||
|
||||
Nike, Twitter, Spotify, Microsoft, Amazon, Lyft, BuzzFeed, Reddit, The NSA, Her Majesty's Government, Google, Twilio, Runscope, Mozilla, Heroku,
|
||||
PayPal, NPR, Obama for America, Transifex, Native Instruments, The Washington
|
||||
Post, SoundCloud, Kippt, Sony, and Federal U.S.
|
||||
Institutions that prefer to be unnamed claim to use Requests internally.
|
||||
|
||||
**Armin Ronacher**, creator of Flask—
|
||||
*Requests is the perfect example how beautiful an API can be with the
|
||||
right level of abstraction.*
|
||||
|
||||
**Matt DeBoard**—
|
||||
*I'm going to get Kenneth Reitz's Python requests module tattooed
|
||||
on my body, somehow. The whole thing.*
|
||||
|
||||
**Daniel Greenfeld**—
|
||||
*Nuked a 1200 LOC spaghetti code library with 10 lines of code thanks to
|
||||
Kenneth Reitz's Requests library. Today has been AWESOME.*
|
||||
|
||||
**Kenny Meyers**—
|
||||
*Python HTTP: When in doubt, or when not in doubt, use Requests. Beautiful,
|
||||
simple, Pythonic.*
|
||||
|
||||
Requests is one of the most downloaded Python packages of all time, pulling in
|
||||
over 400,000 downloads **each day**. Join the party!
|
||||
|
||||
If your organization uses Requests internally, consider `supporting the development of 3.0 <https://www.kennethreitz.org/requests3>`_. Your
|
||||
generosity will be greatly appreciated, and help drive the project forward
|
||||
into the future.
|
||||
are 100% automatic, thanks to `urllib3 <https://github.com/urllib3/urllib3>`_.
|
||||
|
||||
Beloved Features
|
||||
----------------
|
||||
@@ -111,7 +68,7 @@ Requests is ready for today's web.
|
||||
- Chunked Requests
|
||||
- ``.netrc`` Support
|
||||
|
||||
Requests officially supports Python 2.7 & 3.4–3.7, and runs great on PyPy.
|
||||
Requests officially supports Python 2.7 & 3.6+, and runs great on PyPy.
|
||||
|
||||
|
||||
The User Guide
|
||||
@@ -124,7 +81,6 @@ instructions for getting the most out of Requests.
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
user/intro
|
||||
user/install
|
||||
user/quickstart
|
||||
user/advanced
|
||||
@@ -140,15 +96,18 @@ Requests ecosystem and community.
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
community/sponsors
|
||||
community/recommended
|
||||
community/faq
|
||||
community/out-there
|
||||
community/support
|
||||
community/vulnerabilities
|
||||
community/updates
|
||||
community/release-process
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
community/updates
|
||||
|
||||
The API Documentation / Guide
|
||||
-----------------------------
|
||||
|
||||
@@ -171,8 +130,6 @@ you.
|
||||
:maxdepth: 3
|
||||
|
||||
dev/contributing
|
||||
dev/philosophy
|
||||
dev/todo
|
||||
dev/authors
|
||||
|
||||
There are no more guides. You are now guideless.
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
Advanced Usage
|
||||
==============
|
||||
|
||||
.. image:: https://farm5.staticflickr.com/4263/35163665790_d182d84f5e_k_d.jpg
|
||||
|
||||
This document covers some of Requests more advanced features.
|
||||
|
||||
.. _session-objects:
|
||||
@@ -193,7 +191,7 @@ When you are using the prepared request flow, keep in mind that it does not take
|
||||
This can cause problems if you are using environment variables to change the behaviour of requests.
|
||||
For example: Self-signed SSL certificates specified in ``REQUESTS_CA_BUNDLE`` will not be taken into account.
|
||||
As a result an ``SSL: CERTIFICATE_VERIFY_FAILED`` is thrown.
|
||||
You can get around this behaviour by explicity merging the environment settings into your session::
|
||||
You can get around this behaviour by explicitly merging the environment settings into your session::
|
||||
|
||||
from requests import Request, Session
|
||||
|
||||
@@ -203,7 +201,7 @@ You can get around this behaviour by explicity merging the environment settings
|
||||
prepped = s.prepare_request(req)
|
||||
|
||||
# Merge environment settings into session
|
||||
settings = s.merge_environment_settings(prepped.url, None, None, None, None)
|
||||
settings = s.merge_environment_settings(prepped.url, {}, None, None, None)
|
||||
resp = s.send(prepped, **settings)
|
||||
|
||||
print(resp.status_code)
|
||||
@@ -235,15 +233,22 @@ or persistent::
|
||||
s.verify = '/path/to/certfile'
|
||||
|
||||
.. note:: If ``verify`` is set to a path to a directory, the directory must have been processed using
|
||||
the c_rehash utility supplied with OpenSSL.
|
||||
the ``c_rehash`` utility supplied with OpenSSL.
|
||||
|
||||
This list of trusted CAs can also be specified through the ``REQUESTS_CA_BUNDLE`` environment variable.
|
||||
If ``REQUESTS_CA_BUNDLE`` is not set, ``CURL_CA_BUNDLE`` will be used as fallback.
|
||||
|
||||
Requests can also ignore verifying the SSL certificate if you set ``verify`` to False::
|
||||
|
||||
>>> requests.get('https://kennethreitz.org', verify=False)
|
||||
<Response [200]>
|
||||
|
||||
Note that when ``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. Setting verify to ``False`` may be useful
|
||||
during local development or testing.
|
||||
|
||||
By default, ``verify`` is set to True. Option ``verify`` only applies to host certs.
|
||||
|
||||
Client Side Certificates
|
||||
@@ -300,7 +305,7 @@ immediately. You can override this behaviour and defer downloading the response
|
||||
body until you access the :attr:`Response.content <requests.Response.content>`
|
||||
attribute with the ``stream`` parameter::
|
||||
|
||||
tarball_url = 'https://github.com/requests/requests/tarball/master'
|
||||
tarball_url = 'https://github.com/psf/requests/tarball/master'
|
||||
r = requests.get(tarball_url, stream=True)
|
||||
|
||||
At this point only the response headers have been downloaded and the connection
|
||||
@@ -395,8 +400,8 @@ To do that, just set files to a list of tuples of ``(form_field_name, file_info)
|
||||
|
||||
>>> url = 'https://httpbin.org/post'
|
||||
>>> multiple_files = [
|
||||
('images', ('foo.png', open('foo.png', 'rb'), 'image/png')),
|
||||
('images', ('bar.png', open('bar.png', 'rb'), 'image/png'))]
|
||||
... ('images', ('foo.png', open('foo.png', 'rb'), 'image/png')),
|
||||
... ('images', ('bar.png', open('bar.png', 'rb'), 'image/png'))]
|
||||
>>> r = requests.post(url, files=multiple_files)
|
||||
>>> r.text
|
||||
{
|
||||
@@ -482,7 +487,7 @@ they are added.
|
||||
Custom Authentication
|
||||
---------------------
|
||||
|
||||
Requests allows you to use specify your own authentication mechanism.
|
||||
Requests allows you to specify your own authentication mechanism.
|
||||
|
||||
Any callable which is passed as the ``auth`` argument to a request method will
|
||||
have the opportunity to modify the request before it is dispatched.
|
||||
@@ -584,10 +589,26 @@ If you need to use a proxy, you can configure individual requests with the
|
||||
|
||||
requests.get('http://example.org', proxies=proxies)
|
||||
|
||||
You can also configure proxies by setting the environment variables
|
||||
``HTTP_PROXY`` and ``HTTPS_PROXY``.
|
||||
Alternatively you can configure it once for an entire
|
||||
:class:`Session <requests.Session>`::
|
||||
|
||||
::
|
||||
import requests
|
||||
|
||||
proxies = {
|
||||
'http': 'http://10.10.1.10:3128',
|
||||
'https': 'http://10.10.1.10:1080',
|
||||
}
|
||||
session = requests.Session()
|
||||
session.proxies.update(proxies)
|
||||
|
||||
session.get('http://example.org')
|
||||
|
||||
When the proxies configuration is not overridden in python as shown above,
|
||||
by default Requests relies on the proxy configuration defined by standard
|
||||
environment variables ``http_proxy``, ``https_proxy``, ``no_proxy`` and
|
||||
``curl_ca_bundle``. Uppercase variants of these variables are also supported.
|
||||
You can therefore set them to configure Requests (only set the ones relevant
|
||||
to your needs)::
|
||||
|
||||
$ export HTTP_PROXY="http://10.10.1.10:3128"
|
||||
$ export HTTPS_PROXY="http://10.10.1.10:1080"
|
||||
@@ -596,9 +617,17 @@ You can also configure proxies by setting the environment variables
|
||||
>>> import requests
|
||||
>>> requests.get('http://example.org')
|
||||
|
||||
To use HTTP Basic Auth with your proxy, use the `http://user:password@host/` syntax::
|
||||
To use HTTP Basic Auth with your proxy, use the `http://user:password@host/`
|
||||
syntax in any of the above configuration entries::
|
||||
|
||||
proxies = {'http': 'http://user:pass@10.10.1.10:3128/'}
|
||||
$ export HTTPS_PROXY="http://user:pass@10.10.1.10:1080"
|
||||
|
||||
$ python
|
||||
>>> proxies = {'http': 'http://user:pass@10.10.1.10:3128/'}
|
||||
|
||||
.. warning:: Storing sensitive username and password information in an
|
||||
environment variable or a version-controlled file is a security risk and is
|
||||
highly discouraged.
|
||||
|
||||
To give a proxy for a specific scheme and host, use the
|
||||
`scheme://hostname` form for the key. This will match for
|
||||
@@ -610,6 +639,23 @@ any request to the given scheme and exact hostname.
|
||||
|
||||
Note that proxy URLs must include the scheme.
|
||||
|
||||
Finally, note that using a proxy for https connections typically requires your
|
||||
local machine to trust the proxy's root certificate. By default the list of
|
||||
certificates trusted by Requests can be found with::
|
||||
|
||||
from requests.utils import DEFAULT_CA_BUNDLE_PATH
|
||||
print(DEFAULT_CA_BUNDLE_PATH)
|
||||
|
||||
You override this default certificate bundle by setting the standard
|
||||
``curl_ca_bundle`` environment variable to another file path::
|
||||
|
||||
$ export curl_ca_bundle="/usr/local/myproxy_info/cacert.pem"
|
||||
$ export https_proxy="http://10.10.1.10:1080"
|
||||
|
||||
$ python
|
||||
>>> import requests
|
||||
>>> requests.get('https://example.org')
|
||||
|
||||
SOCKS
|
||||
^^^^^
|
||||
|
||||
@@ -623,7 +669,7 @@ You can get the dependencies for this feature from ``pip``:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ pip install requests[socks]
|
||||
$ python -m pip install requests[socks]
|
||||
|
||||
Once you've installed those dependencies, using a SOCKS proxy is just as easy
|
||||
as using a HTTP one::
|
||||
@@ -651,10 +697,22 @@ Encodings
|
||||
When you receive a response, Requests makes a guess at the encoding to
|
||||
use for decoding the response when you access the :attr:`Response.text
|
||||
<requests.Response.text>` attribute. Requests will first check for an
|
||||
encoding in the HTTP header, and if none is present, will use `chardet
|
||||
<https://pypi.org/project/chardet/>`_ to attempt to guess the encoding.
|
||||
encoding in the HTTP header, and if none is present, will use
|
||||
`charset_normalizer <https://pypi.org/project/charset_normalizer/>`_
|
||||
or `chardet <https://github.com/chardet/chardet>`_ to attempt to
|
||||
guess the encoding.
|
||||
|
||||
The only time Requests will not do this is if no explicit charset
|
||||
If ``chardet`` is installed, ``requests`` uses it, however for python3
|
||||
``chardet`` is no longer a mandatory dependency. The ``chardet``
|
||||
library is an LGPL-licenced dependency and some users of requests
|
||||
cannot depend on mandatory LGPL-licensed dependencies.
|
||||
|
||||
When you install ``request`` without specifying ``[use_chardet_on_py3]]`` extra,
|
||||
and ``chardet`` is not already installed, ``requests`` uses ``charset-normalizer``
|
||||
(MIT-licensed) to guess the encoding. For Python 2, ``requests`` uses only
|
||||
``chardet`` and is a mandatory dependency there.
|
||||
|
||||
The only time Requests will not guess the encoding is if no explicit charset
|
||||
is present in the HTTP headers **and** the ``Content-Type``
|
||||
header contains ``text``. In this situation, `RFC 2616
|
||||
<https://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.7.1>`_ specifies
|
||||
@@ -680,7 +738,7 @@ from GitHub. Suppose we wanted commit ``a050faf`` on Requests. We would get it
|
||||
like so::
|
||||
|
||||
>>> import requests
|
||||
>>> r = requests.get('https://api.github.com/repos/requests/requests/git/commits/a050faf084662f3a352dd1a941f2c7c9f886d4ad')
|
||||
>>> r = requests.get('https://api.github.com/repos/psf/requests/git/commits/a050faf084662f3a352dd1a941f2c7c9f886d4ad')
|
||||
|
||||
We should confirm that GitHub responded correctly. If it has, we want to work
|
||||
out what type of content it is. Do this like so::
|
||||
@@ -698,12 +756,12 @@ So, GitHub returns JSON. That's great, we can use the :meth:`r.json
|
||||
>>> commit_data = r.json()
|
||||
|
||||
>>> print(commit_data.keys())
|
||||
[u'committer', u'author', u'url', u'tree', u'sha', u'parents', u'message']
|
||||
['committer', 'author', 'url', 'tree', 'sha', 'parents', 'message']
|
||||
|
||||
>>> print(commit_data[u'committer'])
|
||||
{u'date': u'2012-05-10T11:10:50-07:00', u'email': u'me@kennethreitz.com', u'name': u'Kenneth Reitz'}
|
||||
>>> print(commit_data['committer'])
|
||||
{'date': '2012-05-10T11:10:50-07:00', 'email': 'me@kennethreitz.com', 'name': 'Kenneth Reitz'}
|
||||
|
||||
>>> print(commit_data[u'message'])
|
||||
>>> print(commit_data['message'])
|
||||
makin' history
|
||||
|
||||
So far, so simple. Well, let's investigate the GitHub API a little bit. Now,
|
||||
@@ -735,37 +793,37 @@ we should probably avoid making ham-handed POSTS to it. Instead, let's play
|
||||
with the Issues feature of GitHub.
|
||||
|
||||
This documentation was added in response to
|
||||
`Issue #482 <https://github.com/requests/requests/issues/482>`_. Given that
|
||||
`Issue #482 <https://github.com/psf/requests/issues/482>`_. Given that
|
||||
this issue already exists, we will use it as an example. Let's start by getting it.
|
||||
|
||||
::
|
||||
|
||||
>>> r = requests.get('https://api.github.com/repos/requests/requests/issues/482')
|
||||
>>> r = requests.get('https://api.github.com/repos/psf/requests/issues/482')
|
||||
>>> r.status_code
|
||||
200
|
||||
|
||||
>>> issue = json.loads(r.text)
|
||||
|
||||
>>> print(issue[u'title'])
|
||||
>>> print(issue['title'])
|
||||
Feature any http verb in docs
|
||||
|
||||
>>> print(issue[u'comments'])
|
||||
>>> print(issue['comments'])
|
||||
3
|
||||
|
||||
Cool, we have three comments. Let's take a look at the last of them.
|
||||
|
||||
::
|
||||
|
||||
>>> r = requests.get(r.url + u'/comments')
|
||||
>>> r = requests.get(r.url + '/comments')
|
||||
>>> r.status_code
|
||||
200
|
||||
|
||||
>>> comments = r.json()
|
||||
|
||||
>>> print(comments[0].keys())
|
||||
[u'body', u'url', u'created_at', u'updated_at', u'user', u'id']
|
||||
['body', 'url', 'created_at', 'updated_at', 'user', 'id']
|
||||
|
||||
>>> print(comments[2][u'body'])
|
||||
>>> print(comments[2]['body'])
|
||||
Probably in the "advanced" section
|
||||
|
||||
Well, that seems like a silly place. Let's post a comment telling the poster
|
||||
@@ -773,7 +831,7 @@ that he's silly. Who is the poster, anyway?
|
||||
|
||||
::
|
||||
|
||||
>>> print(comments[2][u'user'][u'login'])
|
||||
>>> print(comments[2]['user']['login'])
|
||||
kennethreitz
|
||||
|
||||
OK, so let's tell this Kenneth guy that we think this example should go in the
|
||||
@@ -783,7 +841,7 @@ is to POST to the thread. Let's do it.
|
||||
::
|
||||
|
||||
>>> body = json.dumps({u"body": u"Sounds great! I'll get right on it!"})
|
||||
>>> url = u"https://api.github.com/repos/requests/requests/issues/482/comments"
|
||||
>>> url = u"https://api.github.com/repos/psf/requests/issues/482/comments"
|
||||
|
||||
>>> r = requests.post(url=url, data=body)
|
||||
>>> r.status_code
|
||||
@@ -803,7 +861,7 @@ the very common Basic Auth.
|
||||
201
|
||||
|
||||
>>> content = r.json()
|
||||
>>> print(content[u'body'])
|
||||
>>> print(content['body'])
|
||||
Sounds great! I'll get right on it.
|
||||
|
||||
Brilliant. Oh, wait, no! I meant to add that it would take me a while, because
|
||||
@@ -817,7 +875,7 @@ that.
|
||||
5804413
|
||||
|
||||
>>> body = json.dumps({u"body": u"Sounds great! I'll get right on it once I feed my cat."})
|
||||
>>> url = u"https://api.github.com/repos/requests/requests/issues/comments/5804413"
|
||||
>>> url = u"https://api.github.com/repos/psf/requests/issues/comments/5804413"
|
||||
|
||||
>>> r = requests.patch(url=url, data=body, auth=auth)
|
||||
>>> r.status_code
|
||||
@@ -960,7 +1018,7 @@ library to use SSLv3::
|
||||
block=block, ssl_version=ssl.PROTOCOL_SSLv3)
|
||||
|
||||
.. _`described here`: https://www.kennethreitz.org/essays/the-future-of-python-http
|
||||
.. _`urllib3`: https://github.com/shazow/urllib3
|
||||
.. _`urllib3`: https://github.com/urllib3/urllib3
|
||||
|
||||
.. _blocking-or-nonblocking:
|
||||
|
||||
@@ -976,11 +1034,12 @@ response at a time. However, these calls will still block.
|
||||
|
||||
If you are concerned about the use of blocking IO, there are lots of projects
|
||||
out there that combine Requests with one of Python's asynchronicity frameworks.
|
||||
Some excellent examples are `requests-threads`_, `grequests`_, and `requests-futures`_.
|
||||
Some excellent examples are `requests-threads`_, `grequests`_, `requests-futures`_, and `httpx`_.
|
||||
|
||||
.. _`requests-threads`: https://github.com/requests/requests-threads
|
||||
.. _`grequests`: https://github.com/kennethreitz/grequests
|
||||
.. _`grequests`: https://github.com/spyoungtech/grequests
|
||||
.. _`requests-futures`: https://github.com/ross/requests-futures
|
||||
.. _`httpx`: https://github.com/encode/httpx
|
||||
|
||||
Header Ordering
|
||||
---------------
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
Authentication
|
||||
==============
|
||||
|
||||
.. image:: https://farm5.staticflickr.com/4258/35550409215_3b08d49d22_k_d.jpg
|
||||
|
||||
This document discusses using various kinds of authentication with Requests.
|
||||
|
||||
Many web services require authentication, and there are many different types.
|
||||
|
||||
@@ -3,41 +3,34 @@
|
||||
Installation of Requests
|
||||
========================
|
||||
|
||||
.. image:: https://farm5.staticflickr.com/4230/35550376215_da1bf77a8c_k_d.jpg
|
||||
|
||||
|
||||
This part of the documentation covers the installation of Requests.
|
||||
The first step to using any software package is getting it properly installed.
|
||||
|
||||
|
||||
$ pipenv install requests
|
||||
-------------------------
|
||||
$ python -m pip install requests
|
||||
--------------------------------
|
||||
|
||||
To install Requests, simply run this simple command in your terminal of choice::
|
||||
|
||||
$ pipenv install requests
|
||||
|
||||
If you don't have `pipenv <http://pipenv.org/>`_ installed (tisk tisk!), head over to the Pipenv website for installation instructions. Or, if you prefer to just use pip and don't have it installed,
|
||||
`this Python installation guide <https://docs.python-guide.org/starting/installation/>`_
|
||||
can guide you through the process.
|
||||
$ python -m pip install requests
|
||||
|
||||
Get the Source Code
|
||||
-------------------
|
||||
|
||||
Requests is actively developed on GitHub, where the code is
|
||||
`always available <https://github.com/requests/requests>`_.
|
||||
`always available <https://github.com/psf/requests>`_.
|
||||
|
||||
You can either clone the public repository::
|
||||
|
||||
$ git clone git://github.com/requests/requests.git
|
||||
$ git clone git://github.com/psf/requests.git
|
||||
|
||||
Or, download the `tarball <https://github.com/requests/requests/tarball/master>`_::
|
||||
Or, download the `tarball <https://github.com/psf/requests/tarball/master>`_::
|
||||
|
||||
$ curl -OL https://github.com/requests/requests/tarball/master
|
||||
$ curl -OL https://github.com/psf/requests/tarball/master
|
||||
# optionally, zipball is also available (for Windows users).
|
||||
|
||||
Once you have a copy of the source, you can embed it in your own Python
|
||||
package, or install it into your site-packages easily::
|
||||
|
||||
$ cd requests
|
||||
$ pip install .
|
||||
$ python -m pip install .
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
.. _introduction:
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
.. image:: https://farm5.staticflickr.com/4317/35198386374_1939af3de6_k_d.jpg
|
||||
|
||||
Philosophy
|
||||
----------
|
||||
|
||||
Requests was developed with a few :pep:`20` idioms in mind.
|
||||
|
||||
|
||||
#. Beautiful is better than ugly.
|
||||
#. Explicit is better than implicit.
|
||||
#. Simple is better than complex.
|
||||
#. Complex is better than complicated.
|
||||
#. Readability counts.
|
||||
|
||||
All contributions to Requests should keep these important rules in mind.
|
||||
|
||||
.. _`apache2`:
|
||||
|
||||
Apache2 License
|
||||
---------------
|
||||
|
||||
A large number of open source projects you find today are `GPL Licensed`_.
|
||||
While the GPL has its time and place, it should most certainly not be your
|
||||
go-to license for your next open source project.
|
||||
|
||||
A project that is released as GPL cannot be used in any commercial product
|
||||
without the product itself also being offered as open source.
|
||||
|
||||
The MIT, BSD, ISC, and Apache2 licenses are great alternatives to the GPL
|
||||
that allow your open-source software to be used freely in proprietary,
|
||||
closed-source software.
|
||||
|
||||
Requests is released under terms of `Apache2 License`_.
|
||||
|
||||
.. _`GPL Licensed`: https://opensource.org/licenses/gpl-license.php
|
||||
.. _`Apache2 License`: https://opensource.org/licenses/Apache-2.0
|
||||
|
||||
|
||||
Requests License
|
||||
----------------
|
||||
|
||||
.. include:: ../../LICENSE
|
||||
@@ -3,8 +3,6 @@
|
||||
Quickstart
|
||||
==========
|
||||
|
||||
.. image:: https://farm5.staticflickr.com/4259/35163667010_8bfcaef274_k_d.jpg
|
||||
|
||||
.. module:: requests.models
|
||||
|
||||
Eager to get started? This page gives a good introduction in how to get started
|
||||
@@ -93,7 +91,7 @@ again::
|
||||
|
||||
>>> r = requests.get('https://api.github.com/events')
|
||||
>>> r.text
|
||||
u'[{"repository":{"open_issues":0,"url":"https://github.com/...
|
||||
'[{"repository":{"open_issues":0,"url":"https://github.com/...
|
||||
|
||||
Requests will automatically decode content from the server. Most unicode
|
||||
charsets are seamlessly decoded.
|
||||
@@ -130,6 +128,9 @@ You can also access the response body as bytes, for non-text requests::
|
||||
|
||||
The ``gzip`` and ``deflate`` transfer-encodings are automatically decoded for you.
|
||||
|
||||
The ``br`` transfer-encoding is automatically decoded for you if a Brotli library
|
||||
like `brotli <https://pypi.org/project/brotli>`_ or `brotlicffi <https://pypi.org/project/brotli>`_ is installed.
|
||||
|
||||
For example, to create an image from binary data returned by a request, you can
|
||||
use the following code::
|
||||
|
||||
@@ -148,11 +149,13 @@ There's also a builtin JSON decoder, in case you're dealing with JSON data::
|
||||
|
||||
>>> r = requests.get('https://api.github.com/events')
|
||||
>>> r.json()
|
||||
[{u'repository': {u'open_issues': 0, u'url': 'https://github.com/...
|
||||
[{'repository': {'open_issues': 0, 'url': 'https://github.com/...
|
||||
|
||||
In case the JSON decoding fails, ``r.json()`` raises an exception. For example, if
|
||||
the response gets a 204 (No Content), or if the response contains invalid JSON,
|
||||
attempting ``r.json()`` raises ``ValueError: No JSON object could be decoded``.
|
||||
attempting ``r.json()`` raises ``simplejson.JSONDecodeError`` if simplejson is
|
||||
installed or raises ``ValueError: No JSON object could be decoded`` on Python 2 or
|
||||
``json.JSONDecodeError`` on Python 3.
|
||||
|
||||
It should be noted that the success of the call to ``r.json()`` does **not**
|
||||
indicate the success of the response. Some servers may return a JSON object in a
|
||||
@@ -215,7 +218,8 @@ Note: Custom headers are given less precedence than more specific sources of inf
|
||||
|
||||
* Authorization headers set with `headers=` will be overridden if credentials
|
||||
are specified in ``.netrc``, which in turn will be overridden by the ``auth=``
|
||||
parameter.
|
||||
parameter. Requests will search for the netrc file at `~/.netrc`, `~/_netrc`,
|
||||
or at the path specified by the `NETRC` environment variable.
|
||||
* Authorization headers will be removed if you get redirected off-host.
|
||||
* Proxy-Authorization headers will be overridden by proxy credentials provided in the URL.
|
||||
* Content-Length headers will be overridden when we can determine the length of the content.
|
||||
@@ -560,3 +564,6 @@ All exceptions that Requests explicitly raises inherit from
|
||||
-----------------------
|
||||
|
||||
Ready for more? Check out the :ref:`advanced <advanced>` section.
|
||||
|
||||
|
||||
If you're on the job market, consider taking `this programming quiz <https://triplebyte.com/a/b1i2FB8/requests-docs-1>`_. A substantial donation will be made to this project, if you find a job through this platform.
|
||||
|
||||
1
ext/LICENSE
Normal file
@@ -0,0 +1 @@
|
||||
Copyright 2019 Kenneth Reitz. All rights reserved.
|
||||
BIN
ext/flower-of-life.jpg
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
ext/kr-compressed.png
Normal file
|
After Width: | Height: | Size: 5.8 KiB |
BIN
ext/kr.png
Normal file
|
After Width: | Height: | Size: 9.2 KiB |
BIN
ext/psf-compressed.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
ext/psf.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
ext/requests-logo-compressed.png
Normal file
|
After Width: | Height: | Size: 188 KiB |
BIN
ext/requests-logo.png
Normal file
|
After Width: | Height: | Size: 188 KiB |
BIN
ext/ss-compressed.png
Normal file
|
After Width: | Height: | Size: 363 KiB |
BIN
ext/ss.png
Normal file
|
After Width: | Height: | Size: 363 KiB |
@@ -1,2 +1,3 @@
|
||||
[pytest]
|
||||
addopts = -p no:warnings
|
||||
addopts = -p no:warnings --doctest-modules
|
||||
doctest_optionflags= NORMALIZE_WHITESPACE ELLIPSIS
|
||||
@@ -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,26 +27,34 @@ 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.
|
||||
"""
|
||||
|
||||
import urllib3
|
||||
import chardet
|
||||
import warnings
|
||||
from .exceptions import RequestsDependencyWarning
|
||||
|
||||
try:
|
||||
from charset_normalizer import __version__ as charset_normalizer_version
|
||||
except ImportError:
|
||||
charset_normalizer_version = None
|
||||
|
||||
def check_compatibility(urllib3_version, chardet_version):
|
||||
try:
|
||||
from chardet import __version__ as chardet_version
|
||||
except ImportError:
|
||||
chardet_version = None
|
||||
|
||||
def check_compatibility(urllib3_version, chardet_version, charset_normalizer_version):
|
||||
urllib3_version = urllib3_version.split('.')
|
||||
assert urllib3_version != ['dev'] # Verify urllib3 isn't installed from git.
|
||||
|
||||
@@ -57,19 +65,24 @@ 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.24
|
||||
# urllib3 >= 1.21.1, <= 1.26
|
||||
assert major == 1
|
||||
assert minor >= 21
|
||||
assert minor <= 24
|
||||
|
||||
# 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
|
||||
assert minor <= 26
|
||||
|
||||
# Check charset_normalizer for compatibility.
|
||||
if chardet_version:
|
||||
major, minor, patch = chardet_version.split('.')[:3]
|
||||
major, minor, patch = int(major), int(minor), int(patch)
|
||||
# chardet_version >= 3.0.2, < 5.0.0
|
||||
assert (3, 0, 2) <= (major, minor, patch) < (5, 0, 0)
|
||||
elif charset_normalizer_version:
|
||||
major, minor, patch = charset_normalizer_version.split('.')[:3]
|
||||
major, minor, patch = int(major), int(minor), int(patch)
|
||||
# charset_normalizer >= 2.0.0 < 3.0.0
|
||||
assert (2, 0, 0) <= (major, minor, patch) < (3, 0, 0)
|
||||
else:
|
||||
raise Exception("You need either charset_normalizer or chardet installed")
|
||||
|
||||
def _check_cryptography(cryptography_version):
|
||||
# cryptography < 1.3.4
|
||||
@@ -84,20 +97,28 @@ def _check_cryptography(cryptography_version):
|
||||
|
||||
# Check imported dependencies for compatibility.
|
||||
try:
|
||||
check_compatibility(urllib3.__version__, chardet.__version__)
|
||||
check_compatibility(urllib3.__version__, chardet_version, charset_normalizer_version)
|
||||
except (AssertionError, ValueError):
|
||||
warnings.warn("urllib3 ({}) or chardet ({}) doesn't match a supported "
|
||||
"version!".format(urllib3.__version__, chardet.__version__),
|
||||
warnings.warn("urllib3 ({}) or chardet ({})/charset_normalizer ({}) doesn't match a supported "
|
||||
"version!".format(urllib3.__version__, chardet_version, charset_normalizer_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
|
||||
|
||||
# Check cryptography version
|
||||
from cryptography import __version__ as cryptography_version
|
||||
_check_cryptography(cryptography_version)
|
||||
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)
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
@@ -4,11 +4,11 @@
|
||||
|
||||
__title__ = 'requests'
|
||||
__description__ = 'Python HTTP for Humans.'
|
||||
__url__ = 'http://python-requests.org'
|
||||
__version__ = '2.20.1'
|
||||
__build__ = 0x022001
|
||||
__url__ = 'https://requests.readthedocs.io'
|
||||
__version__ = '2.26.0'
|
||||
__build__ = 0x022600
|
||||
__author__ = 'Kenneth Reitz'
|
||||
__author_email__ = 'me@kennethreitz.org'
|
||||
__license__ = 'Apache 2.0'
|
||||
__copyright__ = 'Copyright 2018 Kenneth Reitz'
|
||||
__copyright__ = 'Copyright 2020 Kenneth Reitz'
|
||||
__cake__ = u'\u2728 \U0001f370 \u2728'
|
||||
|
||||
@@ -16,10 +16,10 @@ 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 body of the :class:`Request`.
|
||||
in the query string for the :class:`Request`.
|
||||
:param data: (optional) Dictionary, list of tuples, bytes, or file-like
|
||||
object to send in the body of the :class:`Request`.
|
||||
:param json: (optional) A JSON serializable Python object to send in the body of 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]>
|
||||
"""
|
||||
|
||||
@@ -65,13 +66,12 @@ def get(url, params=None, **kwargs):
|
||||
|
||||
:param url: URL for the new :class:`Request` object.
|
||||
:param params: (optional) Dictionary, list of tuples or bytes to send
|
||||
in the body of the :class:`Request`.
|
||||
in the query string for the :class:`Request`.
|
||||
:param \*\*kwargs: Optional arguments that ``request`` takes.
|
||||
:return: :class:`Response <Response>` object
|
||||
:rtype: requests.Response
|
||||
"""
|
||||
|
||||
kwargs.setdefault('allow_redirects', True)
|
||||
return request('get', url, params=params, **kwargs)
|
||||
|
||||
|
||||
@@ -84,7 +84,6 @@ def options(url, **kwargs):
|
||||
:rtype: requests.Response
|
||||
"""
|
||||
|
||||
kwargs.setdefault('allow_redirects', True)
|
||||
return request('options', url, **kwargs)
|
||||
|
||||
|
||||
@@ -92,7 +91,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
|
||||
"""
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -8,7 +8,10 @@ This module handles import compatibility issues between Python 2 and
|
||||
Python 3.
|
||||
"""
|
||||
|
||||
import chardet
|
||||
try:
|
||||
import chardet
|
||||
except ImportError:
|
||||
import charset_normalizer as chardet
|
||||
|
||||
import sys
|
||||
|
||||
@@ -43,6 +46,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 +63,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
|
||||
|
||||
|
||||
@@ -25,6 +25,10 @@ class RequestException(IOError):
|
||||
super(RequestException, self).__init__(*args, **kwargs)
|
||||
|
||||
|
||||
class InvalidJSONError(RequestException):
|
||||
"""A JSON error occurred."""
|
||||
|
||||
|
||||
class HTTPError(RequestException):
|
||||
"""An HTTP error occurred."""
|
||||
|
||||
@@ -94,11 +98,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 +110,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
|
||||
|
||||
@@ -8,10 +8,19 @@ import ssl
|
||||
|
||||
import idna
|
||||
import urllib3
|
||||
import chardet
|
||||
|
||||
from . import __version__ as requests_version
|
||||
|
||||
try:
|
||||
import charset_normalizer
|
||||
except ImportError:
|
||||
charset_normalizer = None
|
||||
|
||||
try:
|
||||
import chardet
|
||||
except ImportError:
|
||||
chardet = None
|
||||
|
||||
try:
|
||||
from urllib3.contrib import pyopenssl
|
||||
except ImportError:
|
||||
@@ -71,7 +80,12 @@ def info():
|
||||
|
||||
implementation_info = _implementation()
|
||||
urllib3_info = {'version': urllib3.__version__}
|
||||
chardet_info = {'version': chardet.__version__}
|
||||
charset_normalizer_info = {'version': None}
|
||||
chardet_info = {'version': None}
|
||||
if charset_normalizer:
|
||||
charset_normalizer_info = {'version': charset_normalizer.__version__}
|
||||
if chardet:
|
||||
chardet_info = {'version': chardet.__version__}
|
||||
|
||||
pyopenssl_info = {
|
||||
'version': None,
|
||||
@@ -99,9 +113,11 @@ def info():
|
||||
'implementation': implementation_info,
|
||||
'system_ssl': system_ssl_info,
|
||||
'using_pyopenssl': pyopenssl is not None,
|
||||
'using_charset_normalizer': chardet is None,
|
||||
'pyOpenSSL': pyopenssl_info,
|
||||
'urllib3': urllib3_info,
|
||||
'chardet': chardet_info,
|
||||
'charset_normalizer': charset_normalizer_info,
|
||||
'cryptography': cryptography_info,
|
||||
'idna': idna_info,
|
||||
'requests': {
|
||||
|
||||
@@ -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
|
||||
@@ -29,7 +29,7 @@ from .auth import HTTPBasicAuth
|
||||
from .cookies import cookiejar_from_dict, get_cookie_header, _copy_cookie_jar
|
||||
from .exceptions import (
|
||||
HTTPError, MissingSchema, InvalidURL, ChunkedEncodingError,
|
||||
ContentDecodingError, ConnectionError, StreamConsumedError)
|
||||
ContentDecodingError, ConnectionError, StreamConsumedError, InvalidJSONError)
|
||||
from ._internal_utils import to_native_string, unicode_is_ascii
|
||||
from .utils import (
|
||||
guess_filename, get_auth_from_url, requote_uri,
|
||||
@@ -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:
|
||||
@@ -463,7 +466,12 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
|
||||
# urllib3 requires a bytes-like body. Python 2's json.dumps
|
||||
# provides this natively, but Python 3 gives a Unicode string.
|
||||
content_type = 'application/json'
|
||||
body = complexjson.dumps(json)
|
||||
|
||||
try:
|
||||
body = complexjson.dumps(json, allow_nan=False)
|
||||
except ValueError as ve:
|
||||
raise InvalidJSONError(ve, request=self)
|
||||
|
||||
if not isinstance(body, bytes):
|
||||
body = body.encode('utf-8')
|
||||
|
||||
@@ -472,12 +480,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 +616,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.
|
||||
@@ -723,7 +731,7 @@ class Response(object):
|
||||
|
||||
@property
|
||||
def apparent_encoding(self):
|
||||
"""The apparent encoding, provided by the chardet library."""
|
||||
"""The apparent encoding, provided by the charset_normalizer or chardet libraries."""
|
||||
return chardet.detect(self.content)['encoding']
|
||||
|
||||
def iter_content(self, chunk_size=1, decode_unicode=False):
|
||||
@@ -781,7 +789,7 @@ class Response(object):
|
||||
|
||||
return chunks
|
||||
|
||||
def iter_lines(self, chunk_size=ITER_CHUNK_SIZE, decode_unicode=None, delimiter=None):
|
||||
def iter_lines(self, chunk_size=ITER_CHUNK_SIZE, decode_unicode=False, delimiter=None):
|
||||
"""Iterates over the response data, one line at a time. When
|
||||
stream=True is set on the request, this avoids reading the
|
||||
content at once into memory for large responses.
|
||||
@@ -837,7 +845,7 @@ class Response(object):
|
||||
"""Content of the response, in unicode.
|
||||
|
||||
If Response.encoding is None, encoding will be guessed using
|
||||
``chardet``.
|
||||
``charset_normalizer`` or ``chardet``.
|
||||
|
||||
The encoding of the response content is determined based solely on HTTP
|
||||
headers, following RFC 2616 to the letter. If you can take advantage of
|
||||
@@ -874,13 +882,18 @@ class Response(object):
|
||||
r"""Returns the json-encoded content of a response, if any.
|
||||
|
||||
:param \*\*kwargs: Optional arguments that ``json.loads`` takes.
|
||||
:raises ValueError: If the response body does not contain valid json.
|
||||
:raises simplejson.JSONDecodeError: If the response body does not
|
||||
contain valid json and simplejson is installed.
|
||||
:raises json.JSONDecodeError: If the response body does not contain
|
||||
valid json and simplejson is not installed on Python 3.
|
||||
:raises ValueError: If the response body does not contain valid
|
||||
json and simplejson is not installed on Python 2.
|
||||
"""
|
||||
|
||||
if not self.encoding and self.content and len(self.content) > 3:
|
||||
# No encoding set. JSON RFC 4627 section 3 states we should expect
|
||||
# UTF-8, -16 or -32. Detect which one to use; If the detection or
|
||||
# decoding fails, fall back to `self.text` (using chardet to make
|
||||
# decoding fails, fall back to `self.text` (using charset_normalizer to make
|
||||
# a best guess).
|
||||
encoding = guess_json_utf(self.content)
|
||||
if encoding is not None:
|
||||
@@ -915,7 +928,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):
|
||||
|
||||
@@ -1,9 +1,17 @@
|
||||
import sys
|
||||
|
||||
try:
|
||||
import chardet
|
||||
except ImportError:
|
||||
import charset_normalizer as chardet
|
||||
import warnings
|
||||
|
||||
warnings.filterwarnings('ignore', 'Trying to detect', module='charset_normalizer')
|
||||
|
||||
# This code exists for backwards compatibility reasons.
|
||||
# I don't like it either. Just look the other way. :)
|
||||
|
||||
for package in ('urllib3', 'idna', 'chardet'):
|
||||
for package in ('urllib3', 'idna'):
|
||||
locals()[package] = __import__(package)
|
||||
# This traversal is apparently necessary such that the identities are
|
||||
# preserved (requests.packages.urllib3.* is urllib3.*)
|
||||
@@ -11,4 +19,8 @@ for package in ('urllib3', 'idna', 'chardet'):
|
||||
if mod == package or mod.startswith(package + '.'):
|
||||
sys.modules['requests.packages.' + mod] = sys.modules[mod]
|
||||
|
||||
target = chardet.__name__
|
||||
for mod in list(sys.modules):
|
||||
if mod == target or mod.startswith(target + '.'):
|
||||
sys.modules['requests.packages.' + target.replace(target, 'chardet')] = sys.modules[mod]
|
||||
# Kinda cool, though, right?
|
||||
|
||||
@@ -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
|
||||
@@ -624,7 +633,7 @@ class Session(SessionRedirectMixin):
|
||||
kwargs.setdefault('stream', self.stream)
|
||||
kwargs.setdefault('verify', self.verify)
|
||||
kwargs.setdefault('cert', self.cert)
|
||||
kwargs.setdefault('proxies', self.proxies)
|
||||
kwargs.setdefault('proxies', self.rebuild_proxies(request, self.proxies))
|
||||
|
||||
# It's possible that users might accidentally send a Request object.
|
||||
# Guard against that specific failure case.
|
||||
@@ -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"""
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -19,6 +19,8 @@ import sys
|
||||
import tempfile
|
||||
import warnings
|
||||
import zipfile
|
||||
from collections import OrderedDict
|
||||
from urllib3.util import make_headers
|
||||
|
||||
from .__version__ import __version__
|
||||
from . import certs
|
||||
@@ -26,7 +28,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
|
||||
@@ -40,6 +42,11 @@ DEFAULT_CA_BUNDLE_PATH = certs.where()
|
||||
|
||||
DEFAULT_PORTS = {'http': 80, 'https': 443}
|
||||
|
||||
# Ensure that ', ' is used to preserve previous delimiter behavior.
|
||||
DEFAULT_ACCEPT_ENCODING = ", ".join(
|
||||
re.split(r",\s*", make_headers(accept_encoding=True)["accept-encoding"])
|
||||
)
|
||||
|
||||
|
||||
if sys.platform == 'win32':
|
||||
# provide a proxy_bypass version on Windows without DNS lookups
|
||||
@@ -168,18 +175,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 +224,7 @@ def get_netrc_auth(url, raise_errors=False):
|
||||
if raise_errors:
|
||||
raise
|
||||
|
||||
# AppEngine hackiness.
|
||||
# App Engine hackiness.
|
||||
except (ImportError, AttributeError):
|
||||
pass
|
||||
|
||||
@@ -249,13 +262,28 @@ def extract_zipped_paths(path):
|
||||
|
||||
# we have a valid zip archive and a valid member of that archive
|
||||
tmp = tempfile.gettempdir()
|
||||
extracted_path = os.path.join(tmp, *member.split('/'))
|
||||
extracted_path = os.path.join(tmp, member.split('/')[-1])
|
||||
if not os.path.exists(extracted_path):
|
||||
extracted_path = zip_file.extract(member, path=tmp)
|
||||
|
||||
# use read + write to avoid the creating nested folders, we only want the file, avoids mkdir racing condition
|
||||
with atomic_open(extracted_path) as file_handler:
|
||||
file_handler.write(zip_file.read(member))
|
||||
return extracted_path
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def atomic_open(filename):
|
||||
"""Write a file to the disk in an atomic fashion"""
|
||||
replacer = os.rename if sys.version_info[0] == 2 else os.replace
|
||||
tmp_descriptor, tmp_name = tempfile.mkstemp(dir=os.path.dirname(filename))
|
||||
try:
|
||||
with os.fdopen(tmp_descriptor, 'wb') as tmp_handler:
|
||||
yield tmp_handler
|
||||
replacer(tmp_name, filename)
|
||||
except BaseException:
|
||||
os.remove(tmp_name)
|
||||
raise
|
||||
|
||||
|
||||
def from_key_val_list(value):
|
||||
"""Take an object and test to see if it can be represented as a
|
||||
dictionary. Unless it can not be represented as such, return an
|
||||
@@ -266,6 +294,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 +322,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 +524,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."""
|
||||
@@ -805,7 +841,7 @@ def default_headers():
|
||||
"""
|
||||
return CaseInsensitiveDict({
|
||||
'User-Agent': default_user_agent(),
|
||||
'Accept-Encoding': ', '.join(('gzip', 'deflate')),
|
||||
'Accept-Encoding': DEFAULT_ACCEPT_ENCODING,
|
||||
'Accept': '*/*',
|
||||
'Connection': 'keep-alive',
|
||||
})
|
||||
|
||||
8
requirements-dev.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
pytest>=2.8.0,<=3.10.1
|
||||
pytest-cov
|
||||
pytest-httpbin==1.0.0
|
||||
pytest-mock==2.0.0
|
||||
httpbin==0.7.0
|
||||
Flask>=1.0,<2.0
|
||||
trustme
|
||||
wheel
|
||||
28
setup.py
@@ -1,7 +1,6 @@
|
||||
#!/usr/bin/env python
|
||||
# Learn more: https://github.com/kennethreitz/setup.py
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
from codecs import open
|
||||
@@ -42,9 +41,11 @@ if sys.argv[-1] == 'publish':
|
||||
packages = ['requests']
|
||||
|
||||
requires = [
|
||||
'chardet>=3.0.2,<3.1.0',
|
||||
'idna>=2.5,<2.8',
|
||||
'urllib3>=1.21.1,<1.25',
|
||||
'charset_normalizer~=2.0.0; python_version >= "3"',
|
||||
'chardet>=3.0.2,<5; python_version < "3"',
|
||||
'idna>=2.5,<3; python_version < "3"',
|
||||
'idna>=2.5,<4; python_version >= "3"',
|
||||
'urllib3>=1.21.1,<1.27',
|
||||
'certifi>=2017.4.17'
|
||||
|
||||
]
|
||||
@@ -54,7 +55,7 @@ test_requirements = [
|
||||
'pytest-mock',
|
||||
'pytest-xdist',
|
||||
'PySocks>=1.5.6, !=1.5.7',
|
||||
'pytest>=2.8.0'
|
||||
'pytest>=3'
|
||||
]
|
||||
|
||||
about = {}
|
||||
@@ -63,8 +64,6 @@ with open(os.path.join(here, 'requests', '__version__.py'), 'r', 'utf-8') as f:
|
||||
|
||||
with open('README.md', 'r', 'utf-8') as f:
|
||||
readme = f.read()
|
||||
with open('HISTORY.md', 'r', 'utf-8') as f:
|
||||
history = f.read()
|
||||
|
||||
setup(
|
||||
name=about['__title__'],
|
||||
@@ -76,10 +75,10 @@ setup(
|
||||
author_email=about['__author_email__'],
|
||||
url=about['__url__'],
|
||||
packages=packages,
|
||||
package_data={'': ['LICENSE', 'NOTICE'], 'requests': ['*.pem']},
|
||||
package_data={'': ['LICENSE', 'NOTICE']},
|
||||
package_dir={'requests': 'requests'},
|
||||
include_package_data=True,
|
||||
python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*",
|
||||
python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*",
|
||||
install_requires=requires,
|
||||
license=about['__license__'],
|
||||
zip_safe=False,
|
||||
@@ -92,18 +91,23 @@ setup(
|
||||
'Programming Language :: Python :: 2',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.4',
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
'Programming Language :: Python :: 3.8',
|
||||
'Programming Language :: Python :: 3.9',
|
||||
'Programming Language :: Python :: Implementation :: CPython',
|
||||
'Programming Language :: Python :: Implementation :: PyPy'
|
||||
],
|
||||
cmdclass={'test': PyTest},
|
||||
tests_require=test_requirements,
|
||||
extras_require={
|
||||
'security': ['pyOpenSSL >= 0.14', 'cryptography>=1.3.4', 'idna>=2.0.0'],
|
||||
'security': [],
|
||||
'socks': ['PySocks>=1.5.6, !=1.5.7'],
|
||||
'socks:sys_platform == "win32" and python_version == "2.7"': ['win_inet_pton'],
|
||||
'use_chardet_on_py3': ['chardet>=3.0.2,<5']
|
||||
},
|
||||
project_urls={
|
||||
'Documentation': 'https://requests.readthedocs.io',
|
||||
'Source': 'https://github.com/psf/requests',
|
||||
},
|
||||
)
|
||||
|
||||
@@ -1,7 +1,19 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
try:
|
||||
from http.server import HTTPServer
|
||||
from http.server import SimpleHTTPRequestHandler
|
||||
except ImportError:
|
||||
from BaseHTTPServer import HTTPServer
|
||||
from SimpleHTTPServer import SimpleHTTPRequestHandler
|
||||
|
||||
import ssl
|
||||
import tempfile
|
||||
import threading
|
||||
|
||||
import pytest
|
||||
from requests.compat import urljoin
|
||||
import trustme
|
||||
|
||||
|
||||
def prepare_url(value):
|
||||
@@ -22,3 +34,25 @@ def httpbin(httpbin):
|
||||
@pytest.fixture
|
||||
def httpbin_secure(httpbin_secure):
|
||||
return prepare_url(httpbin_secure)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def nosan_server(tmp_path_factory):
|
||||
tmpdir = tmp_path_factory.mktemp("certs")
|
||||
ca = trustme.CA()
|
||||
# only commonName, no subjectAltName
|
||||
server_cert = ca.issue_cert(common_name=u"localhost")
|
||||
ca_bundle = str(tmpdir / "ca.pem")
|
||||
ca.cert_pem.write_to_path(ca_bundle)
|
||||
|
||||
context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
|
||||
server_cert.configure_cert(context)
|
||||
server = HTTPServer(("localhost", 0), SimpleHTTPRequestHandler)
|
||||
server.socket = context.wrap_socket(server.socket, server_side=True)
|
||||
server_thread = threading.Thread(target=server.serve_forever)
|
||||
server_thread.start()
|
||||
|
||||
yield "localhost", server.server_address[1], ca_bundle
|
||||
|
||||
server.shutdown()
|
||||
server_thread.join()
|
||||
|
||||
@@ -28,7 +28,7 @@ def test_digestauth_401_count_reset_on_redirect():
|
||||
"""Ensure we correctly reset num_401_calls after a successful digest auth,
|
||||
followed by a 302 redirect to another digest auth prompt.
|
||||
|
||||
See https://github.com/requests/requests/issues/1979.
|
||||
See https://github.com/psf/requests/issues/1979.
|
||||
"""
|
||||
text_401 = (b'HTTP/1.1 401 UNAUTHORIZED\r\n'
|
||||
b'Content-Length: 0\r\n'
|
||||
@@ -138,7 +138,7 @@ def test_digestauth_401_only_sent_once():
|
||||
def test_digestauth_only_on_4xx():
|
||||
"""Ensure we only send digestauth on 4xx challenges.
|
||||
|
||||
See https://github.com/requests/requests/issues/3772.
|
||||
See https://github.com/psf/requests/issues/3772.
|
||||
"""
|
||||
text_200_chal = (b'HTTP/1.1 200 OK\r\n'
|
||||
b'Content-Length: 0\r\n'
|
||||
|
||||
@@ -9,6 +9,7 @@ import pickle
|
||||
import collections
|
||||
import contextlib
|
||||
import warnings
|
||||
import re
|
||||
|
||||
import io
|
||||
import requests
|
||||
@@ -17,13 +18,13 @@ from requests.adapters import HTTPAdapter
|
||||
from requests.auth import HTTPDigestAuth, _basic_auth_str
|
||||
from requests.compat import (
|
||||
Morsel, cookielib, getproxies, str, urlparse,
|
||||
builtin_str, OrderedDict)
|
||||
builtin_str)
|
||||
from requests.cookies import (
|
||||
cookiejar_from_dict, morsel_to_cookie)
|
||||
from requests.exceptions import (
|
||||
ConnectionError, ConnectTimeout, InvalidSchema, InvalidURL,
|
||||
MissingSchema, ReadTimeout, Timeout, RetryError, TooManyRedirects,
|
||||
ProxyError, InvalidHeader, UnrewindableBodyError, SSLError, InvalidProxyURL)
|
||||
ProxyError, InvalidHeader, UnrewindableBodyError, SSLError, InvalidProxyURL, InvalidJSONError)
|
||||
from requests.models import PreparedRequest
|
||||
from requests.structures import CaseInsensitiveDict
|
||||
from requests.sessions import SessionRedirectMixin
|
||||
@@ -39,6 +40,9 @@ from urllib3.util import Timeout as Urllib3Timeout
|
||||
# listening on that port)
|
||||
TARPIT = 'http://10.255.255.1'
|
||||
|
||||
# This is to avoid waiting the timeout of using TARPIT
|
||||
INVALID_PROXY='http://localhost:1'
|
||||
|
||||
try:
|
||||
from ssl import SSLContext
|
||||
del SSLContext
|
||||
@@ -129,7 +133,7 @@ class TestRequests:
|
||||
assert request.url == expected
|
||||
|
||||
def test_params_original_order_is_preserved_by_default(self):
|
||||
param_ordered_dict = OrderedDict((('z', 1), ('a', 1), ('k', 1), ('d', 1)))
|
||||
param_ordered_dict = collections.OrderedDict((('z', 1), ('a', 1), ('k', 1), ('d', 1)))
|
||||
session = requests.Session()
|
||||
request = requests.Request('GET', 'http://example.com/', params=param_ordered_dict)
|
||||
prep = session.prepare_request(request)
|
||||
@@ -445,11 +449,11 @@ class TestRequests:
|
||||
def test_headers_preserve_order(self, httpbin):
|
||||
"""Preserve order when headers provided as OrderedDict."""
|
||||
ses = requests.Session()
|
||||
ses.headers = OrderedDict()
|
||||
ses.headers = collections.OrderedDict()
|
||||
ses.headers['Accept-Encoding'] = 'identity'
|
||||
ses.headers['First'] = '1'
|
||||
ses.headers['Second'] = '2'
|
||||
headers = OrderedDict([('Third', '3'), ('Fourth', '4')])
|
||||
headers = collections.OrderedDict([('Third', '3'), ('Fourth', '4')])
|
||||
headers['Fifth'] = '5'
|
||||
headers['Second'] = '222'
|
||||
req = requests.Request('GET', httpbin('get'), headers=headers)
|
||||
@@ -465,7 +469,7 @@ class TestRequests:
|
||||
@pytest.mark.parametrize('key', ('User-agent', 'user-agent'))
|
||||
def test_user_agent_transfers(self, httpbin, key):
|
||||
|
||||
heads = {key: 'Mozilla/5.0 (github.com/requests/requests)'}
|
||||
heads = {key: 'Mozilla/5.0 (github.com/psf/requests)'}
|
||||
|
||||
r = requests.get(httpbin('user-agent'), headers=heads)
|
||||
assert heads[key] in r.text
|
||||
@@ -550,6 +554,42 @@ class TestRequests:
|
||||
with pytest.raises(InvalidProxyURL):
|
||||
requests.get(httpbin(), proxies={'http': 'http:///example.com:8080'})
|
||||
|
||||
def test_respect_proxy_env_on_send_self_prepared_request(self, httpbin):
|
||||
with override_environ(http_proxy=INVALID_PROXY):
|
||||
with pytest.raises(ProxyError):
|
||||
session = requests.Session()
|
||||
request = requests.Request('GET', httpbin())
|
||||
session.send(request.prepare())
|
||||
|
||||
def test_respect_proxy_env_on_send_session_prepared_request(self, httpbin):
|
||||
with override_environ(http_proxy=INVALID_PROXY):
|
||||
with pytest.raises(ProxyError):
|
||||
session = requests.Session()
|
||||
request = requests.Request('GET', httpbin())
|
||||
prepared = session.prepare_request(request)
|
||||
session.send(prepared)
|
||||
|
||||
def test_respect_proxy_env_on_send_with_redirects(self, httpbin):
|
||||
with override_environ(http_proxy=INVALID_PROXY):
|
||||
with pytest.raises(ProxyError):
|
||||
session = requests.Session()
|
||||
url = httpbin('redirect/1')
|
||||
print(url)
|
||||
request = requests.Request('GET', url)
|
||||
session.send(request.prepare())
|
||||
|
||||
def test_respect_proxy_env_on_get(self, httpbin):
|
||||
with override_environ(http_proxy=INVALID_PROXY):
|
||||
with pytest.raises(ProxyError):
|
||||
session = requests.Session()
|
||||
session.get(httpbin())
|
||||
|
||||
def test_respect_proxy_env_on_request(self, httpbin):
|
||||
with override_environ(http_proxy=INVALID_PROXY):
|
||||
with pytest.raises(ProxyError):
|
||||
session = requests.Session()
|
||||
session.request(method='GET', url=httpbin())
|
||||
|
||||
def test_basicauth_with_netrc(self, httpbin):
|
||||
auth = ('user', 'pass')
|
||||
wrong_auth = ('wronguser', 'wrongpass')
|
||||
@@ -667,7 +707,7 @@ class TestRequests:
|
||||
post1 = requests.post(url, data={'some': 'data'})
|
||||
assert post1.status_code == 200
|
||||
|
||||
with open('Pipfile') as f:
|
||||
with open('requirements-dev.txt') as f:
|
||||
post2 = requests.post(url, files={'some': f})
|
||||
assert post2.status_code == 200
|
||||
|
||||
@@ -735,7 +775,7 @@ class TestRequests:
|
||||
post1 = requests.post(url, data={'some': 'data'})
|
||||
assert post1.status_code == 200
|
||||
|
||||
with open('Pipfile') as f:
|
||||
with open('requirements-dev.txt') as f:
|
||||
post2 = requests.post(url, data={'some': 'data'}, files={'some': f})
|
||||
assert post2.status_code == 200
|
||||
|
||||
@@ -772,9 +812,11 @@ class TestRequests:
|
||||
|
||||
def test_conflicting_post_params(self, httpbin):
|
||||
url = httpbin('post')
|
||||
with open('Pipfile') as f:
|
||||
pytest.raises(ValueError, "requests.post(url, data='[{\"some\": \"data\"}]', files={'some': f})")
|
||||
pytest.raises(ValueError, "requests.post(url, data=u('[{\"some\": \"data\"}]'), files={'some': f})")
|
||||
with open('requirements-dev.txt') as f:
|
||||
with pytest.raises(ValueError):
|
||||
requests.post(url, data='[{"some": "data"}]', files={'some': f})
|
||||
with pytest.raises(ValueError):
|
||||
requests.post(url, data=u('[{"some": "data"}]'), files={'some': f})
|
||||
|
||||
def test_request_ok_set(self, httpbin):
|
||||
r = requests.get(httpbin('status', '404'))
|
||||
@@ -832,8 +874,9 @@ class TestRequests:
|
||||
r = requests.get(httpbin(), cert='.')
|
||||
assert r.status_code == 200
|
||||
|
||||
def test_https_warnings(self, httpbin_secure, httpbin_ca_bundle):
|
||||
def test_https_warnings(self, nosan_server):
|
||||
"""warnings are emitted with requests.get"""
|
||||
host, port, ca_bundle = nosan_server
|
||||
if HAS_MODERN_SSL or HAS_PYOPENSSL:
|
||||
warnings_expected = ('SubjectAltNameWarning', )
|
||||
else:
|
||||
@@ -843,8 +886,7 @@ class TestRequests:
|
||||
|
||||
with pytest.warns(None) as warning_records:
|
||||
warnings.simplefilter('always')
|
||||
requests.get(httpbin_secure('status', '200'),
|
||||
verify=httpbin_ca_bundle)
|
||||
requests.get("https://localhost:{}/".format(port), verify=ca_bundle)
|
||||
|
||||
warning_records = [item for item in warning_records
|
||||
if item.category.__name__ != 'ResourceWarning']
|
||||
@@ -2211,7 +2253,7 @@ class TestTimeout:
|
||||
pass
|
||||
|
||||
def test_encoded_methods(self, httpbin):
|
||||
"""See: https://github.com/requests/requests/issues/2316"""
|
||||
"""See: https://github.com/psf/requests/issues/2316"""
|
||||
r = requests.request(b'GET', httpbin('get'))
|
||||
assert r.ok
|
||||
|
||||
@@ -2418,9 +2460,17 @@ class TestPreparingURLs(object):
|
||||
)
|
||||
)
|
||||
def test_preparing_url(self, url, expected):
|
||||
|
||||
def normalize_percent_encode(x):
|
||||
# Helper function that normalizes equivalent
|
||||
# percent-encoded bytes before comparisons
|
||||
for c in re.findall(r'%[a-fA-F0-9]{2}', x):
|
||||
x = x.replace(c, c.upper())
|
||||
return x
|
||||
|
||||
r = requests.Request('GET', url=url)
|
||||
p = r.prepare()
|
||||
assert p.url == expected
|
||||
assert normalize_percent_encode(p.url) == expected
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'url',
|
||||
@@ -2516,3 +2566,8 @@ class TestPreparingURLs(object):
|
||||
r = requests.Request('GET', url=input, params=params)
|
||||
p = r.prepare()
|
||||
assert p.url == expected
|
||||
|
||||
def test_post_json_nan(self, httpbin):
|
||||
data = {"foo": float("nan")}
|
||||
with pytest.raises(requests.exceptions.InvalidJSONError):
|
||||
r = requests.post(httpbin('post'), json=data)
|
||||
@@ -33,7 +33,8 @@ class TestSuperLen:
|
||||
'stream, value', (
|
||||
(StringIO.StringIO, 'Test'),
|
||||
(BytesIO, b'Test'),
|
||||
pytest.mark.skipif('cStringIO is None')((cStringIO, 'Test')),
|
||||
pytest.param(cStringIO, 'Test',
|
||||
marks=pytest.mark.skipif('cStringIO is None')),
|
||||
))
|
||||
def test_io_streams(self, stream, value):
|
||||
"""Ensures that we properly deal with different kinds of IO streams."""
|
||||
@@ -397,7 +398,7 @@ def test_get_auth_from_url(url, auth):
|
||||
),
|
||||
))
|
||||
def test_requote_uri_with_unquoted_percents(uri, expected):
|
||||
"""See: https://github.com/requests/requests/issues/2356"""
|
||||
"""See: https://github.com/psf/requests/issues/2356"""
|
||||
assert requote_uri(uri) == expected
|
||||
|
||||
|
||||
|
||||
@@ -96,6 +96,7 @@ class Server(threading.Thread):
|
||||
handler_result = self.handler(sock)
|
||||
|
||||
self.handler_results.append(handler_result)
|
||||
sock.close()
|
||||
|
||||
def _accept_connection(self):
|
||||
try:
|
||||
|
||||
18
tox.ini
@@ -1,8 +1,18 @@
|
||||
[tox]
|
||||
envlist = py27,py34,py35,py36
|
||||
envlist = py{27,36,37,38,39}-{default,use_chardet_on_py3}
|
||||
|
||||
[testenv]
|
||||
|
||||
deps = -rrequirements-dev.txt
|
||||
extras =
|
||||
security
|
||||
socks
|
||||
commands =
|
||||
pip install -e .[socks]
|
||||
python setup.py test
|
||||
pytest tests
|
||||
|
||||
[testenv:default]
|
||||
|
||||
[testenv:use_chardet_on_py3]
|
||||
extras =
|
||||
security
|
||||
socks
|
||||
use_chardet_on_py3
|
||||
|
||||