Compare commits

...

737 Commits

Author SHA1 Message Date
Nate Prewitt
b25c87d7cb v2.32.5
Some checks failed
Lint code / lint (push) Has been cancelled
Publish to PyPI / Build dists (push) Has been cancelled
Publish to PyPI / provenance (push) Has been cancelled
Publish to PyPI / Publish (push) Has been cancelled
Tests / build (macOS-latest, 3.10) (push) Has been cancelled
Tests / build (macOS-latest, 3.11) (push) Has been cancelled
Tests / build (macOS-latest, 3.12) (push) Has been cancelled
Tests / build (macOS-latest, 3.13) (push) Has been cancelled
Tests / build (macOS-latest, 3.14-dev) (push) Has been cancelled
Tests / build (macOS-latest, 3.9) (push) Has been cancelled
Tests / build (macOS-latest, pypy-3.10) (push) Has been cancelled
Tests / build (macOS-latest, pypy-3.11) (push) Has been cancelled
Tests / build (ubuntu-22.04, 3.10) (push) Has been cancelled
Tests / build (ubuntu-22.04, 3.11) (push) Has been cancelled
Tests / build (ubuntu-22.04, 3.12) (push) Has been cancelled
Tests / build (ubuntu-22.04, 3.13) (push) Has been cancelled
Tests / build (ubuntu-22.04, 3.14-dev) (push) Has been cancelled
Tests / build (ubuntu-22.04, 3.9) (push) Has been cancelled
Tests / build (ubuntu-22.04, pypy-3.10) (push) Has been cancelled
Tests / build (ubuntu-22.04, pypy-3.11) (push) Has been cancelled
Tests / build (windows-latest, 3.10) (push) Has been cancelled
Tests / build (windows-latest, 3.11) (push) Has been cancelled
Tests / build (windows-latest, 3.12) (push) Has been cancelled
Tests / build (windows-latest, 3.13) (push) Has been cancelled
Tests / build (windows-latest, 3.14-dev) (push) Has been cancelled
Tests / build (windows-latest, 3.9) (push) Has been cancelled
Tests / build (windows-latest, pypy-3.10) (push) Has been cancelled
Tests / No Character Detection (push) Has been cancelled
Tests / urllib3 1.x (push) Has been cancelled
2025-08-18 13:23:20 -07:00
Nate Prewitt
131e506079 Merge pull request #7010 from psf/dependabot/github_actions/actions/checkout-5.0.0
Bump actions/checkout from 4.2.0 to 5.0.0
2025-08-11 15:32:16 -07:00
dependabot[bot]
b336cb2bc6 Bump actions/checkout from 4.2.0 to 5.0.0
Bumps [actions/checkout](https://github.com/actions/checkout) from 4.2.0 to 5.0.0.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4.2.0...08c6903cd8c0fde910a37f88322edcfb5dd907a8)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 5.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-11 22:15:22 +00:00
Grant Birkinbine
46e939b552 Update publish workflow to use artifact-id instead of name
Added artifact-id output to publish workflow and updated download-artifact action version to `v5.0.0`. Also hardens the workflow a bit by adding `persist-credentials: false` to the checkout step
2025-08-06 07:36:19 -05:00
Nate Prewitt
4b9c546aa3 Merge pull request #6999 from psf/dependabot/github_actions/step-security/harden-runner-2.13.0
Bump step-security/harden-runner from 2.12.0 to 2.13.0
2025-07-28 12:09:42 -07:00
dependabot[bot]
7618dbef01 Bump step-security/harden-runner from 2.12.0 to 2.13.0
Bumps [step-security/harden-runner](https://github.com/step-security/harden-runner) from 2.12.0 to 2.13.0.
- [Release notes](https://github.com/step-security/harden-runner/releases)
- [Commits](0634a2670c...ec9f2d5744)

---
updated-dependencies:
- dependency-name: step-security/harden-runner
  dependency-version: 2.13.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-28 19:01:25 +00:00
Nate Prewitt
2edca11103 Add support for Python 3.14 and drop support for Python 3.8 (#6993)
* Add testing for Python 3.14 preview build

* Add trove classifier for Python 3.14

* Remove support for Python 3.8
2025-07-25 14:42:15 -06:00
Abhishek Jha
fec96cd597 Update Makefile rules (#6996) 2025-07-18 10:24:31 -06:00
Quaylyn Rimer
d58d8aa2f4 docs: clarify timeout parameter uses seconds in Session.request (#6994) 2025-07-18 02:09:19 +00:00
dependabot[bot]
91a3eabd3d Bump github/codeql-action from 3.28.5 to 3.29.0
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.28.5 to 3.29.0.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](f6091c0113...ce28f5bb42)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 3.29.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-16 14:10:36 -05:00
Nate Prewitt
90fee0876a Revert caching a default SSLContext (#6767) 2025-06-13 10:42:08 -06:00
AHMAD FAIZ
8ff173b186 Clarify error description in cloning instructions
This clarifies the error description in the 'Cloning the repository' section of the README. The current wording mentions 'an error about a bad commit', which is somewhat vague. I've updated it to 'an error about a bad commit timestamp', which more accurately describes the nature of the error referenced in issue #2690.
This small change improves the clarity of the documentation, helping users better understand the potential issue they might encounter when cloning the repository and why they need to use the specified Git flag.
2025-06-10 07:40:33 -05:00
Jonas Fonseca
3f07f990ac Fix typo in documentation for verify 2025-06-09 21:54:25 -05:00
Ian Stapleton Cordasco
e57b5bf05c Add Trusted Publishing Release Workflow
Rather than rely on manual releases from a developer laptop, let's use
tag pushes to trigger a workflow to publish artifacts to PyPI. This will
leverage trusted publishing and upload attestations as well.
2025-06-09 21:32:45 -05:00
Ian Stapleton Cordasco
021dc729f0 Polish up release tooling for last manual release
Some checks failed
Lint code / lint (push) Has been cancelled
Tests / build (macOS-latest, 3.10) (push) Has been cancelled
Tests / build (macOS-latest, 3.11) (push) Has been cancelled
Tests / build (macOS-latest, 3.12) (push) Has been cancelled
Tests / build (macOS-latest, 3.13) (push) Has been cancelled
Tests / build (macOS-latest, 3.8) (push) Has been cancelled
Tests / build (macOS-latest, 3.9) (push) Has been cancelled
Tests / build (macOS-latest, pypy-3.10) (push) Has been cancelled
Tests / build (macOS-latest, pypy-3.11) (push) Has been cancelled
Tests / build (ubuntu-22.04, 3.10) (push) Has been cancelled
Tests / build (ubuntu-22.04, 3.11) (push) Has been cancelled
Tests / build (ubuntu-22.04, 3.12) (push) Has been cancelled
Tests / build (ubuntu-22.04, 3.13) (push) Has been cancelled
Tests / build (ubuntu-22.04, 3.8) (push) Has been cancelled
Tests / build (ubuntu-22.04, 3.9) (push) Has been cancelled
Tests / build (ubuntu-22.04, pypy-3.10) (push) Has been cancelled
Tests / build (ubuntu-22.04, pypy-3.11) (push) Has been cancelled
Tests / build (windows-latest, 3.10) (push) Has been cancelled
Tests / build (windows-latest, 3.11) (push) Has been cancelled
Tests / build (windows-latest, 3.12) (push) Has been cancelled
Tests / build (windows-latest, 3.13) (push) Has been cancelled
Tests / build (windows-latest, 3.8) (push) Has been cancelled
Tests / build (windows-latest, 3.9) (push) Has been cancelled
Tests / build (windows-latest, pypy-3.10) (push) Has been cancelled
Tests / No Character Detection (push) Has been cancelled
Tests / urllib3 1.x (push) Has been cancelled
2025-06-09 11:39:48 -05:00
Ian Stapleton Cordasco
821770e822 Bump version and add release notes for v2.32.4 2025-06-09 11:39:48 -05:00
Piotr Szlazak
59f8aa2adf Add netrc file search information to authentication documentation (#6876) 2025-06-08 12:47:55 -05:00
Arthur Woimbée
5b4b64c346 Add more tests to prevent regression of CVE 2024 47081
Remove workaround not needed since py38 for os.path.expanduser.
2025-06-05 09:55:33 -05:00
danigm
7bc45877a8 Add new test to check netrc auth leak (#6962)
This patch adds a new test that reproduces the security issue reported
here:
https://seclists.org/oss-sec/2025/q2/204

Doing a request to a malicious url with a prefix like "domain.com:@"
will use the "domain.com" netrc credentials in the request to other
domain.
2025-06-05 06:21:46 -05:00
Nate Prewitt
96ba401c12 Only use hostname to do netrc lookup instead of netloc 2025-06-04 10:39:25 -05:00
Nate Prewitt
7341690e84 Merge pull request #6951 from tswast/patch-1 2025-06-01 11:07:17 -07:00
Tim Sweña
6716d7c9f2 remove links 2025-06-01 09:03:51 -05:00
Ian Stapleton Cordasco
a7e1c745dc Update docs/conf.py
Co-authored-by: Nate Prewitt <nate.prewitt@gmail.com>
2025-05-31 11:59:51 -05:00
Tim Sweña (Swast)
c799b8167a docs: fix dead links to kenreitz.org 2025-05-21 11:08:05 -05:00
Robin
c65c780849 Add two more tests exercising the adapter (#6936)
Closes #6935
2025-05-03 11:39:14 -05:00
Nate Prewitt
579cd9f233 Drop pypy 3.9 and add pypy 3.11 support 2025-05-01 21:54:57 -05:00
Nate Prewitt
c54d0347e2 Merge pull request #6939 from psf/dependabot/github_actions/actions/setup-python-5.6.0 2025-04-28 10:36:20 -07:00
dependabot[bot]
991f05dcd9 Bump actions/setup-python from 5.5.0 to 5.6.0
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5.5.0 to 5.6.0.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](8d9ed9ac5c...a26af69be9)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-version: 5.6.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-28 17:28:05 +00:00
Robin
4ce9520a1c Update lint workflow to ubuntu-24.04
Ubuntu 20.04 was the old default and is no longer supported by GitHub Actions
2025-04-23 07:44:05 -05:00
Ian Stapleton Cordasco
42a1dd640c Merge pull request #6924 from RichieB2B/rfc5280
Add key usage extension to test ca.crt
2025-04-15 21:46:50 -05:00
Nate Prewitt
c4c8e20289 Merge pull request #6925 from psf/dependabot/github_actions/actions/setup-python-5.5.0
Bump actions/setup-python from 5.4.0 to 5.5.0
2025-03-31 09:43:07 -07:00
dependabot[bot]
a5cb4284e1 Bump actions/setup-python from 5.4.0 to 5.5.0
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5.4.0 to 5.5.0.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](42375524e2...8d9ed9ac5c)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-31 16:31:10 +00:00
Richard van den Berg
2019450b43 Add key usage extension to test ca.crt 2025-03-29 14:53:45 +01:00
Nate Prewitt
1764cc938e Merge pull request #6899 from duzhuoshanwai/main
Docs: Add quotes to prevent Zsh wildcard interpretation.
2025-02-20 10:43:13 -08:00
duzhuoshanwai
e946665c59 Update advanced.rst
Add quotes to prevent Zsh wildcard interpretation.
2025-02-19 10:05:28 +08:00
Ian Stapleton Cordasco
8ba805fa93 Merge pull request #6897 from cjwatson/fix-test-certificates
Add CA constraint to test CA
2025-02-17 06:40:19 -06:00
Colin Watson
9ebebdef98 Regenerate test certificates
Created using the following command with OpenSSL 3.4.0:

    for cert in expired mtls valid/server; do
        make -C tests/certs/$cert clean all
    done
2025-02-17 00:41:30 +00:00
Colin Watson
5074096613 Add CA constraint to test CA
Otherwise recent versions of OpenSSL reject it as an invalid CA
certificate (at least once the test certificates are regenerated).

Fixes: #6896
2025-02-17 00:39:07 +00:00
Nate Prewitt
1b7c37ef4e Merge pull request #6529 from anupam-arista/patch-1 2025-02-13 08:49:49 -08:00
anupam-arista
5d31ddbf7b Update src/requests/models.py
Co-authored-by: Ian Stapleton Cordasco <graffatcolmingov@gmail.com>
2025-02-12 17:58:07 +05:30
anupam-arista
a2fd25ff34 Update models.py 2025-02-11 21:28:59 +05:30
anupam-arista
d96f9982a2 Update src/requests/models.py
Co-authored-by: Ian Stapleton Cordasco <graffatcolmingov@gmail.com>
2025-02-11 21:25:29 +05:30
anupam-arista
b25f2b5ec2 Merge branch 'psf:main' into patch-1 2025-02-11 07:49:26 +05:30
Nate Prewitt
f761e74a4d Merge pull request #6880 from jakobheine/td/remove-urlrequired-from-docs
docs(exceptions): Remove unused exception URLRequired from documentation
2025-02-10 13:13:26 -08:00
Nate Prewitt
f2a6ae5e32 Merge pull request #6883 from psf/dependabot/github_actions/actions/setup-python-5.4.0
Bump actions/setup-python from 5.3.0 to 5.4.0
2025-02-03 08:58:57 -08:00
dependabot[bot]
11f63a330b Bump actions/setup-python from 5.3.0 to 5.4.0
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5.3.0 to 5.4.0.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](0b93645e9f...42375524e2)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-03 16:27:40 +00:00
jakobheine
e361622fae docs(exceptions): Remove unused exception URLRequired from documentation
The documentation previously listed `requests.URLRequired` as a valid
exception, suggesting it would be raised for invalid URLs. However,
this exception has been dead code since commit ab27027 (2012) and is
never actually raised.

Instead, invalid URLs raise `MissingSchema`, `InvalidSchema`, or
`InvalidURL`, none of which were documented. This commit removes
`URLRequired` from the documentation to reflect the actual behavior
and prevent confusion.

Signed-off-by: jakobheine <me@jakobheine.de>
2025-02-01 19:42:06 +00:00
Nate Prewitt
fe0583ba49 Merge pull request #6875 from psf/dependabot/github_actions/github/codeql-action-3.28.5
Bump github/codeql-action from 3.27.0 to 3.28.5
2025-01-27 09:39:35 -08:00
dependabot[bot]
8c36da656d Bump github/codeql-action from 3.27.0 to 3.28.5
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.27.0 to 3.28.5.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](662472033e...f6091c0113)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-27 16:56:12 +00:00
anupam-arista
b653d80ded Merge branch 'psf:main' into patch-1 2024-12-13 05:08:45 +05:30
Ian Stapleton Cordasco
23540c93ca Merge pull request #6824 from psf/nateprewitt-patch-1
Remove old macOS runners
2024-11-10 10:18:36 -06:00
Nate Prewitt
ad959acfcf Remove old macOS runners 2024-11-09 22:50:30 -07:00
Nate Prewitt
a6cf27a77f Update vulnerability disclosure process (#6820)
* Update contact point for Vulnerability disclosures

* Fix RedHat Contact

* Point vulnerabilities.rst to our .SECURITY file
2024-11-02 13:13:02 -07:00
Nate Prewitt
ed0b1b5802 Merge pull request #6817 from psf/dependabot/github_actions/actions/setup-python-5.3.0
Bump actions/setup-python from 5.2.0 to 5.3.0
2024-10-28 10:24:23 -06:00
Nate Prewitt
1f16cffa43 Merge pull request #6818 from psf/dependabot/github_actions/github/codeql-action-3.27.0
Bump github/codeql-action from 3.26.0 to 3.27.0
2024-10-28 10:24:12 -06:00
dependabot[bot]
9787d0c09c Bump github/codeql-action from 3.26.0 to 3.27.0
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.26.0 to 3.27.0.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](eb055d739a...662472033e)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-28 16:05:20 +00:00
dependabot[bot]
26664fa578 Bump actions/setup-python from 5.2.0 to 5.3.0
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5.2.0 to 5.3.0.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](f677139bbe...0b93645e9f)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-28 16:05:11 +00:00
Nate Prewitt
7335bbf480 Merge pull request #6803 from psf/dependabot/github_actions/actions/checkout-4.2.0
Bump actions/checkout from 4.1.0 to 4.2.0
2024-09-30 10:32:21 -07:00
dependabot[bot]
0bff2d94e6 Bump actions/checkout from 4.1.0 to 4.2.0
Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.0 to 4.2.0.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](8ade135a41...d632683dd7)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-30 16:34:20 +00:00
Ian Stapleton Cordasco
1ae6fc3137 Merge pull request #6802 from graingert/3.13
start testing on 3.13rc
2024-09-19 06:19:03 -05:00
Thomas Grainger
5984296b6a Update tox.ini 2024-09-18 19:40:02 +01:00
Thomas Grainger
f519bbae33 add trove classifier for 3.13 2024-09-18 19:14:19 +01:00
Thomas Grainger
314e7c9c70 upgrade to pytest-httpbin 2.1.0 final 2024-09-18 16:36:43 +01:00
Thomas Grainger
92f10cec5b upgrade to pytest-httpbin 2.1.0rc1 2024-09-18 15:04:53 +01:00
Thomas Grainger
83e67c4485 use allow-prereleases: true instead of 3.13-dev 2024-09-18 15:04:08 +01:00
Thomas Grainger
0f5ef1be8c Merge branch 'main' of github.com:psf/requests into 3.13 2024-09-18 15:03:08 +01:00
Nate Prewitt
f12ccbef6d Merge pull request #6797 from psf/dependabot/github_actions/actions/setup-python-5.2.0 2024-09-02 10:37:44 -07:00
dependabot[bot]
173890a48e Bump actions/setup-python from 5.1.0 to 5.2.0
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5.1.0 to 5.2.0.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](82c7e631bb...f677139bbe)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-02 16:56:26 +00:00
Nate Prewitt
a3ce6f0075 Merge pull request #6787 from psf/dependabot/github_actions/github/codeql-action-3.26.0
Bump github/codeql-action from 3.25.0 to 3.26.0
2024-08-12 09:54:11 -07:00
dependabot[bot]
877892e67e Bump github/codeql-action from 3.25.0 to 3.26.0
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.25.0 to 3.26.0.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](df5a14dc28...eb055d739a)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-12 16:23:16 +00:00
Nate Prewitt
79b74ef704 Merge pull request #6757 from nateprewitt/urllib-1.x-tests 2024-07-29 18:44:13 -07:00
Branch Vincent
15e1f17bb6 remove setuptools test command 2024-07-29 08:49:17 -05:00
Nate Prewitt
01353d3b4a Invert major version check 2024-07-23 04:28:03 -07:00
Nate Prewitt
4e383642a9 Add conditional string encoding based on urllib3 major version 2024-07-18 10:20:38 -07:00
Nate Prewitt
f8aa36b92d Test on urllib3 1.26.x 2024-07-01 18:08:04 -07:00
anupam-arista
06d2a38441 Merge branch 'psf:main' into patch-1 2024-07-01 10:46:41 +05:30
Nate Prewitt
0e322af877 v2.32.3
Some checks failed
Lint code / lint (push) Has been cancelled
Tests / build (macOS-latest, 3.10) (push) Has been cancelled
Tests / build (macOS-latest, 3.11) (push) Has been cancelled
Tests / build (macOS-latest, 3.12) (push) Has been cancelled
Tests / build (macOS-latest, 3.8) (push) Has been cancelled
Tests / build (macOS-latest, 3.9) (push) Has been cancelled
Tests / build (macOS-latest, pypy-3.10) (push) Has been cancelled
Tests / build (macOS-latest, pypy-3.9) (push) Has been cancelled
Tests / build (macos-13, 3.8) (push) Has been cancelled
Tests / build (macos-13, 3.9) (push) Has been cancelled
Tests / build (ubuntu-22.04, 3.10) (push) Has been cancelled
Tests / build (ubuntu-22.04, 3.11) (push) Has been cancelled
Tests / build (ubuntu-22.04, 3.12) (push) Has been cancelled
Tests / build (ubuntu-22.04, 3.8) (push) Has been cancelled
Tests / build (ubuntu-22.04, 3.9) (push) Has been cancelled
Tests / build (ubuntu-22.04, pypy-3.10) (push) Has been cancelled
Tests / build (ubuntu-22.04, pypy-3.9) (push) Has been cancelled
Tests / build (windows-latest, 3.10) (push) Has been cancelled
Tests / build (windows-latest, 3.11) (push) Has been cancelled
Tests / build (windows-latest, 3.12) (push) Has been cancelled
Tests / build (windows-latest, 3.8) (push) Has been cancelled
Tests / build (windows-latest, 3.9) (push) Has been cancelled
Tests / build (windows-latest, pypy-3.10) (push) Has been cancelled
Tests / build (windows-latest, pypy-3.9) (push) Has been cancelled
Tests / No Character Detection (push) Has been cancelled
2024-05-29 08:36:10 -07:00
Nate Prewitt
e188799322 Don't create default SSLContext if ssl module isn't present (#6724) 2024-05-29 08:23:39 -07:00
Nate Prewitt
145b539948 Merge pull request #6716 from sigmavirus24/bug/6715 2024-05-24 14:37:06 -07:00
Nate Prewitt
b1d73ddb50 Don't use default SSLContext with custom poolmanager kwargs 2024-05-24 11:38:10 -07:00
Nate Prewitt
6badbac6e0 Update HISTORY.md 2024-05-24 11:38:06 -07:00
Nate Prewitt
2e1452234d Start testing on 3.13 beta 2024-05-23 11:51:07 -07:00
Ian Stapleton Cordasco
a62a2d35d9 Allow for overriding of specific pool key params
This re-enables the use case of providing a custom SSLContext via a
Transport Adapter as broken in #6655 and reported in #6715

Closes #6715
2024-05-22 06:53:24 -05:00
Nate Prewitt
88dce9d854 v2.32.2
Some checks failed
Lint code / lint (push) Has been cancelled
Tests / build (macOS-latest, 3.10) (push) Has been cancelled
Tests / build (macOS-latest, 3.11) (push) Has been cancelled
Tests / build (macOS-latest, 3.12) (push) Has been cancelled
Tests / build (macOS-latest, 3.8) (push) Has been cancelled
Tests / build (macOS-latest, 3.9) (push) Has been cancelled
Tests / build (macOS-latest, pypy-3.10) (push) Has been cancelled
Tests / build (macOS-latest, pypy-3.9) (push) Has been cancelled
Tests / build (macos-13, 3.8) (push) Has been cancelled
Tests / build (macos-13, 3.9) (push) Has been cancelled
Tests / build (ubuntu-22.04, 3.10) (push) Has been cancelled
Tests / build (ubuntu-22.04, 3.11) (push) Has been cancelled
Tests / build (ubuntu-22.04, 3.12) (push) Has been cancelled
Tests / build (ubuntu-22.04, 3.8) (push) Has been cancelled
Tests / build (ubuntu-22.04, 3.9) (push) Has been cancelled
Tests / build (ubuntu-22.04, pypy-3.10) (push) Has been cancelled
Tests / build (ubuntu-22.04, pypy-3.9) (push) Has been cancelled
Tests / build (windows-latest, 3.10) (push) Has been cancelled
Tests / build (windows-latest, 3.11) (push) Has been cancelled
Tests / build (windows-latest, 3.12) (push) Has been cancelled
Tests / build (windows-latest, 3.8) (push) Has been cancelled
Tests / build (windows-latest, 3.9) (push) Has been cancelled
Tests / build (windows-latest, pypy-3.10) (push) Has been cancelled
Tests / build (windows-latest, pypy-3.9) (push) Has been cancelled
Tests / No Character Detection (push) Has been cancelled
2024-05-21 11:49:22 -07:00
Nate Prewitt
c98e4d133e Merge pull request #6710 from nateprewitt/api_rename
Move _get_connection to get_connection_with_tls_context
2024-05-21 09:41:18 -07:00
Nate Prewitt
92075b330a Add deprecation warning 2024-05-21 09:28:30 -07:00
Nate Prewitt
aa1461b68a Move _get_connection to get_connection_with_tls_context 2024-05-21 05:42:49 -07:00
Nate Prewitt
970e8cec98 v2.32.1
Some checks failed
Lint code / lint (push) Has been cancelled
Tests / build (macOS-latest, 3.10) (push) Has been cancelled
Tests / build (macOS-latest, 3.11) (push) Has been cancelled
Tests / build (macOS-latest, 3.12) (push) Has been cancelled
Tests / build (macOS-latest, 3.8) (push) Has been cancelled
Tests / build (macOS-latest, 3.9) (push) Has been cancelled
Tests / build (macOS-latest, pypy-3.10) (push) Has been cancelled
Tests / build (macOS-latest, pypy-3.9) (push) Has been cancelled
Tests / build (macos-13, 3.8) (push) Has been cancelled
Tests / build (macos-13, 3.9) (push) Has been cancelled
Tests / build (ubuntu-22.04, 3.10) (push) Has been cancelled
Tests / build (ubuntu-22.04, 3.11) (push) Has been cancelled
Tests / build (ubuntu-22.04, 3.12) (push) Has been cancelled
Tests / build (ubuntu-22.04, 3.8) (push) Has been cancelled
Tests / build (ubuntu-22.04, 3.9) (push) Has been cancelled
Tests / build (ubuntu-22.04, pypy-3.10) (push) Has been cancelled
Tests / build (ubuntu-22.04, pypy-3.9) (push) Has been cancelled
Tests / build (windows-latest, 3.10) (push) Has been cancelled
Tests / build (windows-latest, 3.11) (push) Has been cancelled
Tests / build (windows-latest, 3.12) (push) Has been cancelled
Tests / build (windows-latest, 3.8) (push) Has been cancelled
Tests / build (windows-latest, 3.9) (push) Has been cancelled
Tests / build (windows-latest, pypy-3.10) (push) Has been cancelled
Tests / build (windows-latest, pypy-3.9) (push) Has been cancelled
Tests / No Character Detection (push) Has been cancelled
2024-05-20 15:02:29 -07:00
Nate Prewitt
d6ebc4a2f1 v2.32.0
Some checks failed
Lint code / lint (push) Has been cancelled
Tests / build (macOS-latest, 3.10) (push) Has been cancelled
Tests / build (macOS-latest, 3.11) (push) Has been cancelled
Tests / build (macOS-latest, 3.12) (push) Has been cancelled
Tests / build (macOS-latest, 3.8) (push) Has been cancelled
Tests / build (macOS-latest, 3.9) (push) Has been cancelled
Tests / build (macOS-latest, pypy-3.10) (push) Has been cancelled
Tests / build (macOS-latest, pypy-3.9) (push) Has been cancelled
Tests / build (macos-13, 3.8) (push) Has been cancelled
Tests / build (macos-13, 3.9) (push) Has been cancelled
Tests / build (ubuntu-22.04, 3.10) (push) Has been cancelled
Tests / build (ubuntu-22.04, 3.11) (push) Has been cancelled
Tests / build (ubuntu-22.04, 3.12) (push) Has been cancelled
Tests / build (ubuntu-22.04, 3.8) (push) Has been cancelled
Tests / build (ubuntu-22.04, 3.9) (push) Has been cancelled
Tests / build (ubuntu-22.04, pypy-3.10) (push) Has been cancelled
Tests / build (ubuntu-22.04, pypy-3.9) (push) Has been cancelled
Tests / build (windows-latest, 3.10) (push) Has been cancelled
Tests / build (windows-latest, 3.11) (push) Has been cancelled
Tests / build (windows-latest, 3.12) (push) Has been cancelled
Tests / build (windows-latest, 3.8) (push) Has been cancelled
Tests / build (windows-latest, 3.9) (push) Has been cancelled
Tests / build (windows-latest, pypy-3.10) (push) Has been cancelled
Tests / build (windows-latest, pypy-3.9) (push) Has been cancelled
Tests / No Character Detection (push) Has been cancelled
2024-05-20 08:46:49 -07:00
agubelu
9a40d12778 Avoid reloading root certificates to improve concurrent performance (#6667) 2024-05-15 14:07:26 -06:00
Ian Stapleton Cordasco
0c030f78d2 Merge pull request #6702 from nateprewitt/no_char_detection
Allow optional char detection dependencies in post-packaging
2024-05-14 19:15:19 -05:00
Nate Prewitt
555b870eb1 Allow character detection dependencies to be optional in post-packaging steps 2024-05-14 15:26:04 -07:00
Ian Stapleton Cordasco
d6dded3f00 Merge pull request #6700 from franekmagiera/update-redirect-to-invalid-uri-test
Use an invalid URI that will not cause httpbin to throw 500
2024-05-12 16:33:47 -05:00
franekmagiera
bf24b7d8d1 Use an invalid URI that will not cause httpbin to throw 500 2024-05-12 22:08:24 +02:00
Nate Prewitt
2d5f54779a Pin 3.8 and 3.9 runners back to macos-13 (#6688) 2024-04-23 10:50:19 -07:00
Nate Prewitt
f1bb07d39b Merge pull request #6687 from psf/dependabot/github_actions/github/codeql-action-3.25.0
Bump github/codeql-action from 3.24.0 to 3.25.0
2024-04-15 11:01:39 -06:00
dependabot[bot]
60047ade64 Bump github/codeql-action from 3.24.0 to 3.25.0
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.24.0 to 3.25.0.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](e8893c57a1...df5a14dc28)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-15 16:40:35 +00:00
Ian Stapleton Cordasco
31ebb8102c Merge pull request #6682 from frenzymadness/pytest8
Fix compatibility with pytest 8
2024-04-11 14:49:35 -05:00
Lumir Balhar
cc23d1c644 Fix compatibility with pytest 8
`pytest.warns(None)` has been deprecated in pytest 7.0.0
and it's no longer working in pytest 8.

Resolves: https://github.com/psf/requests/issues/6679
2024-04-11 21:10:36 +02:00
Nate Prewitt
0790ea4250 Merge pull request #6680 from mbeijen/rfc9110
Add rfc9110 HTTP status code names
2024-04-11 07:10:57 -07:00
Michiel W. Beijen
e45b428960 Add rfc9110 HTTP status code names
RFC 9110 _HTTP Semantics_ obsoletes some earlier RFCs which defined HTTP
1.1. It adds some status codes that were previously only used for
WebDAV to HTTP _proper_ after making the names somewhat more generic.

See https://www.rfc-editor.org/rfc/rfc9110.html#name-changes-from-rfc-7231

This commit adds the http status code names from that RFC.
2024-04-08 21:48:24 +02:00
Nate Prewitt
2a438c27b5 Merge pull request #6677 from psf/dependabot/github_actions/actions/setup-python-5.1.0
Bump actions/setup-python from 5.0.0 to 5.1.0
2024-04-01 10:36:47 -07:00
dependabot[bot]
2daa7b52a7 Bump actions/setup-python from 5.0.0 to 5.1.0
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5.0.0 to 5.1.0.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](0a5c615913...82c7e631bb)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-01 17:00:20 +00:00
Ian Stapleton Cordasco
8dd3b26bf5 Merge pull request #6302 from flysee/main
Fix the proxy_bypass_registry function all returning true in some cases.
2024-03-18 16:38:16 -05:00
flysee
13d892bdbe Additional should_bypass_proxies function test cases 2024-03-18 22:33:17 +08:00
flysee
1604e20fc8 Fix the proxy_bypass_registry function all returning true in some cases. 2024-03-18 15:36:36 +08:00
Ian Stapleton Cordasco
eeafb6ab3a Merge pull request #6662 from sigmavirus24/fix-tls-floppy
Add local TLS server
2024-03-14 06:25:24 -05:00
Ian Stapleton Cordasco
a94e9b5308 Add local TLS server
This also adds certificates for testing purposes and files to make it
easy to generate/regenerate them.

This also replaces an existing test of how we utilize our pool manager
such that we don't connect to badssl.com

Finally, this adds additional context parameters for our pool manager to
account for mTLS certificates used by clients to authenticate to a
server.
2024-03-14 06:06:22 -05:00
Ian Stapleton Cordasco
a58d7f2ffb Merge pull request #6655 from sigmavirus24/fix-tls-floppy
Use TLS settings in selecting connection pool
2024-03-11 06:21:59 -05:00
Ian Stapleton Cordasco
c0813a2d91 Use TLS settings in selecting connection pool
Previously, if someone made a request with `verify=False` then made a
request where they expected verification to be enabled to the same host,
they would potentially reuse a connection where TLS had not been
verified.

This fixes that issue.
2024-03-06 11:28:13 -06:00
Ian Stapleton Cordasco
eea3bbf9ac Merge pull request #6562 from amkarn258/issue-6223
every chardet package maps to requests.packages.chardet.* package respectively
2024-02-23 06:26:38 -06:00
Ian Stapleton Cordasco
f3f2611d83 Merge pull request #6583 from EFord36/fix-broken-links
Fix broken links in docs
2024-02-23 05:30:46 -06:00
Elliot Ford
a0e79bad05 update broken rfc link
ietf seems appropriate here - it's used elsewhere in the requets docs in
several places.
2024-02-23 10:26:21 +00:00
Elliot Ford
0a7f662aa7 Make example URL format a literal rather than an actual link
The rendered docs 'auto-link' this, which might encourage users to click
the link, even though it doesn't go anywhere.
2024-02-23 10:26:21 +00:00
Elliot Ford
5f1c3c22ff remove section with broken link to survey 2024-02-23 10:26:21 +00:00
Elliot Ford
541aa80ca3 update urllib3 docs link 2024-02-23 10:26:21 +00:00
Elliot Ford
d3b3399ece update authors github link
Update account link for original author which has changed.
2024-02-23 10:25:50 +00:00
Elliot Ford
0ec2780c29 update broken github pagination link 2024-02-23 10:25:50 +00:00
Ian Stapleton Cordasco
b8be93a721 Merge pull request #6589 from bruceadams/super_len_str_utf-8
Enhance `super_len` to count encoded bytes for str
2024-02-22 18:53:25 -06:00
Ian Stapleton Cordasco
3587a5f869 Merge pull request #6644 from sigmavirus24/bug/6643
Trim excess leading path separators
2024-02-22 18:49:42 -06:00
Ian Stapleton Cordasco
60389df6d6 Trim excess leading path separators
A URL with excess leading / (path-separator)s would cause urllib3 to
attempt to reparse the request-uri as a full URI with a host and port.
This bypasses that logic in ConnectionPool.urlopen by replacing these
leading /s with just a single /.

Closes #6643
2024-02-22 18:36:44 -06:00
Nate Prewitt
382fc2c0c6 Merge pull request #6629 from Tarty/fix-6628-jsondecode-error-not-deserializable
Fix #6628 - JSONDecodeError are not deserializable
2024-02-22 12:27:37 -08:00
Nate Prewitt
7a13c041db Merge pull request #6642 from nateprewitt/drop_python_37
Drop support for CPython 3.7
2024-02-20 15:44:43 -08:00
Nate Prewitt
58cea7a728 Drop support for CPython 3.7 2024-02-20 15:37:46 -08:00
Ian Stapleton Cordasco
9439fad038 Merge pull request #6641 from nateprewitt/fix_ci
Fix CI
2024-02-20 17:32:57 -06:00
Nate Prewitt
8fa4302322 Update Sphinx to work with latest readthedocs requirements 2024-02-20 15:04:38 -08:00
Nate Prewitt
28855fd43a Update supported copies of PyPy
Dropped support for pypy-3.7 and pypy-3.8 which are no longer maintained by upstream.
Added support for pypy-3.10.
2024-02-20 13:58:26 -08:00
Nate Prewitt
5fc10bf1f5 Fix httpbin pin for test suite 2024-02-20 13:37:25 -08:00
Ian Stapleton Cordasco
46c1a3d8c8 Merge pull request #6640 from nateprewitt/community_docs_cleanup
Cleanup defunct links from community docs page
2024-02-20 14:04:33 -06:00
Nate Prewitt
6106a63eb6 Cleanup defunct links from community docs page 2024-02-20 11:58:35 -08:00
Ian Stapleton Cordasco
4f3f189d6b Merge pull request #6632 from psf/dependabot/github_actions/github/codeql-action-3.24.0
Bump github/codeql-action from 3.23.0 to 3.24.0
2024-02-05 20:54:26 -06:00
dependabot[bot]
a5a0e4b587 Bump github/codeql-action from 3.23.0 to 3.24.0
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.23.0 to 3.24.0.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](e5f05b81d5...e8893c57a1)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-05 16:38:01 +00:00
Thomas Dehghani
3ff3ff21dd Fix #6628 - JSONDecodeError are not deserializable
requests.exceptions.JSONDecodeError are not deserializable: calling
`pickle.dumps` followed by `pickle.loads` will trigger an error.

This is particularly a problem in a process pool, as an attempt to
decode json on an invalid json document will result in the entire
process pool crashing.

This is due to the MRO of the `requests.exceptions.JSONDecodeError`
class: the `__reduce__` method called when pickling an instance is not
the one from the JSON library parent: two out of three args expected
for instantiation will be dropped, and the instance can't be
deserialised.

By specifying in the class which parent `__reduce__` method should be
called, the bug is fixed as all args are carried over in the resulting
pickled bytes.
2024-01-31 17:13:53 +01:00
Ian Stapleton Cordasco
96b22fa18c Merge pull request #6619 from psf/dependabot/github_actions/github/codeql-action-3.23.0
Bump github/codeql-action from 3.22.11 to 3.23.0
2024-01-08 11:56:01 -06:00
dependabot[bot]
b0e6c9bf85 Bump github/codeql-action from 3.22.11 to 3.23.0
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.22.11 to 3.23.0.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](b374143c11...e5f05b81d5)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-08 17:01:37 +00:00
Ian Stapleton Cordasco
72eccc8dd8 Merge pull request #6612 from miketheman/fix-docs-urls
docs: specify sphinx dirhtml builder, use references instead of absolutes
2023-12-23 12:33:48 -06:00
Mike Fiedler
25939d8784 add myself
Signed-off-by: Mike Fiedler <miketheman@gmail.com>
2023-12-23 18:15:33 +00:00
Mike Fiedler
bfba9dc68c docs: replace concrete URLs with references
Any development links will now refer back to the generated docs.

Signed-off-by: Mike Fiedler <miketheman@gmail.com>
2023-12-23 18:09:55 +00:00
Mike Fiedler
f23346a9b8 Revert "Merge pull request #6605 from jaikishpai/fix-#6604"
This reverts commit 1396eb6f7a, reversing
changes made to e4c821a247.
2023-12-23 17:36:34 +00:00
Ian Stapleton Cordasco
f3f9784419 Merge pull request #6613 from miketheman/add-socks-label
docs: add label to socks heading
2023-12-23 11:24:56 -06:00
Mike Fiedler
b5bd0f14cc docs: add label to socks heading
When trying to link via intersphinx, a label must be used.
Otherwise a full URL is required, which is less desirable.

Signed-off-by: Mike Fiedler <miketheman@gmail.com>
2023-12-23 17:17:34 +00:00
Mike Fiedler
242d3113c0 docs: specify sphinx dirhtml builder
With the requirement of a configuration file, the default builder
of `dirhtml` that RTD used to use is no longer specified.
This leads to URLs ending in `.html` now, which
breaks other exisitng references.

Refs: #6603
Refs: https://docs.readthedocs.io/en/stable/config-file/v2.html#sphinx-builder
Refs: https://www.sphinx-doc.org/en/master/usage/builders/index.html#sphinx.builders.dirhtml.DirectoryHTMLBuilder

Signed-off-by: Mike Fiedler <miketheman@gmail.com>
2023-12-23 16:16:50 +00:00
Nate Prewitt
1396eb6f7a Merge pull request #6605 from jaikishpai/fix-#6604
fix for ##6604
2023-12-19 22:17:55 -08:00
Nate Prewitt
e4c821a247 Merge pull request #6607 from psf/dependabot/github_actions/github/codeql-action-3.22.11
Bump github/codeql-action from 2.22.1 to 3.22.11
2023-12-18 09:30:42 -08:00
dependabot[bot]
421b1f1757 Bump github/codeql-action from 2.22.1 to 3.22.11
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 2.22.1 to 3.22.11.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](fdcae64e14...b374143c11)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-18 16:39:47 +00:00
Jaikish Pai
1447bccc05 fix for ##6604 2023-12-17 22:34:30 +01:00
Ian Stapleton Cordasco
3b5978fc5d Merge pull request #6592 from atatuzuner61/bug/6584
"TOO_EARLY" type definition for status code 425
2023-12-16 14:24:02 -06:00
Ian Stapleton Cordasco
1ddf014f47 Merge pull request #6600 from MestreLion/MestreLion-connection-timeout-note
Add note on connection timeout being larger than specified. Fix #5773
2023-12-16 07:30:18 -06:00
Ian Stapleton Cordasco
92f9e431c9 Update docs/user/advanced.rst
Add note about wall clock too
2023-12-16 07:29:50 -06:00
Ian Stapleton Cordasco
951dd15fa6 Update docs/user/advanced.rst
fix indentation for note so it renders properly
2023-12-16 07:26:23 -06:00
Ian Stapleton Cordasco
51d0d83eaf Merge pull request #6603 from nsoranzo/rtd_config
Add now mandatory readthedocs config file
2023-12-16 07:24:37 -06:00
Nicola Soranzo
c7c2ebf1a7 Add now mandatory readthedocs config file
Docs builds currently fail with:

```
Problem in your project's configuration. No default configuration file found at repository's root. See https://docs.readthedocs.io/en/stable/config-file/
```

See e.g. https://readthedocs.org/projects/requests/builds/22842479/
2023-12-15 20:59:56 +00:00
Rodrigo Silva
a64f32ba45 Add note on connection timeout being larger than specified. Fix #5773
On servers with multiple IPs, such as IPv4 and IPv6, `urllib3` tries each address sequentially until one successfully connects, using the specified timeout for _each_ attempt, leading to a total connection timeout that is a _multiple_ of the requested time.
2023-12-13 10:05:12 -03:00
Nate Prewitt
a25fde6989 Merge pull request #6599 from psf/dependabot/github_actions/actions/setup-python-5.0.0 2023-12-11 08:11:07 -08:00
dependabot[bot]
ba67dc8dcc Bump actions/setup-python from 4.7.0 to 5.0.0
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 4.7.0 to 5.0.0.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](61a6322f88...0a5c615913)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-11 16:07:15 +00:00
Nate Prewitt
769bc3ae5c Merge pull request #6596 from psf/fix-autoclose-automtaion
Update close-issues.yml
2023-12-01 09:18:02 -08:00
Ian Stapleton Cordasco
d6ffd868ee Update close-issues.yml
I noticed the auto-labeling was working but not the auto-closing. Looking at recent actions runs I see that we need to specify the token even if we're not giving our own special token. See https://github.com/psf/requests/actions/runs/7057701782/job/19211845073#step:2:13 for additional context, namely

```
 gh: To use GitHub CLI in a GitHub Actions workflow, set the GH_TOKEN environment variable. Example:
  env:
    GH_TOKEN: ${{ github.token }}
```
2023-12-01 08:05:59 -06:00
Bruce Adams
3fd309a5c1 Enhance super_len to count encoded bytes for str
This fixes issue #6586
2023-11-29 15:42:57 -05:00
Ata Tuzuner
ec84f2c539 Fixes to test 2023-11-29 12:27:18 -05:00
Ata Tuzuner
889910c77a Added tests for status code 425 definitions. 2023-11-29 12:24:15 -05:00
Ata Tuzuner
b37878d340 Too early definition added to 425 status code type 2023-11-28 18:12:22 -05:00
Bruce Adams
f6707042d8 Unit test for string containing multi-byte UTF-8
There are two tests here. One demonstrating existing, correct
behavior for `data=bytes`, and another, failing, test for the case
where `data=string` and the string contains multi-byte UTF-8.
2023-11-27 17:27:43 -05:00
Ian Stapleton Cordasco
0b4d494192 Merge pull request #6581 from EFord36/typo-fix
fix docstring typo: a -> as
2023-11-22 09:10:47 -06:00
Elliot Ford
15849947ec fix docstring typo: a -> as 2023-11-22 11:34:04 +00:00
Ian Stapleton Cordasco
c6de5a14e5 Merge pull request #6580 from psf/dependabot/github_actions/dessant/lock-threads-5.0.0
Bump dessant/lock-threads from 4.0.1 to 5.0.0
2023-11-20 10:37:07 -06:00
dependabot[bot]
e66a07b286 Bump dessant/lock-threads from 4.0.1 to 5.0.0
Bumps [dessant/lock-threads](https://github.com/dessant/lock-threads) from 4.0.1 to 5.0.0.
- [Release notes](https://github.com/dessant/lock-threads/releases)
- [Changelog](https://github.com/dessant/lock-threads/blob/main/CHANGELOG.md)
- [Commits](be8aa5be94...d42e5f4980)

---
updated-dependencies:
- dependency-name: dessant/lock-threads
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-20 16:28:17 +00:00
Nate Prewitt
9e98a8749a Merge pull request #6574 from msea1/matthew/fix_space 2023-11-15 23:44:49 -08:00
Matthew Carruth
c32b046243 Fix missing space in error message 2023-11-15 17:00:28 -08:00
mayank
89cde235be checkstyle 2023-11-04 23:20:21 +05:30
amkarn258
d7490c9d2d Update src/requests/packages.py
Co-authored-by: Ian Stapleton Cordasco <graffatcolmingov@gmail.com>
2023-10-31 22:36:39 +05:30
mayank
e9b1217cff added handling for chardet and charset_normalizer imports 2023-10-31 20:37:59 +05:30
mayank
ad761abcdd every chardet package maps to requests.packages.chardet.* package respectively 2023-10-31 00:50:10 +05:30
Nate Prewitt
839a8edec3 Merge pull request #6552 from swims-hjkl/issue/test_header_validation
#6551  - assert statements for test test_header_validation
2023-10-17 23:08:52 -07:00
sumedhrao7
a8e9c1b436 added assert statements into tests/test_requests/test_header_validation in regards to the issue #6551 2023-10-18 07:40:50 +05:30
Nate Prewitt
b55bb15c35 Merge pull request #6527 from sigmavirus24/update-templates
Autoclose specific issue templates
2023-10-11 09:29:20 -07:00
Ian Stapleton Cordasco
8187768622 Update close-issues.yml
Remove references to GITHUB_TOKEN/MY_TOKEN
2023-10-11 08:19:57 -05:00
Ian Stapleton Cordasco
f75b9504fc Update close comment
Co-authored-by: Nate Prewitt <nate.prewitt@gmail.com>
2023-10-11 08:19:14 -05:00
Nate Prewitt
8199a2b389 Merge pull request #6548 from psf/dependabot/github_actions/github/codeql-action-2.22.1
Bump github/codeql-action from 2.21.3 to 2.22.1
2023-10-09 09:49:28 -07:00
dependabot[bot]
42a3b5cce8 Bump github/codeql-action from 2.21.3 to 2.22.1
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 2.21.3 to 2.22.1.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](5b6282e01c...fdcae64e14)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-09 16:29:55 +00:00
Nate Prewitt
f5a7aefc2d Fix urllib3 pin in setup.cfg (#6545) 2023-10-06 16:34:24 -06:00
Nate Prewitt
ee93fac6b2 Merge pull request #6538 from psf/dependabot/github_actions/actions/checkout-4.1.0
Bump actions/checkout from 4.0.0 to 4.1.0
2023-09-25 11:30:05 -07:00
dependabot[bot]
a775435c4b Bump actions/checkout from 4.0.0 to 4.1.0
Bumps [actions/checkout](https://github.com/actions/checkout) from 4.0.0 to 4.1.0.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](3df4ab11eb...8ade135a41)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-25 16:28:35 +00:00
anupam-arista
12862617df Update models.Response.json docstring clearer 2023-09-14 14:29:37 +05:30
Ian Stapleton Cordasco
6c8d9b1d0f Autoclose specific issue templates
We spend a fair amount of time closing issues because people don't read
the template closely or understand what they're being told. Let's take
advantage of being able to auto-label an issue based on the template and
then trigger a workflow to auto-magically close the issue with a message
and lock the issue.
2023-09-13 09:33:58 -05:00
Ian Stapleton Cordasco
881281250f Merge pull request #6519 from psf/dependabot/github_actions/actions/checkout-4.0.0
Bump actions/checkout from 3.6.0 to 4.0.0
2023-09-04 19:17:08 -05:00
dependabot[bot]
29fc8d1e93 Bump actions/checkout from 3.6.0 to 4.0.0
Bumps [actions/checkout](https://github.com/actions/checkout) from 3.6.0 to 4.0.0.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](f43a0e5ff2...3df4ab11eb)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-04 16:21:27 +00:00
Ian Stapleton Cordasco
8b560ecb24 Merge pull request #6517 from jnhyperion/remove-pytest-ini
Remove pytest.ini in MANIFEST.in since it does not exist anymore
2023-08-29 09:27:10 -05:00
Johnny.H
4585a7fbda remove pytest.ini since it does not exist anymore 2023-08-29 13:41:49 +08:00
Ian Stapleton Cordasco
16dc70df34 Merge pull request #6516 from psf/dependabot/github_actions/actions/checkout-3.6.0
Bump actions/checkout from 3.5.3 to 3.6.0
2023-08-28 14:05:56 -05:00
dependabot[bot]
bea231b033 Bump actions/checkout from 3.5.3 to 3.6.0
Bumps [actions/checkout](https://github.com/actions/checkout) from 3.5.3 to 3.6.0.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](c85c95e3d7...f43a0e5ff2)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-28 16:12:37 +00:00
13steinj
2ee5b0b01c Fix documentation monthly download badge (#6508) 2023-08-18 11:01:26 -06:00
Jonas Schell
89f0eb91b3 fix monthly download badge (#6507) 2023-08-16 08:16:53 -07:00
Nate Prewitt
005571d118 Remove pytest-mock requirement (#6505) 2023-08-13 16:08:21 -07:00
Nate Prewitt
d63e94f552 Move to src directory (#6506) 2023-08-13 14:46:13 -07:00
Nate Prewitt
e9fa2e2da3 Add 3.12 classifier and tox configuration (#6503) 2023-08-13 12:56:18 -07:00
Nate Prewitt
678fca8423 Upgrade to httpbin 0.10.0 (#6496) 2023-08-13 09:56:53 -07:00
Nate Prewitt
d8152769ce Merge pull request #6501 from psf/dependabot/github_actions/actions/checkout-3.5.3 2023-08-12 13:15:39 -07:00
Nate Prewitt
9ff1a25ef5 Merge pull request #6502 from psf/dependabot/github_actions/github/codeql-action-2.21.3
Bump github/codeql-action from 1.1.39 to 2.21.3
2023-08-12 12:50:52 -07:00
dependabot[bot]
4bd06cd325 Bump actions/checkout from 2.7.0 to 3.5.3
Bumps [actions/checkout](https://github.com/actions/checkout) from 2.7.0 to 3.5.3.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v2.7.0...c85c95e3d7251135ab7dc9ce3241c5835cc595a9)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-12 19:37:22 +00:00
Nate Prewitt
09a241f59e Merge pull request #6500 from psf/dependabot/github_actions/actions/setup-python-4.7.0
Bump actions/setup-python from 2.3.4 to 4.7.0
2023-08-12 12:36:48 -07:00
Nate Prewitt
6ad493650c Merge pull request #6499 from psf/dependabot/github_actions/dessant/lock-threads-4.0.1
Bump dessant/lock-threads from 3.0.0 to 4.0.1
2023-08-12 12:24:59 -07:00
dependabot[bot]
9acca90bf6 Bump github/codeql-action from 1.1.39 to 2.21.3
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 1.1.39 to 2.21.3.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](231aa2c8a8...5b6282e01c)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-12 19:03:30 +00:00
dependabot[bot]
c7933453cf Bump actions/setup-python from 2.3.4 to 4.7.0
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 2.3.4 to 4.7.0.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v2.3.4...61a6322f88396a6271a6ee3565807d608ecaddd1)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-12 19:03:22 +00:00
dependabot[bot]
ea49261a27 Bump dessant/lock-threads from 3.0.0 to 4.0.1
Bumps [dessant/lock-threads](https://github.com/dessant/lock-threads) from 3.0.0 to 4.0.1.
- [Release notes](https://github.com/dessant/lock-threads/releases)
- [Changelog](https://github.com/dessant/lock-threads/blob/main/CHANGELOG.md)
- [Commits](e460dfeb36...be8aa5be94)

---
updated-dependencies:
- dependency-name: dessant/lock-threads
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-12 19:03:17 +00:00
Nate Prewitt
8112fcc7be Pre commit update (#6498) 2023-08-12 12:03:10 -07:00
Nate Prewitt
2c193bda0c Pin GHA workflows and add dependabot to keep them up to date (#6497) 2023-08-12 12:02:58 -07:00
Ian Stapleton Cordasco
34a64bc65e Merge pull request #6266 from elprimato/spdx-conform-license
Change to SPDX conform license string
2023-08-12 13:51:42 -05:00
Nate Prewitt
9b6c62e235 Merge branch 'main' into spdx-conform-license 2023-08-12 11:37:15 -07:00
Joren Vrancken
cb7fcd7ebd Specify that Session.headers needs to be set to a OrderedDict in Header Ordering docs (#6475) 2023-08-12 10:53:36 -07:00
Calle Svensson
aa4cc78627 Add note about adapter prefix match to docs (#6465) 2023-07-29 21:05:44 -07:00
Kevin Kirsche
dfe46c1b7f refactor: prefer dictionary comphrension to loop (#6187) 2023-07-29 18:55:18 -07:00
Alexandre Erwin Ittner
2ecdb68561 Update reference to "cookielib" to "cookiejar" in documentation (#6214) 2023-07-29 18:50:43 -07:00
cpzt
fecf3dc472 add docstring parameter hooks (#6456) 2023-07-29 18:01:42 -07:00
Matthew Armand
cdbc2e2715 Add an Example for automatic retries to the Advanced Usage docs (#6258)
- While Requests doesn't automatically retry failures, this ability is a very common advanced use case in real world applications.
- Although there's a mention of this ability on the HTTPAdapter class docs, it's a bit buried and not very specific.
- It makes sense then to have an Example in the HTTPAdapter section of the Advanced Usage docs with a basic template for how this can be accomplished with Requests.
2023-07-03 13:38:22 -07:00
Boris Verkhovskiy
22db55a889 Fix doc typo (#6467) 2023-06-26 11:09:23 -06:00
Nate Prewitt
6e5b15d542 Fix linting issues 2023-05-22 09:36:22 -06:00
Nate Prewitt
147c8511dd v2.31.0
Some checks failed
Lint code / lint (push) Has been cancelled
Tests / build (macOS-latest, 3.10) (push) Has been cancelled
Tests / build (macOS-latest, 3.11) (push) Has been cancelled
Tests / build (macOS-latest, 3.12-dev) (push) Has been cancelled
Tests / build (macOS-latest, 3.7) (push) Has been cancelled
Tests / build (macOS-latest, 3.8) (push) Has been cancelled
Tests / build (macOS-latest, 3.9) (push) Has been cancelled
Tests / build (macOS-latest, pypy-3.8) (push) Has been cancelled
Tests / build (macOS-latest, pypy-3.9) (push) Has been cancelled
Tests / build (ubuntu-22.04, 3.10) (push) Has been cancelled
Tests / build (ubuntu-22.04, 3.11) (push) Has been cancelled
Tests / build (ubuntu-22.04, 3.12-dev) (push) Has been cancelled
Tests / build (ubuntu-22.04, 3.7) (push) Has been cancelled
Tests / build (ubuntu-22.04, 3.8) (push) Has been cancelled
Tests / build (ubuntu-22.04, 3.9) (push) Has been cancelled
Tests / build (ubuntu-22.04, pypy-3.8) (push) Has been cancelled
Tests / build (ubuntu-22.04, pypy-3.9) (push) Has been cancelled
Tests / build (ubuntu-latest, pypy-3.7) (push) Has been cancelled
Tests / build (windows-latest, 3.10) (push) Has been cancelled
Tests / build (windows-latest, 3.11) (push) Has been cancelled
Tests / build (windows-latest, 3.12-dev) (push) Has been cancelled
Tests / build (windows-latest, 3.7) (push) Has been cancelled
Tests / build (windows-latest, 3.8) (push) Has been cancelled
Tests / build (windows-latest, 3.9) (push) Has been cancelled
Tests / build (windows-latest, pypy-3.8) (push) Has been cancelled
Tests / build (windows-latest, pypy-3.9) (push) Has been cancelled
2023-05-22 09:10:32 -06:00
Nate Prewitt
74ea7cf7a6 Merge pull request from GHSA-j8r2-6x86-q33q 2023-05-22 09:08:57 -06:00
Thomas Grainger
3022253346 test on pypy 3.8 and pypy 3.9 on windows and macos (#6424) 2023-05-15 09:04:21 -06:00
Thomas Grainger
b639e66c81 test on py3.12 (#6448)
* test on py3.12

* update to pytest-httpbin==2.0.0
2023-05-13 08:10:56 -06:00
Syed Saifullah
d3d504436e Fixed a small typo (#6452) 2023-05-09 10:55:33 -06:00
Nate Prewitt
2ad18e0e10 v2.30.0
Some checks failed
Lint code / lint (push) Has been cancelled
Tests / build (false, ubuntu-latest, pypy-3.7) (push) Has been cancelled
Tests / build (macOS-latest, 3.10) (push) Has been cancelled
Tests / build (macOS-latest, 3.11) (push) Has been cancelled
Tests / build (macOS-latest, 3.7) (push) Has been cancelled
Tests / build (macOS-latest, 3.8) (push) Has been cancelled
Tests / build (macOS-latest, 3.9) (push) Has been cancelled
Tests / build (ubuntu-22.04, 3.10) (push) Has been cancelled
Tests / build (ubuntu-22.04, 3.11) (push) Has been cancelled
Tests / build (ubuntu-22.04, 3.7) (push) Has been cancelled
Tests / build (ubuntu-22.04, 3.8) (push) Has been cancelled
Tests / build (ubuntu-22.04, 3.9) (push) Has been cancelled
Tests / build (windows-latest, 3.10) (push) Has been cancelled
Tests / build (windows-latest, 3.11) (push) Has been cancelled
Tests / build (windows-latest, 3.7) (push) Has been cancelled
Tests / build (windows-latest, 3.8) (push) Has been cancelled
Tests / build (windows-latest, 3.9) (push) Has been cancelled
2023-05-03 09:39:44 -06:00
Quentin Pradet
f2629e9e3c Remove strict parameter (#6434) 2023-04-28 13:17:10 -06:00
Nate Prewitt
87d63de873 v2.29.0
Some checks failed
Lint code / lint (push) Has been cancelled
Tests / build (false, ubuntu-latest, pypy-3.7) (push) Has been cancelled
Tests / build (macOS-latest, 3.10) (push) Has been cancelled
Tests / build (macOS-latest, 3.11) (push) Has been cancelled
Tests / build (macOS-latest, 3.7) (push) Has been cancelled
Tests / build (macOS-latest, 3.8) (push) Has been cancelled
Tests / build (macOS-latest, 3.9) (push) Has been cancelled
Tests / build (ubuntu-22.04, 3.10) (push) Has been cancelled
Tests / build (ubuntu-22.04, 3.11) (push) Has been cancelled
Tests / build (ubuntu-22.04, 3.7) (push) Has been cancelled
Tests / build (ubuntu-22.04, 3.8) (push) Has been cancelled
Tests / build (ubuntu-22.04, 3.9) (push) Has been cancelled
Tests / build (windows-latest, 3.10) (push) Has been cancelled
Tests / build (windows-latest, 3.11) (push) Has been cancelled
Tests / build (windows-latest, 3.7) (push) Has been cancelled
Tests / build (windows-latest, 3.8) (push) Has been cancelled
Tests / build (windows-latest, 3.9) (push) Has been cancelled
2023-04-26 09:19:11 -06:00
Thomas Grainger
51716c4ef3 enable the warnings plugin (#6416) 2023-04-22 18:00:22 -06:00
Thomas Grainger
a7da1ab349 try on ubuntu 22.04 (#6418) 2023-04-22 17:53:09 -06:00
Thomas Grainger
dfc3e24338 pin cryptography<40 on pypy 3.7 (#6421)
* pin cryptography<40 on pypy 3.7
2023-04-22 17:41:27 -06:00
Levi
26bea1e498 Use urllib3 native chunking ability (#6226)
* Fix #3844 
* Use urllib for chunked 

---------

Co-authored-by: James Pickering <james.pickering@xml-solutions.com>
Co-authored-by: Leon Verrall <LVerrall@slb.com>
2023-04-22 17:32:51 -06:00
Seth Michael Larson
7f694b79e1 Allow str/bytes subclasses to be used as header parts 2023-03-03 14:39:02 -06:00
Yifang Zhu
e90852d20c Make json doc strings consistent (#6368) 2023-03-02 21:32:49 -08:00
Nate Prewitt
ec78348c4b Upgrade lint.yml action (#6370) 2023-03-02 20:45:27 -08:00
Boris Verkhovskiy
46188256ee Response.raw.read() returns bytes (#6365) 2023-02-27 08:31:15 -07:00
Quentin Pradet
15585909c3 Support missing SNIMissingWarning in tests (#6336) 2023-01-21 01:44:33 -07:00
Matthew Feickert
16a17a3ca7 fix: Remove '<4' from python_requires (#6333)
* As discussed in https://discuss.python.org/t/use-of-less-than-next-major-version-e-g-4-in-python-requires-setup-py/1066
  and other places by the PyPA, use of upper bounds with python_requires
  for future versions of Python is unintended use of python_requires and
  actively discouraged.
2023-01-18 22:37:24 -07:00
Nate Prewitt
61c324da43 v2.28.2
Some checks failed
Lint code / lint (push) Has been cancelled
Tests / build (false, ubuntu-latest, pypy-3.7) (push) Has been cancelled
Tests / build (macOS-latest, 3.10) (push) Has been cancelled
Tests / build (macOS-latest, 3.11) (push) Has been cancelled
Tests / build (macOS-latest, 3.7) (push) Has been cancelled
Tests / build (macOS-latest, 3.8) (push) Has been cancelled
Tests / build (macOS-latest, 3.9) (push) Has been cancelled
Tests / build (ubuntu-18.04, 3.10) (push) Has been cancelled
Tests / build (ubuntu-18.04, 3.11) (push) Has been cancelled
Tests / build (ubuntu-18.04, 3.7) (push) Has been cancelled
Tests / build (ubuntu-18.04, 3.8) (push) Has been cancelled
Tests / build (ubuntu-18.04, 3.9) (push) Has been cancelled
Tests / build (windows-latest, 3.10) (push) Has been cancelled
Tests / build (windows-latest, 3.11) (push) Has been cancelled
Tests / build (windows-latest, 3.7) (push) Has been cancelled
Tests / build (windows-latest, 3.8) (push) Has been cancelled
Tests / build (windows-latest, 3.9) (push) Has been cancelled
2023-01-12 09:16:09 -07:00
Ashish Kurmi
eb07385b02 ci: add minimum GitHub token permissions for workflows (#6236)
Signed-off-by: Ashish Kurmi <akurmi@stepsecurity.io>
2023-01-11 15:06:53 -07:00
Bruno Alla
2745db131a Switch to Python 3.11 final on CI and add to tox file (#6325) 2023-01-06 11:32:31 -07:00
ch-iv
ec553c275f Update flake8 repo and version (#6317) 2022-12-25 21:24:16 -07:00
Ian Stapleton Cordasco
ac3be98b19 Merge pull request #6291 from oliviacrain/docs/git-clone-protocol
Replace git protocol URL in docs with an HTTPS URL
2022-11-21 16:06:01 -06:00
Olivia Crain
192083576d Replace git protocol URL in docs with an HTTPS URL 2022-11-21 14:01:02 -06:00
Volker Schaus
53a0562331 change to SPDX conform license string 2022-10-23 18:35:43 +00:00
Ian Stapleton Cordasco
1e62a3ec18 Merge pull request #6262 from winmorre/docs-update/#6260
JSONDecodeError included in the documentation
2022-10-21 11:37:47 -05:00
reeko234
7908ad3af9 JSONDecodeError included in the documentation #6260 2022-10-21 07:42:58 +00:00
deedy5
c57f1f0ca1 Allow charset normalizer >=2 and <4 (#6261) 2022-10-20 12:26:18 -06:00
Ian Stapleton Cordasco
7104ad4b13 Merge pull request #6234 from jaap3/patch-1
Fix CURL_CA_BUNDLE override example
2022-09-09 14:10:14 -05:00
Jaap Roes
da246958b4 Fix CURL_CA_BUNDLE override example
Promote REQUESTS_CA_BUNDLE as it is looked at first
2022-09-07 09:48:59 +02:00
David Cain
177dd90f18 Remove Python 2 mention on chardet behavior (#6204) 2022-07-27 09:22:21 -08:00
Miloslav Pojman
786255613b Remove Python 2 mention from tox (#6200) 2022-07-20 17:13:36 -06:00
Sergey Lyapustin
bda7f0171f Fixed warnings message to suggest using secure protocol. (#6188) 2022-06-29 12:41:49 -06:00
Nate Prewitt
4d394574f5 v2.28.1
Some checks failed
Lint code / lint (push) Has been cancelled
Tests / build (false, ubuntu-latest, pypy-3.7) (push) Has been cancelled
Tests / build (macOS-latest, 3.10) (push) Has been cancelled
Tests / build (macOS-latest, 3.11-dev) (push) Has been cancelled
Tests / build (macOS-latest, 3.7) (push) Has been cancelled
Tests / build (macOS-latest, 3.8) (push) Has been cancelled
Tests / build (macOS-latest, 3.9) (push) Has been cancelled
Tests / build (ubuntu-18.04, 3.10) (push) Has been cancelled
Tests / build (ubuntu-18.04, 3.11-dev) (push) Has been cancelled
Tests / build (ubuntu-18.04, 3.7) (push) Has been cancelled
Tests / build (ubuntu-18.04, 3.8) (push) Has been cancelled
Tests / build (ubuntu-18.04, 3.9) (push) Has been cancelled
Tests / build (windows-latest, 3.10) (push) Has been cancelled
Tests / build (windows-latest, 3.11-dev) (push) Has been cancelled
Tests / build (windows-latest, 3.7) (push) Has been cancelled
Tests / build (windows-latest, 3.8) (push) Has been cancelled
Tests / build (windows-latest, 3.9) (push) Has been cancelled
2022-06-29 09:09:11 -06:00
Kevin Kirsche
16b418b44a Use yield from instead of looping yield (#6170) 2022-06-28 20:08:26 -06:00
Lumír 'Frenzy' Balhar
0e28c8f1dc Allow charset normalizer >=2 and <3 (#6169) 2022-06-28 20:01:42 -06:00
Wong Hoi Sing Edison
73793ce43e Update Dependency with chardet>=3.0.2,<6 (#6179)
https://github.com/chardet/chardet/releases/tag/5.0.0 was released on
2022-06-25 with remove of Python 3.6 support, which also align with our
Python > 3.6 requirement.

Signed-off-by: Wong Hoi Sing Edison <hswong3i@pantarei-design.com>
2022-06-27 20:25:58 -06:00
Nate Prewitt
da9996fe4d v2.28.0
Some checks failed
Lint code / lint (push) Has been cancelled
Tests / build (false, ubuntu-latest, pypy-3.7) (push) Has been cancelled
Tests / build (macOS-latest, 3.10) (push) Has been cancelled
Tests / build (macOS-latest, 3.11-dev) (push) Has been cancelled
Tests / build (macOS-latest, 3.7) (push) Has been cancelled
Tests / build (macOS-latest, 3.8) (push) Has been cancelled
Tests / build (macOS-latest, 3.9) (push) Has been cancelled
Tests / build (ubuntu-18.04, 3.10) (push) Has been cancelled
Tests / build (ubuntu-18.04, 3.11-dev) (push) Has been cancelled
Tests / build (ubuntu-18.04, 3.7) (push) Has been cancelled
Tests / build (ubuntu-18.04, 3.8) (push) Has been cancelled
Tests / build (ubuntu-18.04, 3.9) (push) Has been cancelled
Tests / build (windows-latest, 3.10) (push) Has been cancelled
Tests / build (windows-latest, 3.11-dev) (push) Has been cancelled
Tests / build (windows-latest, 3.7) (push) Has been cancelled
Tests / build (windows-latest, 3.8) (push) Has been cancelled
Tests / build (windows-latest, 3.9) (push) Has been cancelled
2022-06-09 08:42:10 -06:00
Nate Prewitt
1dcf3b7122 Add GitHub action to automate linting (#6157) 2022-06-08 13:11:11 -06:00
Nate Prewitt
e36f34597c Add valdation for header name (#6154) 2022-06-08 12:03:56 -06:00
Nate Prewitt
60865f21ae Run 3.11 CI on all platforms (#6155) 2022-06-08 10:12:53 -06:00
Olivier Gayot
3af2f456d8 Fix output of test_lowlevel tests in case of timeout (#6136)
Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
2022-06-08 10:02:42 -06:00
Nate Prewitt
0f358eabe6 Reduce lock thread runs to daily (#6150) 2022-06-01 11:51:04 -06:00
Nate Prewitt
210095fd08 Tolerate bad registry entries in Windows proxy settings (#6149) 2022-06-01 11:36:26 -06:00
Nate Prewitt
a5e7169e75 Cleanup the docs sidebar (#6144) 2022-05-26 12:45:57 -07:00
davidshivaji
79f2ec3acc Grammar fix (#6133) 2022-05-13 10:36:13 -06:00
Mickaël Schoentgen
cb233a101d Fix several ResourceWarnings in test_requests.py (#4766) 2022-05-10 19:04:17 -06:00
Nate Prewitt
40956723f2 Add .git-blame-ignore-revs 2022-04-29 15:39:22 -06:00
Nate Prewitt
2a6f290bc0 Add automatic code formatting to Requests (#6095) 2022-04-29 13:16:58 -06:00
Nate Prewitt
2d5517682b Fix inconsistent exception for JSONDecode error (#6097)
When calling .json() it was possible to raise a
requests.exceptions.JSONDecodeError or ValueError
depending on whether the encoding is set.
2022-03-28 12:51:27 -06:00
Nate Prewitt
8bce583b95 Farewell, sweet Concorde!
Formally removing any remaining vestiges of Python 2 from Requests.
We'll also leave behind Python 3.6 while we're at it.
2022-03-25 10:50:33 -06:00
Ian Stapleton Cordasco
79f60274f7 Merge pull request #6074 from nateprewitt/curl_ca_bundle
Fix environment CA Bundle resolution
2022-02-26 07:39:28 -06:00
Nate Prewitt
79c4a017fe Fix environment CA Bundle resolution 2022-02-25 11:25:20 -07:00
Ian Stapleton Cordasco
5e749546a2 Merge pull request #6068 from nateprewitt/sess_prox_warn
Reword proxies section and add warning
2022-02-19 17:04:06 -06:00
Ian Stapleton Cordasco
3eed0512a6 Merge pull request #6069 from nateprewitt/jinja_fix
Pin markupsafe for older versions of Jinja2
2022-02-19 07:34:48 -06:00
Nate Prewitt
3ed60078e2 Fix jinja 2022-02-18 18:33:43 -07:00
Nate Prewitt
15fde024f2 Reword proxies section and add warning 2022-02-18 18:18:23 -07:00
Nate Prewitt
95f4567336 Wrap urllib3's SSLError as requests' SSLError (#6057) 2022-02-05 11:56:05 -07:00
Nate Prewitt
7ae38876b1 Merge pull request #5978 from sha016/all-proxy-docs
Co-authored-by: Seth Michael Larson <sethmichaellarson@gmail.com>
2022-02-02 11:03:26 -07:00
Seth Michael Larson
2c20474bfe Update advanced.rst 2022-02-02 11:56:27 -06:00
Chavithra
24dfbfde55 Update quickstart.rst : fixing brotlicffi link (#6044) 2022-01-17 11:30:24 -07:00
chyzzqo2
fa1b0a367a Initialize JsonDecodeError before initializing IOError (#6036)
That way we get the formated error message

Co-authored-by: Peter <cHYzZQo@netflix.com>
2022-01-13 08:42:49 -07:00
Ian Stapleton Cordasco
d15a3b6e2e Merge pull request #6042 from nateprewitt/lock_thread_spam
Disable lock-threads on forks
2022-01-11 11:42:00 -06:00
Nate Prewitt
48676caf57 Disable lock-threads on forks 2022-01-11 08:24:39 -07:00
Nate Prewitt
d718e75383 Start testing on 3.11 dev branch (#6037) 2022-01-07 12:07:31 -07:00
Marwan
620ed4fc52 Move socks testing requirement into requirements-dev.txt (#6035) 2022-01-06 10:57:59 -07:00
Nate Prewitt
31a89d9c84 v2.27.1
Some checks failed
Tests / build (macOS-latest, 2.7) (push) Has been cancelled
Tests / build (macOS-latest, 3.10) (push) Has been cancelled
Tests / build (macOS-latest, 3.6) (push) Has been cancelled
Tests / build (macOS-latest, 3.7) (push) Has been cancelled
Tests / build (macOS-latest, 3.8) (push) Has been cancelled
Tests / build (macOS-latest, 3.9) (push) Has been cancelled
Tests / build (ubuntu-18.04, 2.7) (push) Has been cancelled
Tests / build (ubuntu-18.04, 3.10) (push) Has been cancelled
Tests / build (ubuntu-18.04, 3.6) (push) Has been cancelled
Tests / build (ubuntu-18.04, 3.7) (push) Has been cancelled
Tests / build (ubuntu-18.04, 3.8) (push) Has been cancelled
Tests / build (ubuntu-18.04, 3.9) (push) Has been cancelled
Tests / build (ubuntu-latest, pypy-3.7) (push) Has been cancelled
Tests / build (ubuntu-latest, pypy3) (push) Has been cancelled
Tests / build (windows-latest, 2.7) (push) Has been cancelled
Tests / build (windows-latest, 3.10) (push) Has been cancelled
Tests / build (windows-latest, 3.6) (push) Has been cancelled
Tests / build (windows-latest, 3.7) (push) Has been cancelled
Tests / build (windows-latest, 3.8) (push) Has been cancelled
Tests / build (windows-latest, 3.9) (push) Has been cancelled
2022-01-05 08:35:04 -07:00
Ian Stapleton Cordasco
8fa9724398 Merge pull request #6028 from nateprewitt/prox_auth_fix
Fix auth parsing for proxies
2022-01-04 10:04:25 -06:00
Nate Prewitt
38f3f8ecb9 Fix auth parsing for proxies
Co-authored-by: adamp01 <@adamp01>
2022-01-04 08:27:23 -07:00
Nate Prewitt
0192aac241 v2.27.0
Some checks failed
Tests / build (macOS-latest, 2.7) (push) Has been cancelled
Tests / build (macOS-latest, 3.10) (push) Has been cancelled
Tests / build (macOS-latest, 3.6) (push) Has been cancelled
Tests / build (macOS-latest, 3.7) (push) Has been cancelled
Tests / build (macOS-latest, 3.8) (push) Has been cancelled
Tests / build (macOS-latest, 3.9) (push) Has been cancelled
Tests / build (ubuntu-18.04, 2.7) (push) Has been cancelled
Tests / build (ubuntu-18.04, 3.10) (push) Has been cancelled
Tests / build (ubuntu-18.04, 3.6) (push) Has been cancelled
Tests / build (ubuntu-18.04, 3.7) (push) Has been cancelled
Tests / build (ubuntu-18.04, 3.8) (push) Has been cancelled
Tests / build (ubuntu-18.04, 3.9) (push) Has been cancelled
Tests / build (ubuntu-latest, pypy-3.7) (push) Has been cancelled
Tests / build (ubuntu-latest, pypy3) (push) Has been cancelled
Tests / build (windows-latest, 2.7) (push) Has been cancelled
Tests / build (windows-latest, 3.10) (push) Has been cancelled
Tests / build (windows-latest, 3.6) (push) Has been cancelled
Tests / build (windows-latest, 3.7) (push) Has been cancelled
Tests / build (windows-latest, 3.8) (push) Has been cancelled
Tests / build (windows-latest, 3.9) (push) Has been cancelled
2022-01-03 07:59:10 -07:00
Nate Prewitt
e50dc12b0f Fix doc link 2022-01-02 22:20:40 -07:00
Nate Prewitt
17e6e27a93 General cleanup for 2.27.0 2021-12-29 16:29:09 -06:00
Greg Dubicki
ab38e2c726 Make the data vs json parameters more clear (#5382)
As https://stackoverflow.com/q/26685248/2693875 question
and answer popularity shows that there is a lot of people who
do not understand the distinction.
2021-12-29 10:46:21 -07:00
Nate Prewitt
77d1e9aa3e Merge pull request #5894 from dbaxa/do-not-re-build-proxies-when-proxies-have-been-provided
Prevent unnecessary should_bypass_proxies checks in rebuild_proxies
2021-12-29 10:06:05 -07:00
Ian Stapleton Cordasco
b0829a8690 Merge pull request #6020 from nateprewitt/pypy_37
Update 3.10-dev to 3.10 and add pypy-3.7 in CI
2021-12-29 07:32:11 -06:00
Ian Stapleton Cordasco
28d537dde3 Merge pull request #5917 from nateprewitt/proxy_scheme_unknown_fix
Move from urlparse to parse_url for prepending schemes
2021-12-29 07:31:40 -06:00
Nate Prewitt
86bbee71b2 Update 3.10-dev to 3.10 and add pypy-3.7 2021-12-28 22:28:30 -07:00
Nate Prewitt
0d5347e628 Only compute should_bypass_proxies if needed
Co-authored-by: David Black <dblack@atlassian.com>
2021-12-28 22:10:51 -07:00
Nate Prewitt
ef59aa0227 Move from urlparse to parse_url for prepending schemes 2021-12-28 21:12:00 -07:00
Ian Stapleton Cordasco
d09659997c Merge pull request #5414 from mondeja/5367
Raise InvalidUrl if host starts with '.' character.
2021-12-28 19:39:36 -06:00
Ian Stapleton Cordasco
2b06a952a9 Merge pull request #6017 from nateprewitt/schema2scheme
Fix erroneous use of 'schema' instead of 'scheme'
2021-12-28 19:39:08 -06:00
Ian Stapleton Cordasco
e2064a2c05 Merge pull request #6018 from nateprewitt/basic_auth_update
Update basic auth example
2021-12-28 19:38:35 -06:00
Nate Prewitt
401e17bbdc Update basic auth example 2021-12-28 18:07:01 -07:00
Nate Prewitt
4246792b81 Fix erroneous use of 'schema' instead of 'scheme' 2021-12-28 17:32:48 -07:00
Álvaro Mondéjar
658c10e84a Raise InvalidURL if hosts starts with '.' as was reported at #5367. 2021-12-28 14:24:24 -07:00
Abhinav Vashisth
39d0fdd909 Update README.md (#5998) 2021-12-05 02:52:10 -08:00
Ian Stapleton Cordasco
c193d9742e Merge pull request #5993 from davisagli/tox-parallel
Run tox in parallel using -p instead of detox
2021-11-30 08:07:59 -06:00
David Glick
8e764f355d Run tox in parallel using -p instead of detox 2021-11-29 22:20:47 -05:00
Nate Prewitt
7556ea4213 Merge pull request #5391 from hodbn/fix-5274
Send only one Host header in chunked request
2021-11-29 07:58:31 -08:00
David Hotham
2d2447e210 Catch AttributeError in utils.super_len (#5239)
* Catch AttributeError in utils.super_len

This allows it to handle files obtained via `Tarfile.extractfile()`.
2021-11-28 12:04:49 -08:00
Ian Stapleton Cordasco
e77dd8de6e Merge pull request #5990 from mgorny/trustme-test-dep
Skip the test requiring trustme when it is not available
2021-11-27 19:20:17 -06:00
Michał Górny
55da533a87 Defer the trustme import until inside the fixture
Move the trustme import from global scope into the nosan_server fixture
in order to make it possible to deselect the test via command-line
when trustme is not available.
2021-11-27 18:47:56 +01:00
Nate Prewitt
99b3b49241 Refactor rebuild_proxies to allow proxy resolution (#5924)
without stripping Proxy-Authorization header
2021-11-24 13:21:01 -06:00
sha016
e2fa8d3654 mention all_proxy env variable in Proxies section 2021-11-13 20:58:30 -06:00
Alan Yee
590350f8d0 Update Bug_report.md (#5965)
Add some highlighting and comment out the instructions so that the submitter can see it but it is not displayed in the GitHub issue
2021-10-21 11:06:33 -07:00
Nate Prewitt
9dd6e47b5b Add doc build requirements for RTD (#5956) 2021-10-09 15:03:33 -07:00
Борис Верховский
94f9f7357e Don't mention pip as the reason for supporting py2 (#5940) 2021-09-21 16:22:12 -07:00
Kevin Kirsche
fc106ab586 fix minor typos (#5934) 2021-09-15 06:43:12 -05:00
Ian Stapleton Cordasco
1e5fad7433 Update lock-issues.yml (#5930)
Run this hourly. I'm not seeing any effects, let's see if
running it more frequently will allow it to avoid the GitHub ratelimit

https://github.com/dessant/lock-threads#why-are-only-some-issues-and-pull-requests-processed
2021-09-07 17:00:31 -07:00
Nate Prewitt
248122a697 Add support for 3.10 (#5928) 2021-09-03 19:03:15 -07:00
Nate Prewitt
9572d6a299 General doc updates (#5923) 2021-09-02 08:53:46 -07:00
Nate Prewitt
4ab2550d66 Add test for default chunked Host header 2021-09-02 01:53:34 -07:00
hodbn
6fbfca90b6 Send only one Host header in chunked request
Closes #5274
2021-09-02 00:53:08 -07:00
Ben Li-Sauerwine
aae78010e9 Time out requests' tests after 10 minutes. (#5916) 2021-08-27 11:49:51 -07:00
Nate Prewitt
10968357a1 Appropriately handle urllib3's InvalidHeader exception (#5914) 2021-08-26 20:11:30 -05:00
Nate Prewitt
b351e906b6 Update codeql branch target (#5913) 2021-08-26 05:58:35 -05:00
Nate Prewitt
70a13e2a26 Fix syntax error in lock action (#5912) 2021-08-25 18:04:43 -07:00
Ian Stapleton Cordasco
8ea90a5ce7 Shorten the window before we lock threads
Per Nate's recommendation, let's lock things after 90 days rather than
360
2021-08-25 11:44:57 -07:00
Ian Stapleton Cordasco
7adb8686ac Add thread locker workflow (#5909) 2021-08-25 13:21:35 -05:00
Борис Верховский
827b87b9be Formatting (#5910) 2021-08-25 09:48:30 -07:00
Ben Li-Sauerwine
2d30aeb7c6 Add a test which verifies that ChunkedEncodingError is emitted if an invalid Transfer-Encoding: chunked response is returned. (#5906) 2021-08-24 19:00:17 -07:00
Israel Tsadok
b0e025ade7 Fix broken link to adapters essay (#5899) 2021-08-03 22:58:51 -07:00
Thomas Lam
d8829f9f24 Fix extract_zipped_paths infinite loop when provided invalid unc path (#5851) 2021-08-02 19:40:34 -05:00
Michał Górny
b227e3cb82 Fix creating non-listening sockets in tests on some platforms (#5890)
Fix the listen() invocation for the test server not to pass a backlog
value of zero.  The value of zero means no backlog which effectively
means that the socket can not accept any connections.  This does not
matter for the majority of platforms since the value is only advisory
and the platform tends to go with a bigger backlog anyway.  However,
a few platforms (e.g. alpha or riscv Linux) do take the value literally,
and therefore the tests fail since they are unable to connect to
the server.
2021-07-28 11:23:08 -05:00
Steve Berdy
db575eeedc Fix inconsistent exception type in response.json() method (#5856) 2021-07-26 08:56:44 -07:00
Jeremy Cline
941a77f2b8 docs: Update the Red Hat vulnerabilities contact (#5881) 2021-07-19 09:44:02 -07:00
Egor
a3d54b83f7 Update advanced.rst (#5821)
* Update advanced.rst

* remove confusing euphemism
2021-07-18 05:59:37 -05:00
Steve Berdy
a5b45edf2f Update api.rst (#5877) 2021-07-16 11:06:42 -07:00
Nate Prewitt
a1a6a549a0 v2.26.0
Some checks failed
Tests / build (macOS-latest, 2.7) (push) Has been cancelled
Tests / build (macOS-latest, 3.6) (push) Has been cancelled
Tests / build (macOS-latest, 3.7) (push) Has been cancelled
Tests / build (macOS-latest, 3.8) (push) Has been cancelled
Tests / build (macOS-latest, 3.9) (push) Has been cancelled
Tests / build (ubuntu-18.04, 2.7) (push) Has been cancelled
Tests / build (ubuntu-18.04, 3.6) (push) Has been cancelled
Tests / build (ubuntu-18.04, 3.7) (push) Has been cancelled
Tests / build (ubuntu-18.04, 3.8) (push) Has been cancelled
Tests / build (ubuntu-18.04, 3.9) (push) Has been cancelled
Tests / build (ubuntu-latest, pypy3) (push) Has been cancelled
Tests / build (windows-latest, 2.7) (push) Has been cancelled
Tests / build (windows-latest, 3.6) (push) Has been cancelled
Tests / build (windows-latest, 3.7) (push) Has been cancelled
Tests / build (windows-latest, 3.8) (push) Has been cancelled
Tests / build (windows-latest, 3.9) (push) Has been cancelled
2021-07-13 07:52:02 -07:00
Quentin Pradet
e253eba5ed Stop abusing pytest-httpbin to test commonName support
pytest-httpbin<1.0 ships with a server certificate with a commonName but
no subjectAltName. urllib3 2.0 will stop supporting those in the future,
so we want to upgrade pytest-httpbin.

Unfortunately, `test_https_warnings` was relying on this broken
certificate. With this change, we use `trustme` to create a broken
certificate specifically for this test, so that we can upgrade
pytest-httpbin and make sure that other tests relying on httpbin TLS
support will continue to work with urllib3 2.0.
2021-07-12 09:44:43 -05:00
Nate Prewitt
f6c0619d89 Disable requests[security] and remove 3.5 support references 2021-07-09 12:40:55 -07:00
Naor Livne
33cf965f72 Allow idna 3.x to be installed on Python 3.x
Co-authored-by: Mickaël Schoentgen <contact@tiger-222.fr>
Co-authored-by: Seth Michael Larson <sethmichaellarson@gmail.com>
2021-07-07 08:25:20 -05:00
Дилян Палаузов
5351469472 Add support for brotli decoding (#5783)
* Add support for Brotli decoding

When the brotli or brotlicffi packages are installed,
urllib3.util.make_headers() inserts ',br' in the Accept-Encoding header
and decodes br from the answers.

* Create the default Accept-Encoding header once

* Preserve the previous delimiter behavior

* Update prose in quickstart.rst

Co-authored-by: Seth Michael Larson <sethmichaellarson@gmail.com>
2021-07-07 08:16:28 -05:00
Bernát Gábor
24630743ce Avoid zip extract racing condition by using read+write instead extract (#5707)
Extract also creates the folder hierarchy, however we do not need that,
the file itself being extracted to a temporary folder is good enough.
Instead we read the content of the zip and then write it. The write is
not locked but it's OK to update the same file multiple times given the
update operation will not alter the content of the file. By not creating
the folder hierarchy (default via extract) we no longer can run into the
problem of two parallel extracts both trying to create the folder
hierarchy without exists ok flag, and one must fail.

Resolves #5223.

Signed-off-by: Bernát Gábor <bgabor8@bloomberg.net>
2021-07-06 19:14:51 -05:00
Ash Berlin-Taylor
2ed84f55b2 Switch LGPL'd chardet for MIT licensed charset_normalizer (#5797)
Although using the (non-vendored) chardet library is fine for requests
itself, but using a LGPL dependency the story is a lot less clear
for downstream projects, particularly ones that might like to bundle
requests (and thus chardet) in to a single binary -- think something
similar to what docker-compose is doing. By including an LGPL'd module
it is no longer clear if the resulting artefact must also be LGPL'd.

By changing out this dependency for one under MIT we remove all
license ambiguity.

As an "escape hatch" I have made the code so that it will use chardet
first if it is installed, but we no longer depend upon it directly,
although there is a new extra added, `requests[lgpl]`. This should
minimize the impact to users, and give them an escape hatch if
charset_normalizer turns out to be not as good. (In my non-exhaustive
tests it detects the same encoding as chartdet in every case I threw at
it)

Co-authored-by: Jarek Potiuk <jarek@potiuk.com>

Co-authored-by: Jarek Potiuk <jarek@potiuk.com>
2021-07-06 18:55:02 -05:00
TAHRI Ahmed R
33d448eb21 Pin Flask to <2.0 to fix the test suite
httpbin does not limit Flask version and the 2.0 release has broken compatibility with our test suite
2021-07-06 15:39:50 -05:00
Francois Marier
1466ad713c Fix GitHub links (#5835)
All of these links now redirect to a repo under a different GitHub
user account.
2021-05-31 21:23:54 -07:00
Mark Bell
f6d43b03fb Updated to new be-cordial-or-be-on-your-way URL and CoC now references Python Community CoC (#5811)
* Updated references to new be-cordial-or-be-on-your-way URL.

* CoC now references Python Community Code of Conduct
2021-05-07 11:54:37 -05:00
tallalnparis4ev
05a1a21593 Throw value error when serializing JSON object with NaN value (#5810)
* disallow nan values in json serialize

* test nan value in json post

* added exception for invalid json in request

* use invalid json exception

* invalid json test
2021-05-06 13:18:58 -05:00
Coco Mishra
c45a4dfe6b grammar fix (#5791) 2021-04-11 11:25:49 -05:00
Hans96
2c2138e811 Update setup.py (#5780)
Removed `import re` as unnecessary import
2021-03-19 17:09:29 -05:00
laggardkernel
c267415882 Remove call to set default value for allow_redirects
The call to kwargs.setdefault was redundant and unnecessary as the lower-level session defaults to true.
2021-03-19 11:44:19 -05:00
Ian Stapleton Cordasco
5433656878 Merge pull request #5777 from cclauss/patch-1
quickstart.rst: r.json() can raise JSONDecodeError on Py3
2021-03-18 09:36:34 -05:00
Christian Clauss
f79d1ef42f Also update requests.models.Response 2021-03-18 13:19:28 +01:00
Christian Clauss
4193b95db0 simplejson.JSONDecodeError may be raised on Py2 and Py3 2021-03-18 12:27:02 +01:00
Christian Clauss
06462a6e79 quickstart.rst: r.json() can raise JSONDecodeError on Py3
% `python2 -c "import requests ; requests.get('https://github.com').json()"`
% `python3 -c "import requests ; requests.get('https://github.com').json()"`
2021-03-18 10:06:14 +01:00
Andrew M. White
913880c45a Fix typo 2021-02-24 10:19:48 -07:00
Ian Stapleton Cordasco
bdc00eb097 Merge pull request #5755 from pdmccormick/master
Provide directions for cloning repository despite malformed commits
2021-02-17 15:37:02 -06:00
Peter David McCormick
ef6ceffc1c Provide directions for cloning repository despite malformed commits 2021-02-17 15:38:48 -05:00
Ian Stapleton Cordasco
8c211a96cd Merge pull request #5681 from mateusduboli/5677
5677: Rebuild proxies on Session#send
2021-01-24 16:59:46 -06:00
XiaojueGuan
74b7280049 Fix typo request -> requests 2021-01-22 07:41:39 -06:00
Ian Stapleton Cordasco
083aa67a0d Merge pull request #5723 from bbodenmiller/patch-2
Format c_rehash
2021-01-20 08:58:35 -06:00
Ben Bodenmiller
f6072f1e14 Format c_rehash 2021-01-19 17:27:56 -08:00
Nate Prewitt
c2b307dbef v2.25.1
Some checks failed
Tests / build (macOS-latest, 2.7) (push) Has been cancelled
Tests / build (macOS-latest, 3.5) (push) Has been cancelled
Tests / build (macOS-latest, 3.6) (push) Has been cancelled
Tests / build (macOS-latest, 3.7) (push) Has been cancelled
Tests / build (macOS-latest, 3.8) (push) Has been cancelled
Tests / build (macOS-latest, 3.9) (push) Has been cancelled
Tests / build (ubuntu-18.04, 2.7) (push) Has been cancelled
Tests / build (ubuntu-18.04, 3.5) (push) Has been cancelled
Tests / build (ubuntu-18.04, 3.6) (push) Has been cancelled
Tests / build (ubuntu-18.04, 3.7) (push) Has been cancelled
Tests / build (ubuntu-18.04, 3.8) (push) Has been cancelled
Tests / build (ubuntu-18.04, 3.9) (push) Has been cancelled
Tests / build (ubuntu-latest, pypy3) (push) Has been cancelled
Tests / build (windows-latest, 2.7) (push) Has been cancelled
Tests / build (windows-latest, 3.5) (push) Has been cancelled
Tests / build (windows-latest, 3.6) (push) Has been cancelled
Tests / build (windows-latest, 3.7) (push) Has been cancelled
Tests / build (windows-latest, 3.8) (push) Has been cancelled
Tests / build (windows-latest, 3.9) (push) Has been cancelled
2020-12-16 11:34:26 -08:00
Shouro
6de4f104cd Change docs title to requests.sessions 2020-12-14 17:49:49 -06:00
Nate Prewitt
b223291693 Merge pull request #5688 from dan-blanchard/patch-1
Upgrade to chardet 4.x
2020-12-14 09:29:10 -08:00
Dan Blanchard
516f84f490 Upgrade to chardet 4.x 2020-12-11 10:31:38 -05:00
Ernest W. Durbin III
d3e0f73354 Update sponsorship link
PSF relaunched new sponsorship program and the URL has changed.
2020-12-09 08:03:57 -06:00
Mateus Dubiela Oliveira
60ea7f0c2d #5677: Rebuild proxies on Session#send 2020-12-08 18:37:18 +01:00
Ian Stapleton Cordasco
5035827ba4 Merge pull request #5670 from smarie/pr_proxy_conf_helper_and_doc
Proxy related doc updates
2020-12-04 13:38:17 -06:00
Ian Stapleton Cordasco
589c454733 Merge pull request #5673 from jjmaldonis/master
updated `get_encoding_from_headers` to return utf-8 if the content type is set to application/json
2020-11-29 12:19:15 -06:00
jason
5855dd711f updated get_encoding_from_headers to return utf-8 if the content type is set to application/json, following RFC 4627.
fixes #5667
2020-11-29 11:51:41 -06:00
Kaartic Sivaraam
d0359c9460 Fix broken link 2020-11-28 12:21:02 -06:00
Sylvain MARIE
f02a80cbe8 Updated proxies documentation 2020-11-27 17:44:13 +01:00
Sylvain MARIE
d1ca591c0f Revert "New helper method set_http_proxy in Session to set proxies in a more user friendly way"
This reverts commit 4b66260c
2020-11-27 17:05:17 +01:00
Sylvain MARIE
2fddbe3606 Updated proxies documentation 2020-11-27 11:51:47 +01:00
Sylvain MARIE
4b66260cb7 New helper method set_http_proxy in Session to set proxies in a more user friendly way 2020-11-27 11:51:16 +01:00
Nate Prewitt
9ce669e3ae Merge pull request #5663 from hugovk/patch-1
Pin GHA to Ubuntu 18.04
2020-11-18 08:32:02 -08:00
Hugo van Kemenade
0514dea6fc Pin GHA to Ubuntu 18.04
`ubuntu-latest` points to 18.04 and will soon flip to 20.04.

However tests currently fail on 20.04, so let's explicitly pin to 18.04 for now.
2020-11-18 09:00:23 +02:00
Nate Prewitt
962c8986ca Merge pull request #5594 from icfly2/patch-1
Update advanced.rst
2020-11-16 17:31:39 -08:00
Ian Stapleton Cordasco
28cc1d237b Merge pull request #5659 from nateprewitt/contrib_cleanup
Remove reference to development philosophy
2020-11-16 13:19:05 -06:00
Nate Prewitt
78fdf4dd92 Remove reference to development philosophy 2020-11-16 10:44:31 -08:00
Nate Prewitt
03957eb1c2 v2.25.0
Some checks failed
Tests / build (macOS-latest, 2.7) (push) Has been cancelled
Tests / build (macOS-latest, 3.5) (push) Has been cancelled
Tests / build (macOS-latest, 3.6) (push) Has been cancelled
Tests / build (macOS-latest, 3.7) (push) Has been cancelled
Tests / build (macOS-latest, 3.8) (push) Has been cancelled
Tests / build (macOS-latest, 3.9) (push) Has been cancelled
Tests / build (ubuntu-latest, 2.7) (push) Has been cancelled
Tests / build (ubuntu-latest, 3.5) (push) Has been cancelled
Tests / build (ubuntu-latest, 3.6) (push) Has been cancelled
Tests / build (ubuntu-latest, 3.7) (push) Has been cancelled
Tests / build (ubuntu-latest, 3.8) (push) Has been cancelled
Tests / build (ubuntu-latest, 3.9) (push) Has been cancelled
Tests / build (ubuntu-latest, pypy3) (push) Has been cancelled
Tests / build (windows-latest, 2.7) (push) Has been cancelled
Tests / build (windows-latest, 3.5) (push) Has been cancelled
Tests / build (windows-latest, 3.6) (push) Has been cancelled
Tests / build (windows-latest, 3.7) (push) Has been cancelled
Tests / build (windows-latest, 3.8) (push) Has been cancelled
Tests / build (windows-latest, 3.9) (push) Has been cancelled
2020-11-11 11:55:50 -08:00
Nate Prewitt
320a10d142 Remove Pipfile/Pipfile.lock 2020-11-11 10:29:13 -08:00
Nate Prewitt
9cd2d33489 Move CI to Github Actions 2020-11-11 10:29:13 -08:00
Nate Prewitt
2f70990cd3 Merge pull request #5643 from tarmath/netrc
Respect the NETRC environment variable
2020-11-01 08:52:01 -08:00
Mathieu Pichette
ba543713d3 Respect the NETRC environment variable 2020-10-31 21:01:30 -07:00
Ian Stapleton Cordasco
1431502331 Merge pull request #5614 from smstong/master
small typo corrected.
2020-10-05 13:15:43 -05:00
Jonathan
4840d4a376 small typo corrected.
a small typo was corrected.
2020-10-04 20:45:07 -04:00
Ian Stapleton Cordasco
4f6c018715 Merge pull request #5611 from psf/add-codescanning
Create codeql-analysis.yml
2020-10-02 17:10:53 -05:00
Ian Stapleton Cordasco
d09c0e0f24 Update codeql-analysis.yml
Remove proposed/3.0.0 branch, only ever run against Python sans matrix option
2020-10-02 14:06:24 -05:00
Ian Stapleton Cordasco
941ac53ba0 Create codeql-analysis.yml 2020-10-01 09:19:34 -05:00
Ian Stapleton Cordasco
799a97d360 Merge pull request #5608 from abdullahselek/master
Add official Python 3.8 support on Appveyor
2020-09-30 15:35:12 -05:00
Abdullah Selek
ae6144599a Add official Python 3.8 support on Appveyor 2020-09-30 20:52:35 +01:00
Ae-Mc
333fa8d3f2 Remove reading HISTORY.md in setup.py 2020-09-29 10:36:31 -05:00
Ruben
c3280d7844 Update advanced.rst
replaced reference to requests-async with httpx the replacement project
2020-09-23 13:19:29 +02:00
Martin
967a05bfff Update renamed GitHub handle 2020-09-11 10:36:21 -05:00
Nate Prewitt
1f7c88880b Merge pull request #5570 from ajorg-aws/master
Apply the Apache-2.0 license correctly
2020-08-27 11:09:01 -07:00
Andrew Jorgensen
22b5a39098 Apply the Apache-2.0 license correctly
This follows instructions from the Apache Foundation. It also ensures
that the license will be correctly detected by license scanning tools.

Note that by adding a NOTICE file triggers Section 4.d of the license,
which is usually intended by users of the license.

The text that was in the LICENSE file before this change is intended
(by the authors of the license) to be used as a file header, and not as
a full license notice for a project, but it is commonly used this way,
so I would of course understand if this change is rejected.
2020-08-27 09:44:27 -07:00
Sagar Giri
2a7832b5b0 Update index.rst
Update misleading text about python support
2020-08-25 17:50:13 -07:00
Nate Prewitt
48237afd9d updating doc links and formatting 2020-08-18 15:13:59 -07:00
Seth Michael Larson
0b01355870 Pin more helpful links to sidebar 2020-08-18 15:13:59 -07:00
Seth Michael Larson
43ed689d97 Trim release section, add back Twitter support 2020-08-18 15:13:59 -07:00
Seth Michael Larson
551a0bf0df Recommend Pip, remove todo/philo docs, pare down support avenues 2020-08-18 15:13:59 -07:00
Seth Michael Larson
0830062100 Remove images, analytics, 'keep up to date' 2020-08-18 15:13:59 -07:00
Seth Michael Larson
533c384b87 Make README markdown compatible 2020-08-18 15:13:59 -07:00
Matt Silverlock
02eb5a2cd3 Document the dangers of using verify=False 2020-08-16 21:31:05 -05:00
Ben Bodenmiller
2d39c0db05 Docs: list CURL_CA_BUNDLE as supported (#5509)
* Docs: list CURL_CA_BUNDLE as supported
2020-07-23 21:57:30 -07:00
Nate Prewitt
1b41763472 cleanup advanced docs header 2020-06-26 10:51:20 -08:00
Nate Prewitt
8149e9fe54 Merge pull request #5505 from ollien/prepared-requests-docs-correction
Clarify that PreparedRequests should not be manually created
2020-06-19 09:04:21 -07:00
Nick Krichevsky
9cae7be94f Clarify that PreparedRequests should not be manually created
Closes #5504
2020-06-18 22:06:41 -04:00
Kartik Chugh
1ca1c52e69 Google App Engine (#5475)
* Continuity: Google App Engine
2020-06-17 13:09:34 -07:00
Nate Prewitt
0797c61fd5 v2.24.0 2020-06-17 08:50:25 -07:00
Nate Prewitt
daa2b297a3 updating usage information 2020-06-17 08:50:25 -07:00
Nate Prewitt
7c71982260 Merge pull request #5496 from dbaxa/optimise-prepare-body
Avoid an unnecessary computation of the length of data for non-stream requests (which determine content-length based upon body content).
2020-06-17 08:21:38 -07:00
David Black
71a05cf289 Avoid an unnecessary computation of the length of data for non-stream requests (which determines content-length based upon body content). 2020-06-16 20:53:07 +10:00
Bharat Raghunathan
737dd0c3c6 Update number of dependents on requests (#5495)
* Update dependents on requests
2020-06-15 12:56:07 -07:00
Kevin Kirsche
8ac5929ae1 Fix typo in README (#5468) 2020-06-15 08:23:17 -07:00
Nate Prewitt
2b3436e0e7 Merge pull request #5492 from dbaxa/avoid-calling-resolve_redirects-whe-not-following-redirects
Remove what appears to be an un-needed call to self.resolve_redirects when not following redirects as part of creating a request's history.
2020-06-15 07:44:38 -07:00
David Black
fa2dbe9a91 Remove what appears to be an un-needed call to self.resolve_redirects when not following redirects as part of creating a request's history. 2020-06-15 20:16:47 +10:00
Thomas Grainger
9ed5db8ed2 fix raise_for_status docstring (#5293)
the exception isn't stored it's created new each call
2020-05-08 22:08:51 -07:00
Miro Hrončok
427e8eb1e7 Fix test_conflicting_post_params to work on pytest 5 (#5305)
The non-contextmanager form of pytest.raises was removed in pytest 5.
http://doc.pytest.org/en/latest/deprecations.html#raises-warns-with-a-string-as-the-second-argument

It was used here to support Python < 2.7, but that is no longer needed.
https://github.com/psf/requests/pull/1503#issuecomment-22333666

Fixes https://github.com/psf/requests/issues/5304
2020-05-08 21:58:03 -07:00
Seth Michael Larson
251f73f65d Add changelog entry for pyOpenSSL change 2020-05-01 16:33:51 -07:00
Seth Michael Larson
db47b9b4a0 Don't use pyOpenSSL unless no SNI is detected 2020-05-01 16:33:51 -07:00
Nate Prewitt
bfb93d4b7d update bleach security vulnerability 2020-04-03 14:39:06 -07:00
Nate Prewitt
9ea85109a5 fixing rst markup 2020-04-03 14:31:44 -07:00
Dustin Rodrigues
c577eb8d5f fix README typo 2020-04-03 13:59:17 -07:00
Alessio Izzo
bebf5250b0 Remove explicit unicode literal in README.md and doc (#5336)
* [remove] remove "u" prefix in README and documentation examples
2020-03-25 12:44:51 -07:00
Seth Michael Larson
2758124a13 Also update GitHub's Security Disclosure document (#5370) 2020-02-27 21:33:09 -06:00
Nate Prewitt
4fc7f4a255 Update disclosure contact info (#5369) 2020-02-27 12:05:07 -06:00
Nate Prewitt
65989ddfe9 changing of the guard
Thanks for everything Ian. Welcome Seth!
2020-02-26 20:47:28 -08:00
Nate Prewitt
0a760ff025 updating pipfile.lock for bleach security issue (#5364) 2020-02-26 20:21:47 -08:00
Redowan Delowar
ca6f9af5db Normalize exception docstrings (#5338) 2020-02-23 11:56:46 -06:00
Nate Prewitt
b7c6aba848 v2.23.0 2020-02-19 10:44:27 -08:00
Nate Prewitt
fd13816d01 Revert "Fix for response with UTF-8 BOM #4976"
This reverts commit 19cff44ec1.
This reverts commit 9e27326d68.
This reverts commit f507a3ef12.
2020-02-18 18:56:39 -06:00
Nate Prewitt
24bcb9eab6 Revert "Use urllib for chunked requests"
This reverts commit 2da7fe0858.
2020-02-18 18:56:39 -06:00
Nate Prewitt
b15056d1d3 Revert "#4965 fix: Accessing response.content twice removes forgets read error."
This reverts commit bd10047244.

This reverts commit d91fe00983.
2020-02-18 18:56:39 -06:00
Ned Batchelder
80011a7917 Remove an obsolete attribute from __attrs__
The extra attribute in __attrs__ makes an unpickled session have one more attribute than the original.  Removing it makes the original and the unpickled be identical.
2020-02-18 09:17:21 -08:00
Chris Withers
c46f55bd48 Limit dependencies to major instead of minor (#5342) 2020-02-18 08:58:27 -06:00
Alexander Zhukov
e11302018b Fix the syntax highlighting in the example (#5276)
Co-authored-by: Nate Prewitt <nate.prewitt@gmail.com>
2020-02-17 23:19:38 -08:00
Nate Prewitt
23f6faa7cd Merge pull request #5346 from stock1218/master
Update pipenv links in README and installation guide.
2020-02-17 21:44:33 -08:00
John Samuels
ae0a497b0c Update link to pipenv in installation guide. 2020-02-17 21:47:34 +00:00
John Samuels
b1631b03bc Update link to pipenv in README. 2020-02-17 21:46:26 +00:00
Nate Prewitt
a9906536ee Merge pull request #5326 from nawatts/intersphinx-mapping-config
Fix intersphinx_mapping config for Python standard library
2020-01-31 14:24:52 -10:00
Nick Watts
d5c4cac0f4 Fix intersphinx_mapping config for Python standard library 2020-01-25 18:19:22 -05:00
Nate Prewitt
7b565d886c Merge pull request #5325 from nawatts/install-pip-link
Change link for pip installation instructions
2020-01-25 10:19:34 -08:00
Nick Watts
7138d8b0e3 Change link for pip installation instructions 2020-01-25 12:09:10 -05:00
johnthagen
9b95b4e7b4 Add PyPy3 to Travis test suite (#5193) 2020-01-21 11:00:51 -06:00
Hugo van Kemenade
d2f65af033 Move community files under .github/ (#5206) 2020-01-19 09:41:09 -06:00
Sumana Harihareswara
a9ee0eef5a Add Python 2 support entry in FAQ (#5303)
* Add Python 2 support entry in FAQ

Fixes: #5211

Signed-off-by: Sumana Harihareswara <sh@changeset.nyc>

* Adding Python 3 recommendation

Co-authored-by: Nate Prewitt <nate.prewitt@gmail.com>
2020-01-09 09:55:20 -08:00
John Kooker
782e94d141 Update example code in README.md (#5292)
Show the current project description.
2020-01-09 09:26:42 -08:00
Nate Prewitt
ad18d14573 Merge pull request #5306 from hugovk/update-python-versions-in-faq
Update supported Python versions
2020-01-09 09:06:47 -08:00
Hugo
f462eecf48 Update supported Python versions 2020-01-06 11:24:02 +02:00
Nate Prewitt
eedd674628 Merge pull request #5250 from MasterOdin/patch-1
Fix link to requests-threads in community/recommended doc
2019-11-22 18:50:54 -08:00
Matthew Peveler
4a540ff5f1 Fix link to requests-threads on community/recommended 2019-10-30 16:15:13 -03:00
Sorin Sbarnea
d2590ee46c Change documentation website to requests.readthedocs.io (#5236)
Fixes: #5212
2019-10-24 20:02:55 -07:00
Charles Reid
4cd95aa496 update translation links from http -> https (#5237) 2019-10-24 19:46:04 -07:00
Nate Prewitt
56fd46f9bf Merge pull request #5243 from hugovk/test-3.8-final
Test on Python 3.8 final
2019-10-24 19:32:25 -07:00
Hugo
2ff8106d62 Test on Python 3.8 final 2019-10-22 18:40:03 +03:00
Ernest W. Durbin III
fab1fd10d0 Merge pull request #5216 from Leetcore/patch-1
documentation link fixed
2019-09-30 05:52:29 -04:00
Alex K
74b72ce426 documentation link fixed
websites is down, link to requests.readthedocs.io
2019-09-29 18:10:59 +02:00
Hugo
6e05165a29 Test on Python 3.8 beta 2019-09-26 15:06:29 -07:00
Hugo
0178903841 Xenial is now the default 2019-09-26 15:06:29 -07:00
☿ Kenneth Reitz
0d180a5cbb Merge pull request #5208 from psf/partII
Part II: The Principle of Polarity
2019-09-23 16:08:40 -04:00
☿ Kenneth Reitz
8345819b70 Update README.md 2019-09-23 14:31:19 -04:00
☿ Kenneth Reitz
5f824fb019 Update README.md 2019-09-23 14:30:16 -04:00
☿ Kenneth Reitz
1311c96eae Update README.md 2019-09-23 14:29:35 -04:00
☿ Kenneth Reitz
c4c60864f8 Update README.md 2019-09-23 14:28:52 -04:00
Kenneth Reitz
e8a9bd7415 The Principle of Polarity
Everything is dual; Everything has poles; Everything has its pair of opposites; Like and unlike are the same; Opposites are identical in nature, but different in degree; Extremes meet; All truths, are but half-truths; All paradoxes may be reconciled.
2019-09-23 14:17:08 -04:00
Kenneth Reitz
729fd3cf42 Revert "deepmind"
This reverts commit 14c323492a.
2019-09-23 14:07:17 -04:00
Kenneth Reitz
1d3787a0ea AUTHORS.rst 2019-09-23 14:07:01 -04:00
Nate Prewitt
0357b0724b Merge pull request #5195 from lzutao/patch-1
Fix formatting of status code example
2019-09-19 08:32:13 -07:00
Nate Prewitt
189fea7a11 Merge pull request #5197 from 5uper5hoot/patch-1
Fix misspelling
2019-09-19 08:29:29 -07:00
Nate Prewitt
a5f4f3c9a3 resolve more-itertools py2.7 issues
more-itertools is a transitive testing dependency that no longer supports
python2.7. In order to keep the test suite going, we're pinning under
6.0.0 (the breaking version) until we have better syntax in pipfile.
2019-09-19 08:17:21 -07:00
Nate Prewitt
e08981ee46 updating project url 2019-09-19 07:52:28 -07:00
Nate Prewitt
afb508f6a7 removing duplicate entry 2019-09-19 07:42:23 -07:00
Nate Prewitt
09fd857eb1 Revert "Add trusted domains"
This reverts commit fbe48fbb7c.
2019-09-19 07:42:23 -07:00
☿ Kenneth Reitz
1462917951 Update README.md 2019-09-18 19:24:42 -04:00
Peter Schutt
2962c236c9 Fix misspelling
Just noticed a small typo!
2019-09-18 21:09:22 +10:00
Kenneth Reitz
9d4fd3c968 Update README.md 2019-09-18 05:47:48 -04:00
Kenneth Reitz
12640ec242 Merge branch 'master' of github.com:psf/requests 2019-09-18 05:41:40 -04:00
Kenneth Reitz
5cb55a84a7 squash! 2019-09-18 05:41:33 -04:00
Kenneth Reitz
2cb3abea55 Update README.md 2019-09-18 05:41:05 -04:00
Kenneth Reitz
38d9a4f65f Merge branch 'master' of github.com:psf/requests 2019-09-18 05:40:25 -04:00
Kenneth Reitz
fbc5ed552e psf 2019-09-18 05:40:18 -04:00
Kenneth Reitz
5099688bfc Update README.md 2019-09-18 05:38:32 -04:00
Kenneth Reitz
4cd65385f8 Update README.md 2019-09-18 05:38:12 -04:00
Kenneth Reitz
87f9a58d45 Update README.md 2019-09-18 05:37:47 -04:00
Kenneth Reitz
9369b5a37a kr 2019-09-18 05:37:03 -04:00
Kenneth Reitz
23fe729356 Merge branch 'master' of github.com:psf/requests 2019-09-18 05:33:21 -04:00
Kenneth Reitz
1a7d1406cb cleanups 2019-09-18 05:33:15 -04:00
Kenneth Reitz
92b88fcffb Update README.md 2019-09-18 05:26:27 -04:00
Kenneth Reitz
ac851d8ac3 Merge branch 'master' of github.com:psf/requests 2019-09-18 05:26:03 -04:00
Kenneth Reitz
a025522d08 flourish 2019-09-18 05:25:59 -04:00
Kenneth Reitz
a3735e2517 Update README.md 2019-09-18 05:10:42 -04:00
Kenneth Reitz
06826504da Merge branch 'master' of github.com:psf/requests 2019-09-18 05:10:10 -04:00
Kenneth Reitz
14c323492a deepmind 2019-09-18 05:10:03 -04:00
Kenneth Reitz
c196511934 Update README.md 2019-09-18 05:02:36 -04:00
Kenneth Reitz
a9860c4fae Update README.md 2019-09-18 05:02:07 -04:00
Kenneth Reitz
f82382588f Update README.md 2019-09-18 05:01:17 -04:00
Kenneth Reitz
72176ab9ac Update README.md 2019-09-18 04:59:40 -04:00
Kenneth Reitz
eb2c14889f Update README.md 2019-09-18 04:59:26 -04:00
Kenneth Reitz
cfdd00f3a3 Update README.md 2019-09-18 04:57:16 -04:00
Kenneth Reitz
b15bccf35e Update README.md 2019-09-18 04:56:18 -04:00
Kenneth Reitz
f348d51818 Update README.md 2019-09-18 04:56:04 -04:00
Kenneth Reitz
dc1526f85d Update README.md 2019-09-18 04:55:34 -04:00
Kenneth Reitz
c21c039ec8 Update FUNDING.yml 2019-09-18 04:54:31 -04:00
Kenneth Reitz
49acab8033 Update FUNDING.yml 2019-09-18 04:54:20 -04:00
Kenneth Reitz
0f71067f64 Update README.md 2019-09-18 04:52:39 -04:00
Kenneth Reitz
9f35ebd795 Update README.md 2019-09-18 04:52:22 -04:00
Kenneth Reitz
de1c200dff Update README.md 2019-09-18 04:51:58 -04:00
Kenneth Reitz
458496d43e Update README.md 2019-09-18 04:51:23 -04:00
Kenneth Reitz
446911b853 Update README.md 2019-09-18 04:51:10 -04:00
Kenneth Reitz
3ed0f8fba0 Update README.md 2019-09-18 04:50:39 -04:00
Kenneth Reitz
d66ffdbb2b Update README.md 2019-09-18 04:49:57 -04:00
Kenneth Reitz
99197c2058 Update README.md 2019-09-18 04:49:43 -04:00
Kenneth Reitz
179f943300 Update README.md 2019-09-18 04:48:05 -04:00
Kenneth Reitz
75f062dcef Update README.md 2019-09-18 04:47:36 -04:00
Kenneth Reitz
a7944ba94f Update README.md 2019-09-18 04:46:49 -04:00
Kenneth Reitz
cf77263ad4 Update README.md 2019-09-18 04:45:14 -04:00
Kenneth Reitz
af85e68f1f Update README.md 2019-09-18 04:44:37 -04:00
Kenneth Reitz
536b583bc9 Update README.md 2019-09-18 04:44:26 -04:00
Kenneth Reitz
0f1251bc13 Update README.md 2019-09-18 04:43:41 -04:00
Kenneth Reitz
a29be8f9cc Update LICENSE 2019-09-18 04:42:26 -04:00
Kenneth Reitz
ac9f0d7c97 Update README.md 2019-09-18 04:40:07 -04:00
Kenneth Reitz
be2fe0c6af Update README.md 2019-09-18 04:39:30 -04:00
Kenneth Reitz
abe22b1da6 Update README.md 2019-09-18 04:39:17 -04:00
Kenneth Reitz
e11caeb39f Update README.md 2019-09-18 04:38:51 -04:00
Kenneth Reitz
30a16088c4 Update README.md 2019-09-18 04:37:53 -04:00
Kenneth Reitz
6831d2d8e4 Merge branch 'master' of github.com:psf/requests 2019-09-18 04:35:36 -04:00
Kenneth Reitz
a5bcc9c46e pngsquash 2019-09-18 04:35:29 -04:00
Kenneth Reitz
186dcee8a0 Update README.md 2019-09-18 04:31:58 -04:00
Kenneth Reitz
caf91bd175 Update README.md 2019-09-18 04:29:05 -04:00
Kenneth Reitz
80562c9f83 Update README.md 2019-09-18 04:28:47 -04:00
Kenneth Reitz
2256fd2bc4 Update README.md 2019-09-18 04:28:32 -04:00
Kenneth Reitz
316f748226 Update README.md 2019-09-18 04:28:17 -04:00
Kenneth Reitz
c6ab21c103 Update README.md 2019-09-18 04:27:19 -04:00
Kenneth Reitz
1d41e8dc97 Update README.md 2019-09-18 04:27:06 -04:00
Kenneth Reitz
80c7cbd46e Update README.md 2019-09-18 04:26:52 -04:00
Kenneth Reitz
775813aae7 Update README.md 2019-09-18 04:26:38 -04:00
Kenneth Reitz
cbccc5f07e Update README.md 2019-09-18 04:26:00 -04:00
Kenneth Reitz
26466b54ad Merge branch 'master' of github.com:psf/requests 2019-09-18 04:25:21 -04:00
Kenneth Reitz
042ccfcf99 license 2019-09-18 04:25:17 -04:00
Kenneth Reitz
24e46d0303 Update README.md 2019-09-18 04:21:16 -04:00
Kenneth Reitz
70cc902f5e Update README.md 2019-09-18 04:19:56 -04:00
Kenneth Reitz
091604455a Update README.md 2019-09-18 04:19:37 -04:00
Kenneth Reitz
b639f17705 Update README.md 2019-09-18 04:18:41 -04:00
Kenneth Reitz
33f41b8a13 Update README.md 2019-09-18 04:18:03 -04:00
Kenneth Reitz
73a65941ad Update README.md 2019-09-18 04:17:42 -04:00
Kenneth Reitz
2e992817d4 Update README.md 2019-09-18 04:17:04 -04:00
Kenneth Reitz
0f9bcfb86c Update README.md 2019-09-18 04:14:44 -04:00
Kenneth Reitz
fcde69193a Update README.md 2019-09-18 04:14:21 -04:00
Kenneth Reitz
b08073a7c3 Update README.md 2019-09-18 04:12:57 -04:00
Kenneth Reitz
e1eb569751 Update README.md 2019-09-18 04:12:00 -04:00
Kenneth Reitz
8d09a80a16 Update README.md 2019-09-18 04:11:31 -04:00
Kenneth Reitz
8074cc8bf5 Update README.md 2019-09-18 04:08:42 -04:00
Kenneth Reitz
8e19074296 Update README.md 2019-09-18 04:07:44 -04:00
Kenneth Reitz
30c128ade9 Update README.md 2019-09-18 04:05:51 -04:00
Kenneth Reitz
65a73bd0f7 Update README.md 2019-09-18 04:01:56 -04:00
Kenneth Reitz
e63d846b15 Update README.md 2019-09-18 03:59:35 -04:00
Kenneth Reitz
d6db3901cb Update README.md 2019-09-18 03:57:15 -04:00
Kenneth Reitz
355e288940 Update README.md 2019-09-18 03:56:27 -04:00
Kenneth Reitz
a08c421f7c Update README.md 2019-09-18 03:55:43 -04:00
Kenneth Reitz
e35ace77bf Update README.md 2019-09-18 03:55:23 -04:00
Kenneth Reitz
f3b62442be Update README.md 2019-09-18 03:54:03 -04:00
Kenneth Reitz
846c37c29d Update README.md 2019-09-18 03:53:50 -04:00
Kenneth Reitz
570dc15b52 Update README.md 2019-09-18 03:52:51 -04:00
Kenneth Reitz
4a87d1e62f Update README.md 2019-09-18 03:52:36 -04:00
Kenneth Reitz
2d3b68cf1e Update README.md 2019-09-18 03:51:22 -04:00
Kenneth Reitz
31a6e696bb Update README.md 2019-09-18 03:51:03 -04:00
Kenneth Reitz
33e402b21f Update README.md 2019-09-18 03:48:48 -04:00
Kenneth Reitz
60cffb076b Update README.md 2019-09-18 03:48:25 -04:00
Kenneth Reitz
bdc92c795f Update README.md 2019-09-18 03:41:20 -04:00
Kenneth Reitz
426a1c0120 Update README.md 2019-09-18 03:40:05 -04:00
Kenneth Reitz
bc8fa9c246 Update README.md 2019-09-18 03:39:46 -04:00
Kenneth Reitz
be7cbe1353 Update README.md 2019-09-18 03:38:46 -04:00
Kenneth Reitz
9ba6c5e638 Update README.md 2019-09-18 03:37:59 -04:00
Kenneth Reitz
762042260b Update README.md 2019-09-18 03:37:29 -04:00
Kenneth Reitz
2abe57458d Update README.md 2019-09-18 03:37:21 -04:00
Kenneth Reitz
e40a3d6094 Update README.md 2019-09-18 03:35:33 -04:00
Kenneth Reitz
c2479aeac7 logo 2019-09-18 03:34:08 -04:00
Kenneth Reitz
7ce4691289 Merge branch 'master' of github.com:psf/requests 2019-09-18 03:32:27 -04:00
Kenneth Reitz
c5d9e1216e resize 2019-09-18 03:32:18 -04:00
Kenneth Reitz
863542529d Update README.md 2019-09-18 03:31:48 -04:00
Kenneth Reitz
8072d4fda8 Update README.md 2019-09-18 03:31:23 -04:00
Kenneth Reitz
e820ac7c40 Update README.md 2019-09-18 03:30:45 -04:00
Kenneth Reitz
720f1ce61d Update README.md 2019-09-18 03:29:25 -04:00
Kenneth Reitz
6d37433c0e Merge branch 'master' of github.com:psf/requests 2019-09-18 03:28:44 -04:00
Kenneth Reitz
969783702d flower of life 2019-09-18 03:28:35 -04:00
Kenneth Reitz
6fbbbc8c9e Update README.md 2019-09-18 03:26:17 -04:00
Kenneth Reitz
26b104ecb9 Update README.md 2019-09-18 03:25:58 -04:00
Kenneth Reitz
3f21a2d62e shoes and cars 2019-09-18 03:25:21 -04:00
Kenneth Reitz
42926b5731 Merge branch 'master' of github.com:psf/requests 2019-09-18 03:22:03 -04:00
Kenneth Reitz
a7e2da804c flourish 2019-09-18 03:21:34 -04:00
Kenneth Reitz
2416c2dd47 Update README.md 2019-09-18 03:20:31 -04:00
Kenneth Reitz
b44d6fdf49 Update README.md 2019-09-18 03:20:10 -04:00
Kenneth Reitz
0859c01b16 flourish 2019-09-18 03:19:23 -04:00
Kenneth Reitz
c198cc0b2e Update README.md 2019-09-18 03:17:40 -04:00
Kenneth Reitz
4b9e5d0ef3 Update README.md 2019-09-18 03:17:21 -04:00
Kenneth Reitz
9b51d7c4f2 Update README.md 2019-09-18 03:17:05 -04:00
Kenneth Reitz
6b89c8752a Update README.md 2019-09-18 03:16:49 -04:00
Kenneth Reitz
59dac47346 Update README.md 2019-09-18 03:15:04 -04:00
Kenneth Reitz
bb2ae009bc Update README.md 2019-09-18 03:14:40 -04:00
Kenneth Reitz
11982c1f9f Update README.md 2019-09-18 03:14:26 -04:00
Kenneth Reitz
36cc7bbfc3 Update README.md 2019-09-18 03:12:31 -04:00
Kenneth Reitz
d675d83b1d Update README.md 2019-09-18 03:12:12 -04:00
Kenneth Reitz
4d2875da11 Update README.md 2019-09-18 03:11:56 -04:00
Kenneth Reitz
687ff0eb36 Update README.md 2019-09-18 03:11:34 -04:00
Kenneth Reitz
c51a9efa2b Update README.md 2019-09-18 03:10:41 -04:00
Kenneth Reitz
c386eebcf8 Update README.md 2019-09-18 03:10:21 -04:00
Kenneth Reitz
3423b51748 Update README.md 2019-09-18 03:10:00 -04:00
Kenneth Reitz
3ff2995c1d Update README.md 2019-09-18 03:09:42 -04:00
Kenneth Reitz
e231de6ddc Update README.md 2019-09-18 03:05:16 -04:00
Kenneth Reitz
54cefc901c Update README.md 2019-09-18 03:04:51 -04:00
Kenneth Reitz
2bc6aeb64e Update README.md 2019-09-18 03:03:12 -04:00
Kenneth Reitz
7c71cb9643 Update README.md 2019-09-18 03:02:29 -04:00
Kenneth Reitz
e0359b2725 Update README.md 2019-09-18 02:54:15 -04:00
Kenneth Reitz
25d1ffda8c Update README.md 2019-09-18 02:53:30 -04:00
Kenneth Reitz
537ac3cf22 Update README.md 2019-09-18 02:52:51 -04:00
Kenneth Reitz
5477208835 Update README.md 2019-09-18 02:52:15 -04:00
Kenneth Reitz
0b2517465d Update README.md 2019-09-18 02:51:37 -04:00
Kenneth Reitz
1c19e6148f Update README.md 2019-09-18 02:51:10 -04:00
Kenneth Reitz
55d3d8b3b2 Update README.md 2019-09-18 02:50:59 -04:00
Kenneth Reitz
5f3b95992b Update README.md 2019-09-18 02:49:42 -04:00
Kenneth Reitz
3e012c16c3 Update README.md 2019-09-18 02:49:15 -04:00
Kenneth Reitz
c13ccd11f6 Update README.md 2019-09-18 02:48:45 -04:00
Kenneth Reitz
266d17c4de Update README.md 2019-09-18 02:43:58 -04:00
Kenneth Reitz
6b639bbc08 Update README.md 2019-09-18 02:43:41 -04:00
Kenneth Reitz
6c322457a2 pipfile / lock 2019-09-18 02:42:55 -04:00
Kenneth Reitz
5090ba79ac Create .nojekyll 2019-09-18 02:39:15 -04:00
Kenneth Reitz
da13fec6ce Create SECURITY.md 2019-09-18 02:37:03 -04:00
Kenneth Reitz
d7018e6d61 Create FUNDING.yml 2019-09-18 02:34:01 -04:00
lzutao
39b3dcf7d9 Fix formatting of status code example 2019-09-17 19:34:36 +07:00
Kenneth Reitz
3d968ff34d Update index.rst 2019-08-26 10:35:52 -04:00
Kenneth Reitz
b6b90f4d9b Update sidebarintro.html 2019-08-20 19:02:36 -04:00
Kenneth Reitz
913adced21 Update sidebarlogo.html 2019-08-20 19:02:23 -04:00
Nate Prewitt
e320f9e467 Merge pull request #5171 from MFStapert/patch-2
Fix typo
2019-08-20 10:28:48 -07:00
Marijn Stapert
4070bcf1b9 Fix typo 2019-08-20 19:25:03 +02:00
Kenneth Reitz
3c01cd7080 Update README.md 2019-08-20 01:02:03 -04:00
Kenneth Reitz
bc81ee3af4 Update setup.py 2019-08-20 01:01:06 -04:00
Kenneth Reitz
b1d584e899 Update index.rst 2019-08-20 00:58:49 -04:00
Kenneth Reitz
b98be047f2 Update README.md 2019-08-20 00:58:07 -04:00
Kenneth Reitz
ced3779126 Update README.md 2019-08-20 00:57:58 -04:00
Kenneth Reitz
bedb1cd38f Update README.md 2019-08-20 00:57:46 -04:00
Kenneth Reitz
d258b20eba Delete sponsors.rst 2019-08-20 00:57:00 -04:00
Kenneth Reitz
e2fce5e60c Update index.rst 2019-08-20 00:56:45 -04:00
Kenneth Reitz
72ca1b7e31 Update index.rst 2019-08-20 00:55:57 -04:00
Kenneth Reitz
7f3ce7eaac Update sidebarlogo.html 2019-08-20 00:55:22 -04:00
Kenneth Reitz
b248328eb3 Update sidebarintro.html 2019-08-20 00:54:28 -04:00
Kenneth Reitz
10e5f874c7 Update sidebarintro.html 2019-08-20 00:54:00 -04:00
Kenneth Reitz
7f2513fb81 Update index.rst 2019-08-20 00:50:22 -04:00
Kenneth Reitz
04b5c83701 Update index.rst 2019-08-20 00:50:07 -04:00
Kenneth Reitz
1f9ec06e22 Update index.rst 2019-08-20 00:49:18 -04:00
Kenneth Reitz
00fa902c7d Update README.md 2019-08-20 00:47:05 -04:00
Kenneth Reitz
3393232304 Update README.md 2019-08-20 00:46:57 -04:00
Kenneth Reitz
d41fba6347 Update README.md 2019-08-20 00:46:47 -04:00
Kenneth Reitz
7ca0e86a67 Update README.md 2019-08-20 00:45:53 -04:00
Kenneth Reitz
428f7a2759 Merge pull request #5076 from myrheimb/patch-1
Possible fix for #4945?
2019-08-20 00:38:21 -04:00
Kenneth Reitz
a71e2240df Merge pull request #4976 from eduardomourar/feature/strip-utf8-bom
Fix for response with UTF-8 BOM
2019-08-20 00:26:59 -04:00
Kenneth Reitz
4bce5a0bc5 Merge branch 'master' into feature/strip-utf8-bom 2019-08-20 00:26:51 -04:00
Kenneth Reitz
3e7d0a873f Merge pull request #4987 from aless10/master
[fix] fix failing doctests in requests/*
2019-08-20 00:25:50 -04:00
Kenneth Reitz
df918c066f Merge branch 'master' into master 2019-08-20 00:25:37 -04:00
Kenneth Reitz
ada50499a0 Merge pull request #4996 from sblondon/master
Add link to user-agent documentation
2019-08-20 00:24:08 -04:00
Kenneth Reitz
82c744b59c Merge pull request #4983 from jaketreacher/2949-trusted-domain
Add trusted domains
2019-08-20 00:23:52 -04:00
Kenneth Reitz
bbc3d43522 Merge pull request #4922 from jdufresne/ordered
Remove unnecessary compat shim for OrderedDict
2019-08-20 00:22:32 -04:00
Kenneth Reitz
8086ffdbbf Merge pull request #4999 from greysteil/add-project-urls
Add project URLs with links to source code and docs
2019-08-20 00:21:31 -04:00
Kenneth Reitz
5eb7337494 Merge pull request #4978 from sayzlim/master
Fix double image request
2019-08-20 00:21:12 -04:00
Kenneth Reitz
48e1a3359e Merge branch 'master' into master 2019-08-20 00:21:04 -04:00
Kenneth Reitz
1b450d2038 Merge pull request #5018 from hugovk/rm-2.6
Remove duplicate config
2019-08-20 00:17:54 -04:00
Kenneth Reitz
67a7b2e833 Merge pull request #5087 from LuckyDenis/master
#4965 Fix
2019-08-20 00:16:35 -04:00
Kenneth Reitz
42c5a4f622 Merge pull request #5128 from lmvlmv/urllibfix
Use urllib for chunked requests
2019-08-20 00:15:44 -04:00
Kenneth Reitz
11ed88bcb2 Merge pull request #5105 from alanyee/patch-1
Update sessions.py
2019-08-20 00:14:36 -04:00
Kenneth Reitz
0fe6653eab Merge pull request #5049 from hroncok/pytest4
Support pytest 4
2019-08-20 00:12:58 -04:00
Kenneth Reitz
dd15e52840 Merge pull request #5119 from alanyee/patch-1
Update sessions.py
2019-08-20 00:11:22 -04:00
Kenneth Reitz
9bc49b5960 Merge branch 'master' into patch-1 2019-08-20 00:11:02 -04:00
Nate Prewitt
d79024f246 Merge pull request #5160 from OrangutanGaming/change-github
Updated references to previous requests/requests GitHub path
2019-08-19 15:57:15 -07:00
Nihaal
9cdf294107 Updated references to previous requests/requests GitHub path 2019-08-19 21:33:18 +01:00
Nate Prewitt
9f55e4bc09 Merge pull request #5164 from dschaller/patch-1
fix codecov logo in readme
2019-08-19 10:55:40 -07:00
Nate Prewitt
bf582192b8 Merge pull request #5167 from aadibajpai/patch-1
[IMPROVEMENT] Update monthly download count
2019-08-19 10:54:31 -07:00
Aadi Bajpai
408e576d33 Update README.md with download count
https://pepy.tech/project/requests
2019-08-19 22:13:41 +05:30
Derek
7d57e8ec55 fix codecov logo in readme 2019-08-15 18:47:10 -07:00
Denis Belavin
e8ff4897fe Merge branch 'master' into master 2019-08-14 21:12:19 +03:00
Dull Bananas
a4c18cd733 Add missing backtick (#5145) 2019-07-29 09:06:11 -07:00
sblondon
07005b0ffc Merge branch 'master' into master 2019-07-25 18:07:21 +02:00
lmvlmv
989f702742 Merge branch 'master' into urllibfix 2019-07-25 10:49:24 +01:00
Alessio Izzo
a0d58026e0 Merge branch 'master' into master 2019-07-24 12:42:40 +02:00
Denis Belavin
3922dcf2a1 Merge branch 'master' into master 2019-07-23 21:36:37 +03:00
Kenneth Reitz
589a822567 Merge pull request #5141 from minho42/Fix-typos
Fix typos
2019-07-23 12:53:21 -04:00
lmvlmv
e8c9acc8a2 Merge branch 'master' into urllibfix 2019-07-23 09:31:00 +01:00
Kenneth Reitz
9a2e5df000 Merge pull request #5142 from dullbananas/master
Improve docs
2019-07-20 23:57:00 -04:00
Dull Bananas
c79d61b953 List valid methods for request() 2019-07-20 15:32:04 -07:00
Dull Bananas
f9ac75cab1 Fix GitHub profile link 2019-07-20 09:31:39 -07:00
Dull Bananas
ebd3e36ad5 Add 'Dull Bananas' to AUTHORS 2019-07-20 09:29:50 -07:00
Dull Bananas
50daf9c005 Add .eggs dir to .gitignore 2019-07-20 09:23:52 -07:00
Dull Bananas
fb7efcf3f1 Add example of good code below example of bad code 2019-07-20 09:17:54 -07:00
Min ho Kim
5f576ad22f Fix typos 2019-07-20 01:46:08 +10:00
kobayashi
0b6c110a5c Merge pull request #5127 from Unit03/head-allow-redirects-docstring
Document that `request.head` defaults `allow_redirects` to `False`
2019-07-11 20:18:42 -04:00
Leon Verrall
2da7fe0858 Use urllib for chunked requests 2019-07-02 10:17:33 +01:00
Jacek Kołodziej
c8d8b4b513 Document that request.head defaults allow_redirects to False
Related: kennethreitz/requests#4274
2019-07-01 21:41:38 +02:00
Alan Yee
45c2e679e0 Update sessions.py
Use `.format()` over `%` given PEP 3101
2019-06-24 10:12:38 -07:00
aless10
27b24f974f Merge branch 'master' of https://github.com/kennethreitz/requests 2019-06-13 22:48:08 +02:00
Denis Belavin
6296df90b9 Merge branch 'master' into master 2019-06-13 10:18:55 +03:00
Nate Prewitt
4983a9bde3 Merge pull request #5108 from atombrella/python34
Removed py34 from tox.ini.
2019-06-03 07:01:03 -07:00
Mads Jensen
2e4329d153 Removed py34 from tox.ini. 2019-06-03 08:45:48 +02:00
Alan Yee
47cb8bae1a Update sessions.py
-Made removing a key-value pair more modular
-Remove unneeeded return statement
2019-05-29 11:49:44 -07:00
aless10
d889b98eae Merge branch 'master' of https://github.com/kennethreitz/requests 2019-05-24 20:40:22 +02:00
Miro Hrončok
dc75b3ca0b Support pytest 4
Fixes https://github.com/kennethreitz/requests/issues/5048

See https://docs.pytest.org/en/latest/deprecations.html#marks-in-pytest-mark-parametrize
2019-05-24 00:02:43 +02:00
Denis Belavin
0becdca7e3 Merge branch 'master' into master 2019-05-20 21:00:14 +03:00
Buğra İşgüzar
6f81e78dfe Merge pull request #5099 from petar-iv/password-no-print
Print the type of the password instead of the password itself
2019-05-20 18:35:41 +03:00
Denis Belavin
9c3c755abe Merge branch 'master' into master 2019-05-20 10:12:35 +03:00
petar-iv
d88240ba44 Print the type of the password instead of the password itself 2019-05-20 09:57:11 +03:00
aless10
6d2a5072ca [add] add NORMALIZE_WHITESPACE and ELLIPSIS to pytest.ini and remove them from requests/__init__.py 2019-05-19 16:25:52 +02:00
aless10
96ff7ca31f Merge branch 'master' of https://github.com/aless10/requests 2019-05-19 16:21:40 +02:00
aless10
2e633471f1 Merge branch 'master' of https://github.com/kennethreitz/requests 2019-05-19 16:20:40 +02:00
aless10
67a0e90b6b [change] change doctest based on LuckyDenis suggestion 2019-05-19 16:20:11 +02:00
Alessio Izzo
4a59cd0950 Merge branch 'master' into master 2019-05-19 16:08:55 +02:00
Hugo
be295ba4d4 Simplify config 2019-05-16 18:36:45 +03:00
Hugo
d36f391957 Merge branch 'master' into rm-2.6 2019-05-16 18:31:37 +03:00
Frost Ming
a79a63390b Merge pull request #5088 from zurbrugc/master
Linked a GitHub tutorial regarding pull requests in README
2019-05-16 13:20:45 +08:00
Frost Ming
86760daf23 Merge branch 'master' into master 2019-05-16 13:14:08 +08:00
Frost Ming
8e26bfd86d Merge pull request #5092 from kennethreitz/urllib1.25
v2.22.0
2019-05-16 13:12:48 +08:00
zurbrugc
44256ffe7c Linked how to make a pull requests in README
This makes it easier for users new to GitHub to learn how to make a pull request.
2019-05-14 11:25:16 -07:00
zurbrugc
4803716715 Merge pull request #1 from kennethreitz/master
Updating my fork with the original
2019-05-14 11:21:30 -07:00
Белавин Денис
bd10047244 #4965 fix: Accessing response.content twice removes forgets read error. 2019-05-14 12:11:56 +03:00
Белавин Денис
d91fe00983 #4965 fix-draw: Accessing response.content twice removes forgets read error. 2019-05-13 17:18:42 +03:00
Bjørnar Myrheim
a310b5ab34 Possible fix for #4945?
Could the missing colon on line 612 be the reason for the missing reference in the docs as described in issue #4945?
2019-04-30 18:37:11 +02:00
Alessio Izzo
663aa1162b Merge branch 'master' into master 2019-04-23 19:18:02 +02:00
Alessio Izzo
8b773a4fed [remove] remove invalid field in docete
Remove 'Connection': 'close' field in 'headers'
2019-04-07 13:36:34 +02:00
Alessio Izzo
c19c394ac1 Merge branch 'master' into master 2019-04-07 13:24:09 +02:00
Alessio Izzo
aa21dbe7fc Merge branch 'master' into master 2019-03-26 16:24:43 +01:00
Hugo
a7969c5c42 Remove old Python 2.6 check and duplicate config 2019-03-10 17:08:09 +02:00
Grey Baker
7d7d9ebacf Add project URLs with links to source code and docs 2019-02-23 13:24:52 +00:00
sblondon
248211453d Add link to user-agent documentation
So the user has a pointer to the documentation about the searched topic.
2019-02-22 11:04:07 +01:00
aless10
fd926e74c3 [change] change description in __init__ module. Now it is the same as master 2019-02-17 19:45:32 +01:00
aless10
177f4dd2a4 [fix] fix failing doctests in requests/*
[add] add --doctest-modules in pytest.ini file as addopts
[add] add myself to AUTHORS
2019-02-17 19:06:01 +01:00
Jake Treacher
fbe48fbb7c Add trusted domains 2019-02-15 10:40:24 +08:00
Sayz Lim
5add08fc84 Fix double image request
Use official framework for the "custom" ad design integration.
2019-02-12 20:24:58 +07:00
Eduardo Rodrigues
19cff44ec1 fix response with utf8 bom 2019-02-09 22:14:22 +01:00
Eduardo Rodrigues
9e27326d68 add failing tests for bom 2019-02-09 22:00:32 +01:00
Eduardo Rodrigues
f507a3ef12 add utf8 with bom to test 2019-02-09 11:56:06 +01:00
Jon Dufresne
2aab9a9a39 Remove internal use of unnecessary compat shim for OrderedDict
The shim is the same on both Python 2 & 3. It is always
collections.OrderedDict. Avoid the indirection and import from Python
stdlib instead.

Keep requests.compat.OrderedDict for backwards compatibility. Some
packages import this.
2018-12-29 12:05:33 -05:00
142 changed files with 6424 additions and 5232 deletions

View File

@@ -1,2 +1,2 @@
[run]
omit = requests/packages/*
omit = requests/packages/*

5
.git-blame-ignore-revs Normal file
View File

@@ -0,0 +1,5 @@
# You can configure git to automatically use this file with the following config:
# git config --global blame.ignoreRevsFile .git-blame-ignore-revs
# Add automatic code formatting to Requests
2a6f290bc09324406708a4d404a88a45d848ddf9

6
.github/CODE_OF_CONDUCT.md vendored Normal file
View 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/).

View File

@@ -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
View File

@@ -0,0 +1 @@
custom: ['https://www.python.org/psf/sponsorship/']

View File

@@ -25,4 +25,4 @@ import requests
This command is only available on Requests v2.16.4 and greater. Otherwise,
please provide some basic information about your system (Python version,
operating system, &c).
operating system, &c).

View File

@@ -4,15 +4,15 @@ about: Create a report to help us improve
---
Summary.
<!-- Summary. -->
## Expected Result
What you expected.
<!-- What you expected. -->
## Actual Result
What happened instead.
<!-- What happened instead. -->
## Reproduction Steps
@@ -25,10 +25,12 @@ import requests
$ python -m requests.help
```
<paste here>
```json
{
"paste": "here"
}
```
This command is only available on Requests v2.16.4 and greater. Otherwise,
<!-- This command is only available on Requests v2.16.4 and greater. Otherwise,
please provide some basic information about your system (Python version,
operating system, &c).
operating system, &c). -->

View File

@@ -1,6 +1,9 @@
---
name: Request for Help
about: Guidance on using Requests.
labels:
- "Question/Not a bug"
- "actions/autoclose-qa"
---

View File

@@ -1,6 +1,9 @@
---
name: Feature request
about: Suggest an idea for this project
labels:
- "Feature Request"
- "actions/autoclose-feat"
---

84
.github/SECURITY.md vendored Normal file
View File

@@ -0,0 +1,84 @@
# Vulnerability Disclosure
If you think you have found a potential security vulnerability in
requests, please open a [draft Security Advisory](https://github.com/psf/requests/security/advisories/new)
via GitHub. We will coordinate verification and next steps through
that secure medium.
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:
- Python Maintenance Team, Red Hat (python-maint@redhat.com)
- 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.

11
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,11 @@
version: 2
updates:
- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
ignore:
# Ignore all patch releases as we can manually
# upgrade if we run into a bug and need a fix.
- dependency-name: "*"
update-types: ["version-update:semver-patch"]

35
.github/workflows/close-issues.yml vendored Normal file
View File

@@ -0,0 +1,35 @@
name: 'Autoclose Issues'
on:
issues:
types:
- labeled
permissions:
issues: write
jobs:
close_qa:
if: github.event.label.name == 'actions/autoclose-qa'
runs-on: ubuntu-latest
steps:
- env:
ISSUE_URL: ${{ github.event.issue.html_url }}
GH_TOKEN: ${{ github.token }}
run: |
gh issue close $ISSUE_URL \
--comment "As described in the template, we won't be able to answer questions on this issue tracker. Please use [Stack Overflow](https://stackoverflow.com/)" \
--reason completed
gh issue lock $ISSUE_URL --reason off_topic
close_feature_request:
if: github.event.label.name == 'actions/autoclose-feat'
runs-on: ubuntu-latest
steps:
- env:
ISSUE_URL: ${{ github.event.issue.html_url }}
GH_TOKEN: ${{ github.token }}
run: |
gh issue close $ISSUE_URL \
--comment "As described in the template, Requests is not accepting feature requests" \
--reason "not planned"
gh issue lock $ISSUE_URL --reason off_topic

73
.github/workflows/codeql-analysis.yml vendored Normal file
View File

@@ -0,0 +1,73 @@
# 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: [main]
pull_request:
# The branches below must be a subset of the branches above
branches: [main]
schedule:
- cron: '0 23 * * 0'
permissions:
contents: read
jobs:
analyze:
permissions:
actions: read # for github/codeql-action/init to get workflow details
contents: read # for actions/checkout to fetch code
security-events: write # for github/codeql-action/autobuild to send a status report
name: Analyze
runs-on: ubuntu-latest
strategy:
fail-fast: false
steps:
- name: Checkout repository
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
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@ce28f5bb42b7a9f2c824e633a3f6ee835bab6858 # v3.29.0
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@ce28f5bb42b7a9f2c824e633a3f6ee835bab6858 # v3.29.0
# 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@ce28f5bb42b7a9f2c824e633a3f6ee835bab6858 # v3.29.0

20
.github/workflows/lint.yml vendored Normal file
View File

@@ -0,0 +1,20 @@
name: Lint code
on: [push, pull_request]
permissions:
contents: read
jobs:
lint:
runs-on: ubuntu-24.04
timeout-minutes: 10
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Set up Python
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: "3.x"
- name: Run pre-commit
uses: pre-commit/action@646c83fcd040023954eafda54b4db0192ce70507 # v3.0.0

19
.github/workflows/lock-issues.yml vendored Normal file
View File

@@ -0,0 +1,19 @@
name: 'Lock Threads'
on:
schedule:
- cron: '0 0 * * *'
permissions:
issues: write
pull-requests: write
jobs:
action:
if: github.repository_owner == 'psf'
runs-on: ubuntu-latest
steps:
- uses: dessant/lock-threads@d42e5f49803f3c4e14ffee0378e31481265dda22 # v5.0.0
with:
issue-lock-inactive-days: 90
pr-lock-inactive-days: 90

93
.github/workflows/publish.yml vendored Normal file
View File

@@ -0,0 +1,93 @@
name: Publish to PyPI
on:
push:
tags:
- "v*"
permissions:
contents: read
jobs:
build:
name: "Build dists"
runs-on: "ubuntu-latest"
environment:
name: "publish"
outputs:
hashes: ${{ steps.hash.outputs.hashes }}
artifact-id: ${{ steps.upload-artifact.outputs.artifact-id }}
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit
- name: "Checkout repository"
uses: "actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8"
with:
persist-credentials: false
- name: "Setup Python"
uses: "actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065"
with:
python-version: "3.x"
- name: "Install dependencies"
run: python -m pip install build==0.8.0
- name: "Build dists"
run: |
SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct) \
python -m build
- name: "Generate hashes"
id: hash
run: |
cd dist && echo "::set-output name=hashes::$(sha256sum * | base64 -w0)"
- name: "Upload dists"
uses: "actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02"
id: upload-artifact
with:
name: "dist"
path: "dist/"
if-no-files-found: error
retention-days: 5
provenance:
needs: [build]
permissions:
actions: read
contents: write
id-token: write # Needed to access the workflow's OIDC identity.
uses: "slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.1.0"
with:
base64-subjects: "${{ needs.build.outputs.hashes }}"
upload-assets: true
compile-generator: true # Workaround for https://github.com/slsa-framework/slsa-github-generator/issues/1163
publish:
name: "Publish"
if: startsWith(github.ref, 'refs/tags/')
needs: ["build", "provenance"]
permissions:
contents: write
id-token: write
runs-on: "ubuntu-latest"
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit
- name: "Download dists"
uses: "actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0" # v5.0.0
with:
artifact-ids: ${{ needs.build.outputs.artifact-id }}
path: "dist/"
- name: "Publish dists to PyPI"
uses: "pypa/gh-action-pypi-publish@76f52bc884231f62b9a034ebfe128415bbaabdfc"

75
.github/workflows/run-tests.yml vendored Normal file
View File

@@ -0,0 +1,75 @@
name: Tests
on: [push, pull_request]
permissions:
contents: read
jobs:
build:
runs-on: ${{ matrix.os }}
timeout-minutes: 10
strategy:
fail-fast: false
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14-dev", "pypy-3.10", "pypy-3.11"]
os: [ubuntu-22.04, macOS-latest, windows-latest]
# Pypy-3.11 can't install openssl-sys with rust
# which prevents us from testing in GHA.
exclude:
- { python-version: "pypy-3.11", os: "windows-latest" }
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: ${{ matrix.python-version }}
cache: 'pip'
allow-prereleases: true
- name: Install dependencies
run: |
make
- name: Run tests
run: |
make ci
no_chardet:
name: "No Character Detection"
runs-on: ubuntu-latest
strategy:
fail-fast: true
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
- name: 'Set up Python 3.9'
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065
with:
python-version: '3.9'
- name: Install dependencies
run: |
make
python -m pip uninstall -y "charset_normalizer" "chardet"
- name: Run tests
run: |
make ci
urllib3:
name: 'urllib3 1.x'
runs-on: 'ubuntu-latest'
strategy:
fail-fast: true
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
- name: 'Set up Python 3.9'
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065
with:
python-version: '3.9'
- name: Install dependencies
run: |
make
python -m pip install "urllib3<2"
- name: Run tests
run: |
make ci

12
.gitignore vendored
View File

@@ -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

28
.pre-commit-config.yaml Normal file
View File

@@ -0,0 +1,28 @@
exclude: 'docs/|ext/'
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:
- id: check-yaml
- id: debug-statements
- id: end-of-file-fixer
- id: trailing-whitespace
- repo: https://github.com/PyCQA/isort
rev: 5.12.0
hooks:
- id: isort
- repo: https://github.com/psf/black
rev: 23.7.0
hooks:
- id: black
exclude: tests/test_lowlevel.py
- repo: https://github.com/asottile/pyupgrade
rev: v3.10.1
hooks:
- id: pyupgrade
args: [--py37-plus]
- repo: https://github.com/PyCQA/flake8
rev: 6.1.0
hooks:
- id: flake8

29
.readthedocs.yaml Normal file
View File

@@ -0,0 +1,29 @@
# Read the Docs configuration file for Sphinx projects
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
# Required
version: 2
# Set the OS, Python version and other tools you might need
build:
os: ubuntu-22.04
tools:
python: "3.12"
# Build documentation in the "docs/" directory with Sphinx
sphinx:
configuration: docs/conf.py
builder: "dirhtml"
# Optionally build your docs in additional formats such as PDF and ePub
formats:
- pdf
- epub
# Optional but recommended, declare the Python requirements required
# to build your documentation
# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html
python:
install:
- path: .
- requirements: docs/requirements.txt

View File

@@ -1,35 +0,0 @@
language: python
# command to install dependencies
install: "make"
# command to run tests
script:
- |
make test-readme
- 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.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
- stage: coverage
python: '3.6'
script: codecov

View File

@@ -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> `@kennethreitz <https://github.com/kennethreitz>`_, 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,8 @@ 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>`_)
- Hod Bin Noon (`@hodbn <https://github.com/hodbn>`_)
- Mike Fiedler (`@miketheman <https://github.com/miketheman>`_)

View File

@@ -1,3 +0,0 @@
Be cordial or be on your way.
https://www.kennethreitz.org/essays/be-cordial-or-be-on-your-way

View File

@@ -4,9 +4,372 @@ Release History
dev
---
- \[Short description of non-trivial change.\]
2.32.5 (2025-08-18)
-------------------
**Bugfixes**
- \[Short description of non-trivial change.\]
- The SSLContext caching feature originally introduced in 2.32.0 has created
a new class of issues in Requests that have had negative impact across a number
of use cases. The Requests team has decided to revert this feature as long term
maintenance of it is proving to be unsustainable in its current iteration.
**Deprecations**
- Added support for Python 3.14.
- Dropped support for Python 3.8 following its end of support.
2.32.4 (2025-06-10)
-------------------
**Security**
- CVE-2024-47081 Fixed an issue where a maliciously crafted URL and trusted
environment will retrieve credentials for the wrong hostname/machine from a
netrc file.
**Improvements**
- Numerous documentation improvements
**Deprecations**
- Added support for pypy 3.11 for Linux and macOS.
- Dropped support for pypy 3.9 following its end of support.
2.32.3 (2024-05-29)
-------------------
**Bugfixes**
- Fixed bug breaking the ability to specify custom SSLContexts in sub-classes of
HTTPAdapter. (#6716)
- Fixed issue where Requests started failing to run on Python versions compiled
without the `ssl` module. (#6724)
2.32.2 (2024-05-21)
-------------------
**Deprecations**
- To provide a more stable migration for custom HTTPAdapters impacted
by the CVE changes in 2.32.0, we've renamed `_get_connection` to
a new public API, `get_connection_with_tls_context`. Existing custom
HTTPAdapters will need to migrate their code to use this new API.
`get_connection` is considered deprecated in all versions of Requests>=2.32.0.
A minimal (2-line) example has been provided in the linked PR to ease
migration, but we strongly urge users to evaluate if their custom adapter
is subject to the same issue described in CVE-2024-35195. (#6710)
2.32.1 (2024-05-20)
-------------------
**Bugfixes**
- Add missing test certs to the sdist distributed on PyPI.
2.32.0 (2024-05-20)
-------------------
**Security**
- Fixed an issue where setting `verify=False` on the first request from a
Session will cause subsequent requests to the _same origin_ to also ignore
cert verification, regardless of the value of `verify`.
(https://github.com/psf/requests/security/advisories/GHSA-9wx4-h78v-vm56)
**Improvements**
- `verify=True` now reuses a global SSLContext which should improve
request time variance between first and subsequent requests. It should
also minimize certificate load time on Windows systems when using a Python
version built with OpenSSL 3.x. (#6667)
- Requests now supports optional use of character detection
(`chardet` or `charset_normalizer`) when repackaged or vendored.
This enables `pip` and other projects to minimize their vendoring
surface area. The `Response.text()` and `apparent_encoding` APIs
will default to `utf-8` if neither library is present. (#6702)
**Bugfixes**
- Fixed bug in length detection where emoji length was incorrectly
calculated in the request content-length. (#6589)
- Fixed deserialization bug in JSONDecodeError. (#6629)
- Fixed bug where an extra leading `/` (path separator) could lead
urllib3 to unnecessarily reparse the request URI. (#6644)
**Deprecations**
- Requests has officially added support for CPython 3.12 (#6503)
- Requests has officially added support for PyPy 3.9 and 3.10 (#6641)
- Requests has officially dropped support for CPython 3.7 (#6642)
- Requests has officially dropped support for PyPy 3.7 and 3.8 (#6641)
**Documentation**
- Various typo fixes and doc improvements.
**Packaging**
- Requests has started adopting some modern packaging practices.
The source files for the projects (formerly `requests`) is now located
in `src/requests` in the Requests sdist. (#6506)
- Starting in Requests 2.33.0, Requests will migrate to a PEP 517 build system
using `hatchling`. This should not impact the average user, but extremely old
versions of packaging utilities may have issues with the new packaging format.
2.31.0 (2023-05-22)
-------------------
**Security**
- Versions of Requests between v2.3.0 and v2.30.0 are vulnerable to potential
forwarding of `Proxy-Authorization` headers to destination servers when
following HTTPS redirects.
When proxies are defined with user info (`https://user:pass@proxy:8080`), Requests
will construct a `Proxy-Authorization` header that is attached to the request to
authenticate with the proxy.
In cases where Requests receives a redirect response, it previously reattached
the `Proxy-Authorization` header incorrectly, resulting in the value being
sent through the tunneled connection to the destination server. Users who rely on
defining their proxy credentials in the URL are *strongly* encouraged to upgrade
to Requests 2.31.0+ to prevent unintentional leakage and rotate their proxy
credentials once the change has been fully deployed.
Users who do not use a proxy or do not supply their proxy credentials through
the user information portion of their proxy URL are not subject to this
vulnerability.
Full details can be read in our [Github Security Advisory](https://github.com/psf/requests/security/advisories/GHSA-j8r2-6x86-q33q)
and [CVE-2023-32681](https://nvd.nist.gov/vuln/detail/CVE-2023-32681).
2.30.0 (2023-05-03)
-------------------
**Dependencies**
- ⚠️ Added support for urllib3 2.0. ⚠️
This may contain minor breaking changes so we advise careful testing and
reviewing https://urllib3.readthedocs.io/en/latest/v2-migration-guide.html
prior to upgrading.
Users who wish to stay on urllib3 1.x can pin to `urllib3<2`.
2.29.0 (2023-04-26)
-------------------
**Improvements**
- Requests now defers chunked requests to the urllib3 implementation to improve
standardization. (#6226)
- Requests relaxes header component requirements to support bytes/str subclasses. (#6356)
2.28.2 (2023-01-12)
-------------------
**Dependencies**
- Requests now supports charset\_normalizer 3.x. (#6261)
**Bugfixes**
- Updated MissingSchema exception to suggest https scheme rather than http. (#6188)
2.28.1 (2022-06-29)
-------------------
**Improvements**
- Speed optimization in `iter_content` with transition to `yield from`. (#6170)
**Dependencies**
- Added support for chardet 5.0.0 (#6179)
- Added support for charset-normalizer 2.1.0 (#6169)
2.28.0 (2022-06-09)
-------------------
**Deprecations**
- ⚠️ Requests has officially dropped support for Python 2.7. ⚠️ (#6091)
- Requests has officially dropped support for Python 3.6 (including pypy3.6). (#6091)
**Improvements**
- Wrap JSON parsing issues in Request's JSONDecodeError for payloads without
an encoding to make `json()` API consistent. (#6097)
- Parse header components consistently, raising an InvalidHeader error in
all invalid cases. (#6154)
- Added provisional 3.11 support with current beta build. (#6155)
- Requests got a makeover and we decided to paint it black. (#6095)
**Bugfixes**
- Fixed bug where setting `CURL_CA_BUNDLE` to an empty string would disable
cert verification. All Requests 2.x versions before 2.28.0 are affected. (#6074)
- Fixed urllib3 exception leak, wrapping `urllib3.exceptions.SSLError` with
`requests.exceptions.SSLError` for `content` and `iter_content`. (#6057)
- Fixed issue where invalid Windows registry entries caused proxy resolution
to raise an exception rather than ignoring the entry. (#6149)
- Fixed issue where entire payload could be included in the error message for
JSONDecodeError. (#6036)
2.27.1 (2022-01-05)
-------------------
**Bugfixes**
- Fixed parsing issue that resulted in the `auth` component being
dropped from proxy URLs. (#6028)
2.27.0 (2022-01-03)
-------------------
**Improvements**
- Officially added support for Python 3.10. (#5928)
- Added a `requests.exceptions.JSONDecodeError` to unify JSON exceptions between
Python 2 and 3. This gets raised in the `response.json()` method, and is
backwards compatible as it inherits from previously thrown exceptions.
Can be caught from `requests.exceptions.RequestException` as well. (#5856)
- Improved error text for misnamed `InvalidSchema` and `MissingSchema`
exceptions. This is a temporary fix until exceptions can be renamed
(Schema->Scheme). (#6017)
- Improved proxy parsing for proxy URLs missing a scheme. This will address
recent changes to `urlparse` in Python 3.9+. (#5917)
**Bugfixes**
- Fixed defect in `extract_zipped_paths` which could result in an infinite loop
for some paths. (#5851)
- Fixed handling for `AttributeError` when calculating length of files obtained
by `Tarfile.extractfile()`. (#5239)
- Fixed urllib3 exception leak, wrapping `urllib3.exceptions.InvalidHeader` with
`requests.exceptions.InvalidHeader`. (#5914)
- Fixed bug where two Host headers were sent for chunked requests. (#5391)
- Fixed regression in Requests 2.26.0 where `Proxy-Authorization` was
incorrectly stripped from all requests sent with `Session.send`. (#5924)
- Fixed performance regression in 2.26.0 for hosts with a large number of
proxies available in the environment. (#5924)
- Fixed idna exception leak, wrapping `UnicodeError` with
`requests.exceptions.InvalidURL` for URLs with a leading dot (.) in the
domain. (#5414)
**Deprecations**
- Requests support for Python 2.7 and 3.6 will be ending in 2022. While we
don't have exact dates, Requests 2.27.x is likely to be the last release
series providing support.
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**
- 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 every time a dependency is updated.
2.22.0 (2019-05-15)
-------------------
@@ -361,7 +724,7 @@ Or, even better:
- Fixed regression from 2.12.2 where non-string types were rejected in
the basic auth parameters. While support for this behaviour has been
readded, the behaviour is deprecated and will be removed in the
re-added, the behaviour is deprecated and will be removed in the
future.
2.12.3 (2016-12-01)
@@ -549,7 +912,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.
@@ -629,7 +992,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**
@@ -793,7 +1156,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)
------------------
@@ -801,26 +1164,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)
------------------
@@ -1595,12 +1958,12 @@ This is not a backwards compatible change.
- Automatic Authentication API Change
- Smarter Query URL Parameterization
- Allow file uploads and POST data together
-
-
New Authentication Manager System
: - Simpler Basic HTTP System
- Supports all build-in urllib2 Auths
- Supports all built-in urllib2 Auths
- Allows for custom Auth Handlers
0.2.4 (2011-02-19)
@@ -1614,7 +1977,7 @@ This is not a backwards compatible change.
0.2.3 (2011-02-15)
------------------
-
-
New HTTPHandling Methods
@@ -1647,4 +2010,3 @@ This is not a backwards compatible change.
- Frustration
- Conception

182
LICENSE
View File

@@ -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.

View File

@@ -1,2 +1,3 @@
include README.md LICENSE NOTICE HISTORY.md pytest.ini requirements.txt Pipfile Pipfile.lock
include README.md LICENSE NOTICE HISTORY.md requirements-dev.txt
recursive-include tests *.py
recursive-include tests/certs *

View File

@@ -1,28 +1,27 @@
.PHONY: docs
init:
pip install pipenv --upgrade
pipenv install --dev
python -m pip install -r requirements-dev.txt
test:
# This runs all of the tests, on both Python 2 and Python 3.
detox
python -m pytest tests
ci:
pipenv run py.test -n 8 --boxed --junitxml=report.xml
python -m 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!"
flake8:
pipenv run flake8 --ignore=E501,F401,E128,E402,E731,F821 requests
python setup.py check --restructuredtext --strict && ([ $$? -eq 0 ] && echo "README.rst and HISTORY.rst ok") || echo "Invalid markup in README.rst or HISTORY.rst!"
coverage:
pipenv run py.test --cov-config .coveragerc --verbose --cov-report term --cov-report xml --cov=requests tests
python -m pytest --cov-config .coveragerc --verbose --cov-report term --cov-report xml --cov=src/requests tests
publish:
pip install 'twine>=1.5.0'
python setup.py sdist bdist_wheel
twine upload dist/*
.publishenv:
python -m venv .publishenv
.publishenv/bin/pip install 'twine>=1.5.0' build
publish: .publishenv
.publishenv/bin/python -m build
.publishenv/bin/python -m twine upload --skip-existing dist/*
rm -fr build dist .egg requests.egg-info
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"

2
NOTICE Normal file
View File

@@ -0,0 +1,2 @@
Requests
Copyright 2019 Kenneth Reitz

24
Pipfile
View File

@@ -1,24 +0,0 @@
[[source]]
url = "https://pypi.org/simple/"
verify_ssl = true
name = "pypi"
[dev-packages]
pytest = ">=2.8.0,<=3.10.1"
codecov = "*"
pytest-httpbin = ">=0.0.7,<1.0"
pytest-mock = "*"
pytest-cov = "*"
pytest-xdist = "<=1.25"
alabaster = "*"
readme-renderer = "*"
sphinx = "<=1.5.5"
pysocks = "*"
docutils = "*"
"flake8" = "*"
tox = "*"
detox = "*"
httpbin = ">=0.7.0"
[packages]
"e1839a8" = {path = ".", editable = true, extras = ["socks"]}

738
Pipfile.lock generated
View File

@@ -1,738 +0,0 @@
{
"_meta": {
"hash": {
"sha256": "33206a3ef69c36187f33224ccf8e694a323ff4f7b2cc92c35fe8e71898b525a0"
},
"pipfile-spec": 6,
"requires": {},
"sources": [
{
"name": "pypi",
"url": "https://pypi.org/simple/",
"verify_ssl": true
}
]
},
"default": {
"certifi": {
"hashes": [
"sha256:59b7658e26ca9c7339e00f8f4636cdfe59d34fa37b9b04f6f9e9926b3cece1a5",
"sha256:b26104d6835d1f5e49452a26eb2ff87fe7090b89dfcaee5ea2212697e1e1d7ae"
],
"version": "==2019.3.9"
},
"chardet": {
"hashes": [
"sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae",
"sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"
],
"version": "==3.0.4"
},
"e1839a8": {
"editable": true,
"extras": [
"socks"
],
"path": "."
},
"idna": {
"hashes": [
"sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407",
"sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c"
],
"version": "==2.8"
},
"pysocks": {
"hashes": [
"sha256:15d38914b60dbcb231d276f64882a20435c049450160e953ca7d313d1405f16f",
"sha256:32238918ac0f19e9fd870a8692ac9bd14f5e8752b3c62624cda5851424642210",
"sha256:d9031ea45fdfacbe59a99273e9f0448ddb33c1580fe3831c1b09557c5718977c"
],
"version": "==1.7.0"
},
"requests": {
"editable": true,
"extras": [
"socks"
],
"path": ".",
"version": "==2.22.0"
},
"urllib3": {
"hashes": [
"sha256:a53063d8b9210a7bdec15e7b272776b9d42b2fd6816401a0d43006ad2f9902db",
"sha256:d363e3607d8de0c220d31950a8f38b18d5ba7c0830facd71a1c6b1036b7ce06c"
],
"version": "==1.25.2"
},
"win-inet-pton": {
"hashes": [
"sha256:dd03d942c0d3e2b1cf8bab511844546dfa5f74cb61b241699fa379ad707dea4f",
"sha256:eaf0193cbe7152ac313598a0da7313fb479f769343c0c16c5308f64887dc885b"
],
"markers": "sys_platform == 'win32' and python_version == '2.7'",
"version": "==1.1.0"
}
},
"develop": {
"alabaster": {
"hashes": [
"sha256:446438bdcca0e05bd45ea2de1668c1d9b032e1a9154c2c259092d77031ddd359",
"sha256:a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02"
],
"index": "pypi",
"version": "==0.7.12"
},
"apipkg": {
"hashes": [
"sha256:37228cda29411948b422fae072f57e31d3396d2ee1c9783775980ee9c9990af6",
"sha256:58587dd4dc3daefad0487f6d9ae32b4542b185e1c36db6993290e7c41ca2b47c"
],
"version": "==1.5"
},
"atomicwrites": {
"hashes": [
"sha256:03472c30eb2c5d1ba9227e4c2ca66ab8287fbfbbda3888aa93dc2e28fc6811b4",
"sha256:75a9445bac02d8d058d5e1fe689654ba5a6556a1dfd8ce6ec55a0ed79866cfa6"
],
"version": "==1.3.0"
},
"attrs": {
"hashes": [
"sha256:69c0dbf2ed392de1cb5ec704444b08a5ef81680a61cb899dc08127123af36a79",
"sha256:f0b870f674851ecbfbbbd364d6b5cbdff9dcedbc7f3f5e18a6891057f21fe399"
],
"version": "==19.1.0"
},
"babel": {
"hashes": [
"sha256:6778d85147d5d85345c14a26aada5e478ab04e39b078b0745ee6870c2b5cf669",
"sha256:8cba50f48c529ca3fa18cf81fa9403be176d374ac4d60738b839122dfaaa3d23"
],
"version": "==2.6.0"
},
"bleach": {
"hashes": [
"sha256:213336e49e102af26d9cde77dd2d0397afabc5a6bf2fed985dc35b5d1e285a16",
"sha256:3fdf7f77adcf649c9911387df51254b813185e32b2c6619f690b593a617e19fa"
],
"version": "==3.1.0"
},
"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:59b7658e26ca9c7339e00f8f4636cdfe59d34fa37b9b04f6f9e9926b3cece1a5",
"sha256:b26104d6835d1f5e49452a26eb2ff87fe7090b89dfcaee5ea2212697e1e1d7ae"
],
"version": "==2019.3.9"
},
"cffi": {
"hashes": [
"sha256:041c81822e9f84b1d9c401182e174996f0bae9991f33725d059b771744290774",
"sha256:046ef9a22f5d3eed06334d01b1e836977eeef500d9b78e9ef693f9380ad0b83d",
"sha256:066bc4c7895c91812eff46f4b1c285220947d4aa46fa0a2651ff85f2afae9c90",
"sha256:066c7ff148ae33040c01058662d6752fd73fbc8e64787229ea8498c7d7f4041b",
"sha256:2444d0c61f03dcd26dbf7600cf64354376ee579acad77aef459e34efcb438c63",
"sha256:300832850b8f7967e278870c5d51e3819b9aad8f0a2c8dbe39ab11f119237f45",
"sha256:34c77afe85b6b9e967bd8154e3855e847b70ca42043db6ad17f26899a3df1b25",
"sha256:46de5fa00f7ac09f020729148ff632819649b3e05a007d286242c4882f7b1dc3",
"sha256:4aa8ee7ba27c472d429b980c51e714a24f47ca296d53f4d7868075b175866f4b",
"sha256:4d0004eb4351e35ed950c14c11e734182591465a33e960a4ab5e8d4f04d72647",
"sha256:4e3d3f31a1e202b0f5a35ba3bc4eb41e2fc2b11c1eff38b362de710bcffb5016",
"sha256:50bec6d35e6b1aaeb17f7c4e2b9374ebf95a8975d57863546fa83e8d31bdb8c4",
"sha256:55cad9a6df1e2a1d62063f79d0881a414a906a6962bc160ac968cc03ed3efcfb",
"sha256:5662ad4e4e84f1eaa8efce5da695c5d2e229c563f9d5ce5b0113f71321bcf753",
"sha256:59b4dc008f98fc6ee2bb4fd7fc786a8d70000d058c2bbe2698275bc53a8d3fa7",
"sha256:73e1ffefe05e4ccd7bcea61af76f36077b914f92b76f95ccf00b0c1b9186f3f9",
"sha256:a1f0fd46eba2d71ce1589f7e50a9e2ffaeb739fb2c11e8192aa2b45d5f6cc41f",
"sha256:a2e85dc204556657661051ff4bab75a84e968669765c8a2cd425918699c3d0e8",
"sha256:a5457d47dfff24882a21492e5815f891c0ca35fefae8aa742c6c263dac16ef1f",
"sha256:a8dccd61d52a8dae4a825cdbb7735da530179fea472903eb871a5513b5abbfdc",
"sha256:ae61af521ed676cf16ae94f30fe202781a38d7178b6b4ab622e4eec8cefaff42",
"sha256:b012a5edb48288f77a63dba0840c92d0504aa215612da4541b7b42d849bc83a3",
"sha256:d2c5cfa536227f57f97c92ac30c8109688ace8fa4ac086d19d0af47d134e2909",
"sha256:d42b5796e20aacc9d15e66befb7a345454eef794fdb0737d1af593447c6c8f45",
"sha256:dee54f5d30d775f525894d67b1495625dd9322945e7fee00731952e0368ff42d",
"sha256:e070535507bd6aa07124258171be2ee8dfc19119c28ca94c9dfb7efd23564512",
"sha256:e1ff2748c84d97b065cc95429814cdba39bcbd77c9c85c89344b317dc0d9cbff",
"sha256:ed851c75d1e0e043cbf5ca9a8e1b13c4c90f3fbd863dacb01c0808e2b5204201"
],
"version": "==1.12.3"
},
"chardet": {
"hashes": [
"sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae",
"sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"
],
"version": "==3.0.4"
},
"click": {
"hashes": [
"sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13",
"sha256:5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7"
],
"version": "==7.0"
},
"codecov": {
"hashes": [
"sha256:8ed8b7c6791010d359baed66f84f061bba5bd41174bf324c31311e8737602788",
"sha256:ae00d68e18d8a20e9c3288ba3875ae03db3a8e892115bf9b83ef20507732bed4"
],
"index": "pypi",
"version": "==2.0.15"
},
"configparser": {
"hashes": [
"sha256:8be81d89d6e7b4c0d4e44bcc525845f6da25821de80cb5e06e7e0238a2899e32",
"sha256:da60d0014fd8c55eb48c1c5354352e363e2d30bbf7057e5e171a468390184c75"
],
"markers": "python_version < '3.2'",
"version": "==3.7.4"
},
"contextlib2": {
"hashes": [
"sha256:509f9419ee91cdd00ba34443217d5ca51f5a364a404e1dce9e8979cea969ca48",
"sha256:f5260a6e679d2ff42ec91ec5252f4eeffdcf21053db9113bd0a8e4d953769c00"
],
"markers": "python_version < '3.2'",
"version": "==0.5.5"
},
"coverage": {
"hashes": [
"sha256:0c5fe441b9cfdab64719f24e9684502a59432df7570521563d7b1aff27ac755f",
"sha256:2b412abc4c7d6e019ce7c27cbc229783035eef6d5401695dccba80f481be4eb3",
"sha256:3684fabf6b87a369017756b551cef29e505cb155ddb892a7a29277b978da88b9",
"sha256:39e088da9b284f1bd17c750ac672103779f7954ce6125fd4382134ac8d152d74",
"sha256:3c205bc11cc4fcc57b761c2da73b9b72a59f8d5ca89979afb0c1c6f9e53c7390",
"sha256:42692db854d13c6c5e9541b6ffe0fe921fe16c9c446358d642ccae1462582d3b",
"sha256:465ce53a8c0f3a7950dfb836438442f833cf6663d407f37d8c52fe7b6e56d7e8",
"sha256:48020e343fc40f72a442c8a1334284620f81295256a6b6ca6d8aa1350c763bbe",
"sha256:4ec30ade438d1711562f3786bea33a9da6107414aed60a5daa974d50a8c2c351",
"sha256:5296fc86ab612ec12394565c500b412a43b328b3907c0d14358950d06fd83baf",
"sha256:5f61bed2f7d9b6a9ab935150a6b23d7f84b8055524e7be7715b6513f3328138e",
"sha256:6899797ac384b239ce1926f3cb86ffc19996f6fa3a1efbb23cb49e0c12d8c18c",
"sha256:68a43a9f9f83693ce0414d17e019daee7ab3f7113a70c79a3dd4c2f704e4d741",
"sha256:6b8033d47fe22506856fe450470ccb1d8ba1ffb8463494a15cfc96392a288c09",
"sha256:7ad7536066b28863e5835e8cfeaa794b7fe352d99a8cded9f43d1161be8e9fbd",
"sha256:7bacb89ccf4bedb30b277e96e4cc68cd1369ca6841bde7b005191b54d3dd1034",
"sha256:839dc7c36501254e14331bcb98b27002aa415e4af7ea039d9009409b9d2d5420",
"sha256:8e679d1bde5e2de4a909efb071f14b472a678b788904440779d2c449c0355b27",
"sha256:8f9a95b66969cdea53ec992ecea5406c5bd99c9221f539bca1e8406b200ae98c",
"sha256:932c03d2d565f75961ba1d3cec41ddde00e162c5b46d03f7423edcb807734eab",
"sha256:93f965415cc51604f571e491f280cff0f5be35895b4eb5e55b47ae90c02a497b",
"sha256:988529edadc49039d205e0aa6ce049c5ccda4acb2d6c3c5c550c17e8c02c05ba",
"sha256:998d7e73548fe395eeb294495a04d38942edb66d1fa61eb70418871bc621227e",
"sha256:9de60893fb447d1e797f6bf08fdf0dbcda0c1e34c1b06c92bd3a363c0ea8c609",
"sha256:9e80d45d0c7fcee54e22771db7f1b0b126fb4a6c0a2e5afa72f66827207ff2f2",
"sha256:a545a3dfe5082dc8e8c3eb7f8a2cf4f2870902ff1860bd99b6198cfd1f9d1f49",
"sha256:a5d8f29e5ec661143621a8f4de51adfb300d7a476224156a39a392254f70687b",
"sha256:a9abc8c480e103dc05d9b332c6cc9fb1586330356fc14f1aa9c0ca5745097d19",
"sha256:aca06bfba4759bbdb09bf52ebb15ae20268ee1f6747417837926fae990ebc41d",
"sha256:bb23b7a6fd666e551a3094ab896a57809e010059540ad20acbeec03a154224ce",
"sha256:bfd1d0ae7e292105f29d7deaa9d8f2916ed8553ab9d5f39ec65bcf5deadff3f9",
"sha256:c22ab9f96cbaff05c6a84e20ec856383d27eae09e511d3e6ac4479489195861d",
"sha256:c62ca0a38958f541a73cf86acdab020c2091631c137bd359c4f5bddde7b75fd4",
"sha256:c709d8bda72cf4cd348ccec2a4881f2c5848fd72903c185f363d361b2737f773",
"sha256:c968a6aa7e0b56ecbd28531ddf439c2ec103610d3e2bf3b75b813304f8cb7723",
"sha256:ca58eba39c68010d7e87a823f22a081b5290e3e3c64714aac3c91481d8b34d22",
"sha256:df785d8cb80539d0b55fd47183264b7002077859028dfe3070cf6359bf8b2d9c",
"sha256:f406628ca51e0ae90ae76ea8398677a921b36f0bd71aab2099dfed08abd0322f",
"sha256:f46087bbd95ebae244a0eda01a618aff11ec7a069b15a3ef8f6b520db523dcf1",
"sha256:f8019c5279eb32360ca03e9fac40a12667715546eed5c5eb59eb381f2f501260",
"sha256:fc5f4d209733750afd2714e9109816a29500718b32dd9a5db01c0cb3a019b96a"
],
"version": "==4.5.3"
},
"decorator": {
"hashes": [
"sha256:86156361c50488b84a3f148056ea716ca587df2f0de1d34750d35c21312725de",
"sha256:f069f3a01830ca754ba5258fde2278454a0b5b79e0d7f5c13b3b97e57d4acff6"
],
"version": "==4.4.0"
},
"detox": {
"hashes": [
"sha256:e650f95f0c7f5858578014b3b193e5dac76c89285c1bbe4bae598fd641bf9cd3",
"sha256:fcad009e2d20ce61176dc826a2c1562bd712fe53953ca603b455171cf819080f"
],
"index": "pypi",
"version": "==0.19"
},
"dnspython": {
"hashes": [
"sha256:36c5e8e38d4369a08b6780b7f27d790a292b2b08eea01607865bf0936c558e01",
"sha256:f69c21288a962f4da86e56c4905b49d11aba7938d3d740e80d9e366ee4f1632d"
],
"version": "==1.16.0"
},
"docutils": {
"hashes": [
"sha256:02aec4bd92ab067f6ff27a38a38a41173bf01bed8f89157768c1573f53e474a6",
"sha256:51e64ef2ebfb29cae1faa133b3710143496eca21c530f3f71424d77687764274",
"sha256:7a4bd47eaf6596e1295ecb11361139febe29b084a87bf005bf899f9a42edc3c6"
],
"index": "pypi",
"version": "==0.14"
},
"entrypoints": {
"hashes": [
"sha256:589f874b313739ad35be6e0cd7efde2a4e9b6fea91edcc34e58ecbb8dbe56d19",
"sha256:c70dd71abe5a8c85e55e12c19bd91ccfeec11a6e99044204511f9ed547d48451"
],
"version": "==0.3"
},
"enum34": {
"hashes": [
"sha256:2d81cbbe0e73112bdfe6ef8576f2238f2ba27dd0d55752a776c41d38b7da2850",
"sha256:644837f692e5f550741432dd3f223bbb9852018674981b1664e5dc339387588a",
"sha256:6bd0f6ad48ec2aa117d3d141940d484deccda84d4fcd884f5c3d93c23ecd8c79",
"sha256:8ad8c4783bf61ded74527bffb48ed9b54166685e4230386a9ed9b1279e2df5b1"
],
"markers": "python_version < '3.4'",
"version": "==1.1.6"
},
"eventlet": {
"hashes": [
"sha256:c584163e006e613707e224552fafc63e4e0aa31d7de0ab18b481ac0b385254c8",
"sha256:d9d31a3c8dbcedbcce5859a919956d934685b17323fc80e1077cb344a2ffa68d"
],
"version": "==0.24.1"
},
"execnet": {
"hashes": [
"sha256:027ee5d961afa01e97b90d6ccc34b4ed976702bc58e7f092b3c513ea288cb6d2",
"sha256:752a3786f17416d491f833a29217dda3ea4a471fc5269c492eebcee8cc4772d3"
],
"version": "==1.6.0"
},
"filelock": {
"hashes": [
"sha256:b8d5ca5ca1c815e1574aee746650ea7301de63d87935b3463d26368b76e31633",
"sha256:d610c1bb404daf85976d7a82eb2ada120f04671007266b708606565dd03b5be6"
],
"version": "==3.0.10"
},
"flake8": {
"hashes": [
"sha256:859996073f341f2670741b51ec1e67a01da142831aa1fdc6242dbf88dffbe661",
"sha256:a796a115208f5c03b18f332f7c11729812c8c3ded6c46319c59b53efd3819da8"
],
"index": "pypi",
"version": "==3.7.7"
},
"flask": {
"hashes": [
"sha256:2271c0070dbcb5275fad4a82e29f23ab92682dc45f9dfbc22c02ba9b9322ce48",
"sha256:a080b744b7e345ccfcbc77954861cb05b3c63786e93f2b3875e0913d44b43f05"
],
"version": "==1.0.2"
},
"funcsigs": {
"hashes": [
"sha256:330cc27ccbf7f1e992e69fef78261dc7c6569012cf397db8d3de0234e6c937ca",
"sha256:a7bb0f2cf3a3fd1ab2732cb49eba4252c2af4240442415b4abce3b87022a8f50"
],
"markers": "python_version < '3.0'",
"version": "==1.0.2"
},
"functools32": {
"hashes": [
"sha256:89d824aa6c358c421a234d7f9ee0bd75933a67c29588ce50aaa3acdf4d403fa0",
"sha256:f6253dfbe0538ad2e387bd8fdfd9293c925d63553f5813c4e587745416501e6d"
],
"markers": "python_version < '3.2'",
"version": "==3.2.3.post2"
},
"greenlet": {
"hashes": [
"sha256:000546ad01e6389e98626c1367be58efa613fa82a1be98b0c6fc24b563acc6d0",
"sha256:0d48200bc50cbf498716712129eef819b1729339e34c3ae71656964dac907c28",
"sha256:23d12eacffa9d0f290c0fe0c4e81ba6d5f3a5b7ac3c30a5eaf0126bf4deda5c8",
"sha256:37c9ba82bd82eb6a23c2e5acc03055c0e45697253b2393c9a50cef76a3985304",
"sha256:51503524dd6f152ab4ad1fbd168fc6c30b5795e8c70be4410a64940b3abb55c0",
"sha256:8041e2de00e745c0e05a502d6e6db310db7faa7c979b3a5877123548a4c0b214",
"sha256:81fcd96a275209ef117e9ec91f75c731fa18dcfd9ffaa1c0adbdaa3616a86043",
"sha256:853da4f9563d982e4121fed8c92eea1a4594a2299037b3034c3c898cb8e933d6",
"sha256:8b4572c334593d449113f9dc8d19b93b7b271bdbe90ba7509eb178923327b625",
"sha256:9416443e219356e3c31f1f918a91badf2e37acf297e2fa13d24d1cc2380f8fbc",
"sha256:9854f612e1b59ec66804931df5add3b2d5ef0067748ea29dc60f0efdcda9a638",
"sha256:99a26afdb82ea83a265137a398f570402aa1f2b5dfb4ac3300c026931817b163",
"sha256:a19bf883b3384957e4a4a13e6bd1ae3d85ae87f4beb5957e35b0be287f12f4e4",
"sha256:a9f145660588187ff835c55a7d2ddf6abfc570c2651c276d3d4be8a2766db490",
"sha256:ac57fcdcfb0b73bb3203b58a14501abb7e5ff9ea5e2edfa06bb03035f0cff248",
"sha256:bcb530089ff24f6458a81ac3fa699e8c00194208a724b644ecc68422e1111939",
"sha256:beeabe25c3b704f7d56b573f7d2ff88fc99f0138e43480cecdfcaa3b87fe4f87",
"sha256:d634a7ea1fc3380ff96f9e44d8d22f38418c1c381d5fac680b272d7d90883720",
"sha256:d97b0661e1aead761f0ded3b769044bb00ed5d33e1ec865e891a8b128bf7c656"
],
"version": "==0.4.15"
},
"httpbin": {
"hashes": [
"sha256:7a04b5904c80b7aa04dd0a6af6520d68ce17a5db175e66a64b971f8e93d73a26",
"sha256:cbb37790c91575f4f15757f42ad41d9f729eb227d5edbe89e4ec175486db8dfa"
],
"index": "pypi",
"version": "==0.7.0"
},
"idna": {
"hashes": [
"sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407",
"sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c"
],
"version": "==2.8"
},
"imagesize": {
"hashes": [
"sha256:3f349de3eb99145973fefb7dbe38554414e5c30abd0c8e4b970a7c9d09f3a1d8",
"sha256:f3832918bc3c66617f92e35f5d70729187676313caa60c187eb0f28b8fe5e3b5"
],
"version": "==1.1.0"
},
"itsdangerous": {
"hashes": [
"sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19",
"sha256:b12271b2047cb23eeb98c8b5622e2e5c5e9abd9784a153e9d8ef9cb4dd09d749"
],
"version": "==1.1.0"
},
"jinja2": {
"hashes": [
"sha256:065c4f02ebe7f7cf559e49ee5a95fb800a9e4528727aec6f24402a5374c65013",
"sha256:14dd6caf1527abb21f08f86c784eac40853ba93edb79552aa1e4b8aef1b61c7b"
],
"version": "==2.10.1"
},
"markupsafe": {
"hashes": [
"sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473",
"sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161",
"sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235",
"sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5",
"sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff",
"sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b",
"sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1",
"sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e",
"sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183",
"sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66",
"sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1",
"sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1",
"sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e",
"sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b",
"sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905",
"sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735",
"sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d",
"sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e",
"sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d",
"sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c",
"sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21",
"sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2",
"sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5",
"sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b",
"sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6",
"sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f",
"sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f",
"sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7"
],
"version": "==1.1.1"
},
"mccabe": {
"hashes": [
"sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42",
"sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"
],
"version": "==0.6.1"
},
"mock": {
"hashes": [
"sha256:83657d894c90d5681d62155c82bda9c1187827525880eda8ff5df4ec813437c3",
"sha256:d157e52d4e5b938c550f39eb2fd15610db062441a9c2747d3dbfa9298211d0f8"
],
"markers": "python_version < '3.0'",
"version": "==3.0.5"
},
"monotonic": {
"hashes": [
"sha256:23953d55076df038541e648a53676fb24980f7a1be290cdda21300b3bc21dfb0",
"sha256:552a91f381532e33cbd07c6a2655a21908088962bb8fa7239ecbcc6ad1140cc7"
],
"version": "==1.5"
},
"more-itertools": {
"hashes": [
"sha256:38a936c0a6d98a38bcc2d03fdaaedaba9f412879461dd2ceff8d37564d6522e4",
"sha256:c0a5785b1109a6bd7fac76d6837fd1feca158e54e521ccd2ae8bfe393cc9d4fc",
"sha256:fe7a7cae1ccb57d33952113ff4fa1bc5f879963600ed74918f1236e212ee50b9"
],
"version": "==5.0.0"
},
"pathlib2": {
"hashes": [
"sha256:25199318e8cc3c25dcb45cbe084cc061051336d5a9ea2a12448d3d8cb748f742",
"sha256:5887121d7f7df3603bca2f710e7219f3eca0eb69e0b7cc6e0a022e155ac931a7"
],
"markers": "python_version < '3.6'",
"version": "==2.3.3"
},
"pluggy": {
"hashes": [
"sha256:25a1bc1d148c9a640211872b4ff859878d422bccb59c9965e04eed468a0aa180",
"sha256:964cedd2b27c492fbf0b7f58b3284a09cf7f99b0f715941fb24a439b3af1bd1a"
],
"version": "==0.11.0"
},
"py": {
"hashes": [
"sha256:64f65755aee5b381cea27766a3a147c3f15b9b6b9ac88676de66ba2ae36793fa",
"sha256:dc639b046a6e2cff5bbe40194ad65936d6ba360b52b3c3fe1d08a82dd50b5e53"
],
"version": "==1.8.0"
},
"pycodestyle": {
"hashes": [
"sha256:95a2219d12372f05704562a14ec30bc76b05a5b297b21a5dfe3f6fac3491ae56",
"sha256:e40a936c9a450ad81df37f549d676d127b1b66000a6c500caa2b085bc0ca976c"
],
"version": "==2.5.0"
},
"pycparser": {
"hashes": [
"sha256:a988718abfad80b6b157acce7bf130a30876d27603738ac39f140993246b25b3"
],
"version": "==2.19"
},
"pyflakes": {
"hashes": [
"sha256:17dbeb2e3f4d772725c777fabc446d5634d1038f234e77343108ce445ea69ce0",
"sha256:d976835886f8c5b31d47970ed689944a0262b5f3afa00a5a7b4dc81e5449f8a2"
],
"version": "==2.1.1"
},
"pygments": {
"hashes": [
"sha256:31cba6ffb739f099a85e243eff8cb717089fdd3c7300767d9fc34cb8e1b065f5",
"sha256:5ad302949b3c98dd73f8d9fcdc7e9cb592f120e32a18e23efd7f3dc51194472b"
],
"version": "==2.4.0"
},
"pysocks": {
"hashes": [
"sha256:15d38914b60dbcb231d276f64882a20435c049450160e953ca7d313d1405f16f",
"sha256:32238918ac0f19e9fd870a8692ac9bd14f5e8752b3c62624cda5851424642210",
"sha256:d9031ea45fdfacbe59a99273e9f0448ddb33c1580fe3831c1b09557c5718977c"
],
"version": "==1.7.0"
},
"pytest": {
"hashes": [
"sha256:3f193df1cfe1d1609d4c583838bea3d532b18d6160fd3f55c9447fdca30848ec",
"sha256:e246cf173c01169b9617fc07264b7b1316e78d7a650055235d6d897bc80d9660"
],
"index": "pypi",
"version": "==3.10.1"
},
"pytest-cov": {
"hashes": [
"sha256:2b097cde81a302e1047331b48cadacf23577e431b61e9c6f49a1170bbe3d3da6",
"sha256:e00ea4fdde970725482f1f35630d12f074e121a23801aabf2ae154ec6bdd343a"
],
"index": "pypi",
"version": "==2.7.1"
},
"pytest-forked": {
"hashes": [
"sha256:5fe33fbd07d7b1302c95310803a5e5726a4ff7f19d5a542b7ce57c76fed8135f",
"sha256:d352aaced2ebd54d42a65825722cb433004b4446ab5d2044851d9cc7a00c9e38"
],
"version": "==1.0.2"
},
"pytest-httpbin": {
"hashes": [
"sha256:8cd57e27418a7d7d205fcc9802eea246ed06170e3065abfa76c6d9b40553592c",
"sha256:d3919c5df0b644454129c0066a8ae62db40ac54bacb4cfd89d8cfa58615a4b42"
],
"index": "pypi",
"version": "==0.3.0"
},
"pytest-mock": {
"hashes": [
"sha256:43ce4e9dd5074993e7c021bb1c22cbb5363e612a2b5a76bc6d956775b10758b7",
"sha256:5bf5771b1db93beac965a7347dc81c675ec4090cb841e49d9d34637a25c30568"
],
"index": "pypi",
"version": "==1.10.4"
},
"pytest-xdist": {
"hashes": [
"sha256:96f893094c89fddeaff3f4783f4807f7aeb138be1a0d87a8805057b6af1201b5",
"sha256:aab1402f2b063df48bf044b042707610f8fcc4c49d0eb9c10e79e30b3f26074f"
],
"index": "pypi",
"version": "==1.25.0"
},
"pytz": {
"hashes": [
"sha256:303879e36b721603cc54604edcac9d20401bdbe31e1e4fdee5b9f98d5d31dfda",
"sha256:d747dd3d23d77ef44c6a3526e274af6efeb0a6f1afd5a69ba4d5be4098c8e141"
],
"version": "==2019.1"
},
"raven": {
"extras": [
"flask"
],
"hashes": [
"sha256:3fa6de6efa2493a7c827472e984ce9b020797d0da16f1db67197bcc23c8fae54",
"sha256:44a13f87670836e153951af9a3c80405d36b43097db869a36e92809673692ce4"
],
"version": "==6.10.0"
},
"readme-renderer": {
"hashes": [
"sha256:bb16f55b259f27f75f640acf5e00cf897845a8b3e4731b5c1a436e4b8529202f",
"sha256:c8532b79afc0375a85f10433eca157d6b50f7d6990f337fa498c96cd4bfc203d"
],
"index": "pypi",
"version": "==24.0"
},
"requests": {
"editable": true,
"extras": [
"socks"
],
"path": ".",
"version": "==2.22.0"
},
"scandir": {
"hashes": [
"sha256:2586c94e907d99617887daed6c1d102b5ca28f1085f90446554abf1faf73123e",
"sha256:2ae41f43797ca0c11591c0c35f2f5875fa99f8797cb1a1fd440497ec0ae4b022",
"sha256:2b8e3888b11abb2217a32af0766bc06b65cc4a928d8727828ee68af5a967fa6f",
"sha256:2c712840c2e2ee8dfaf36034080108d30060d759c7b73a01a52251cc8989f11f",
"sha256:4d4631f6062e658e9007ab3149a9b914f3548cb38bfb021c64f39a025ce578ae",
"sha256:67f15b6f83e6507fdc6fca22fedf6ef8b334b399ca27c6b568cbfaa82a364173",
"sha256:7d2d7a06a252764061a020407b997dd036f7bd6a175a5ba2b345f0a357f0b3f4",
"sha256:8c5922863e44ffc00c5c693190648daa6d15e7c1207ed02d6f46a8dcc2869d32",
"sha256:92c85ac42f41ffdc35b6da57ed991575bdbe69db895507af88b9f499b701c188",
"sha256:b24086f2375c4a094a6b51e78b4cf7ca16c721dcee2eddd7aa6494b42d6d519d",
"sha256:cb925555f43060a1745d0a321cca94bcea927c50114b623d73179189a4e100ac"
],
"markers": "python_version < '3.5'",
"version": "==1.10.0"
},
"six": {
"hashes": [
"sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c",
"sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73"
],
"version": "==1.12.0"
},
"snowballstemmer": {
"hashes": [
"sha256:919f26a68b2c17a7634da993d91339e288964f93c274f1343e3bbbe2096e1128",
"sha256:9f3bcd3c401c3e862ec0ebe6d2c069ebc012ce142cce209c098ccb5b09136e89"
],
"version": "==1.2.1"
},
"sphinx": {
"hashes": [
"sha256:11f271e7a9398385ed730e90f0bb41dc3815294bdcd395b46ed2d033bc2e7d87",
"sha256:4064ea6c56feeb268838cb8fbbee507d0c3d5d92fa63a7df935a916b52c9e2f5"
],
"index": "pypi",
"version": "==1.5.5"
},
"toml": {
"hashes": [
"sha256:229f81c57791a41d65e399fc06bf0848bab550a9dfd5ed66df18ce5f05e73d5c",
"sha256:235682dd292d5899d361a811df37e04a8828a5b1da3115886b73cf81ebc9100e",
"sha256:f1db651f9657708513243e61e6cc67d101a39bad662eaa9b5546f789338e07a3"
],
"version": "==0.10.0"
},
"tox": {
"hashes": [
"sha256:2a8d8a63660563e41e64e3b5b677e81ce1ffa5e2a93c2c565d3768c287445800",
"sha256:edfca7809925f49bdc110d0a2d9966bbf35a0c25637216d9586e7a5c5de17bfb"
],
"index": "pypi",
"version": "==3.6.1"
},
"typing": {
"hashes": [
"sha256:4027c5f6127a6267a435201981ba156de91ad0d1d98e9ddc2aa173453453492d",
"sha256:57dcf675a99b74d64dacf6fba08fb17cf7e3d5fdff53d4a30ea2a5e7e52543d4",
"sha256:a4c8473ce11a65999c8f59cb093e70686b6c84c98df58c1dae9b3b196089858a"
],
"markers": "python_version < '3.5'",
"version": "==3.6.6"
},
"urllib3": {
"hashes": [
"sha256:a53063d8b9210a7bdec15e7b272776b9d42b2fd6816401a0d43006ad2f9902db",
"sha256:d363e3607d8de0c220d31950a8f38b18d5ba7c0830facd71a1c6b1036b7ce06c"
],
"version": "==1.25.2"
},
"virtualenv": {
"hashes": [
"sha256:99acaf1e35c7ccf9763db9ba2accbca2f4254d61d1912c5ee364f9cc4a8942a0",
"sha256:fe51cdbf04e5d8152af06c075404745a7419de27495a83f0d72518ad50be3ce8"
],
"version": "==16.6.0"
},
"webencodings": {
"hashes": [
"sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78",
"sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"
],
"version": "==0.5.1"
},
"werkzeug": {
"hashes": [
"sha256:865856ebb55c4dcd0630cdd8f3331a1847a819dda7e8c750d3db6f2aa6c0209c",
"sha256:a0b915f0815982fb2a09161cb8f31708052d0951c3ba433ccc5e1aa276507ca6"
],
"version": "==0.15.4"
}
}
}

135
README.md
View File

@@ -1,23 +1,10 @@
Requests: HTTP for Humans™
==========================
# Requests
[![image](https://img.shields.io/pypi/v/requests.svg)](https://pypi.org/project/requests/)
[![image](https://img.shields.io/pypi/l/requests.svg)](https://pypi.org/project/requests/)
[![image](https://img.shields.io/pypi/pyversions/requests.svg)](https://pypi.org/project/requests/)
[![codecov.io](https://codecov.io/github/requests/requests/coverage.svg?branch=master)](https://codecov.io/github/requests/requests)
[![image](https://img.shields.io/github/contributors/requests/requests.svg)](https://github.com/requests/requests/graphs/contributors)
[![image](https://img.shields.io/badge/Say%20Thanks-!-1EAEDB.svg)](https://saythanks.io/to/kennethreitz)
**Requests** is a simple, yet elegant, HTTP library.
Requests is the only *Non-GMO* HTTP library for Python, safe for human
consumption.
![image](https://farm5.staticflickr.com/4317/35198386374_1939af3de6_k_d.jpg)
Behold, the power of Requests:
``` {.sourceCode .python}
```python
>>> import requests
>>> r = requests.get('https://api.github.com/user', auth=('user', 'pass'))
>>> r = requests.get('https://httpbin.org/basic-auth/user/pass', auth=('user', 'pass'))
>>> r.status_code
200
>>> r.headers['content-type']
@@ -25,83 +12,67 @@ Behold, the power of Requests:
>>> r.encoding
'utf-8'
>>> r.text
u'{"type":"User"...'
'{"authenticated": true, ...'
>>> r.json()
{u'disk_usage': 368627, u'private_gists': 484, ...}
{'authenticated': True, ...}
```
See [the similar code, sans Requests](https://gist.github.com/973705).
Requests allows you to send HTTP/1.1 requests extremely easily. Theres 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!
[![image](https://raw.githubusercontent.com/requests/requests/master/docs/_static/requests-logo-small.png)](http://docs.python-requests.org/)
Requests is one of the most downloaded Python packages today, pulling in around `30M downloads / week`— according to GitHub, Requests is currently [depended upon](https://github.com/psf/requests/network/dependents?package_id=UGFja2FnZS01NzA4OTExNg%3D%3D) by `1,000,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).
[![Downloads](https://static.pepy.tech/badge/requests/month)](https://pepy.tech/project/requests)
[![Supported Versions](https://img.shields.io/pypi/pyversions/requests.svg)](https://pypi.org/project/requests)
[![Contributors](https://img.shields.io/github/contributors/psf/requests.svg)](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.43.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 3.9+.
Documentation
-------------
## Supported Features & BestPractices
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 HTTPspeaking 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. Become more familiar with the project by reading our [Contributor's Guide](http://docs.python-requests.org/en/latest/dev/contributing/) and our [development philosophy](http://docs.python-requests.org/en/latest/dev/philosophy/).
2. 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.
3. Fork [the repository](https://github.com/requests/requests) on
GitHub to start making your changes to the **master** branch (or
branch off of it).
4. Write a test which shows that the bug was fixed or that the feature
works as expected.
5. 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)
[![Read the Docs](https://raw.githubusercontent.com/psf/requests/main/ext/ss.png)](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 timestamp (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
```
---
[![Kenneth Reitz](https://raw.githubusercontent.com/psf/requests/main/ext/kr.png)](https://kennethreitz.org) [![Python Software Foundation](https://raw.githubusercontent.com/psf/requests/main/ext/psf.png)](https://www.python.org/psf)

View File

@@ -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

View File

@@ -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
View File

@@ -0,0 +1 @@

View File

@@ -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
View File

@@ -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
View File

@@ -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'
}
})
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 155 KiB

View File

@@ -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>

View File

@@ -1,131 +1,37 @@
<p class="logo">
<a href="{{ pathto(master_doc) }}">
<img class="logo" src="{{ pathto('_static/requests-sidebar.png', 1) }}" title="https://kennethreitz.org/tattoos"/>
<img class="logo" src="{{ pathto('_static/requests-sidebar.png', 1) }}" alt="Requests logo" />
</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="http://open-dsm-5.org/">Open DSM-5M</a></li>
<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>
<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="{{ pathto('user/quickstart') }}">Quickstart</a></li>
<li><a href="{{ pathto('user/advanced') }}">Advanced Usage</a></li>
<li><a href="{{ pathto('api') }}">API Reference</a></li>
<li><a href="{{ pathto('community/updates') + '#release-history' }}">Release History</a></li>
<li><a href="{{ pathto('dev/contributing') }}">Contributors Guide</a></li>
<p></p>
<li><a href="https://github.com/requests/requests">Requests @ GitHub</a></li>
<li><a href="{{ pathto('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>
</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>

View File

@@ -1,33 +1,7 @@
<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
@@ -35,50 +9,22 @@
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>
<h3>Stay Informed</h3>
<p>Receive updates on new releases and upcoming projects.</p>
<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="http://open-dsm-5.org/">Open DSM-5M</a></li>
<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="{{ pathto('user/quickstart') }}">Quickstart</a></li>
<li><a href="{{ pathto('user/advanced') }}">Advanced Usage</a></li>
<li><a href="{{ pathto('api') }}">API Reference</a></li>
<li><a href="{{ pathto('community/updates') + '#release-history' }}">Release History</a></li>
<li><a href="{{ pathto('dev/contributing') }}">Contributors Guide</a></li>
<p></p>
<li><a href="{{ pathto('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>
<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>

View File

@@ -31,11 +31,11 @@ Exceptions
.. autoexception:: requests.RequestException
.. autoexception:: requests.ConnectionError
.. autoexception:: requests.HTTPError
.. autoexception:: requests.URLRequired
.. autoexception:: requests.TooManyRedirects
.. autoexception:: requests.ConnectTimeout
.. autoexception:: requests.ReadTimeout
.. autoexception:: requests.Timeout
.. autoexception:: requests.JSONDecodeError
Request Sessions
@@ -127,7 +127,7 @@ API Changes
::
import requests
r = requests.get('https://github.com/timeline.json')
r = requests.get('https://api.github.com/events')
r.json() # This *call* raises an exception if JSON decoding fails
* The ``Session`` API has changed. Sessions objects no longer take parameters.
@@ -156,7 +156,7 @@ API Changes
::
# in 0.x, passing prefetch=False would accomplish the same thing
r = requests.get('https://github.com/timeline.json', stream=True)
r = requests.get('https://api.github.com/events', stream=True)
for chunk in r.iter_content(8192):
...

View File

@@ -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 :ref:`documentation about headers <custom-headers>`.
Why not Httplib2?
@@ -53,15 +55,18 @@ Chris Adams gave an excellent summary on
Python 3 Support?
-----------------
Yes! Here's a list of Python platforms that are officially
supported:
Yes! Requests supports all `officially supported versions of Python <https://devguide.python.org/versions/>`_
and recent releases of PyPy.
* Python 2.7
* Python 3.4
* Python 3.5
* Python 3.6
* Python 3.7
* PyPy
Python 2 Support?
-----------------
No! As of Requests 2.28.0, Requests no longer supports Python 2.7. Users who
have been unable to migrate should pin to `requests<2.28`. Full information
can be found in `psf/requests#6023 <https://github.com/psf/requests/issues/6023>`_.
It is *highly* recommended users migrate to a supported Python 3.x version now 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?
-----------------------------------------
@@ -79,10 +84,7 @@ when servers are using `Virtual Hosting`_. When such servers are hosting
more than one SSL site they need to be able to return the appropriate
certificate based on the hostname the client is connecting to.
Python3 and Python 2.7.9+ include native support for SNI in their SSL modules.
For information on using SNI with Requests on Python < 2.7.9 refer to this
`Stack Overflow answer`_.
Python 3 already includes native support for SNI in their SSL modules.
.. _`Server-Name-Indication`: https://en.wikipedia.org/wiki/Server_Name_Indication
.. _`virtual hosting`: https://en.wikipedia.org/wiki/Virtual_hosting
.. _`Stack Overflow answer`: https://stackoverflow.com/questions/18578439/using-requests-with-tls-doesnt-give-sni-support/18579484#18579484

View File

@@ -1,24 +1,10 @@
Integrations
============
.. image:: https://farm5.staticflickr.com/4239/34450900674_15863ddea0_k_d.jpg
Python for iOS
--------------
Requests is built into the wonderful `Python for iOS <https://itunes.apple.com/us/app/python-2.7-for-ios/id485729872?mt=Python8>`_ runtime!
To give it a try, simply::
import requests
Articles & Talks
================
- `Python for the Web <https://www.gun.io/blog/python-for-the-web>`_ teaches how to use Python to interact with the web, using Requests.
- `Daniel Greenfeld's Review of Requests <https://pydanny.blogspot.com/2011/05/python-http-requests-for-humans.html>`_
- `My 'Python for Humans' talk <http://python-for-humans.heroku.com>`_ ( `audio <https://codeconf.s3.amazonaws.com/2011/pycodeconf/talks/PyCodeConf2011%20-%20Kenneth%20Reitz.m4a>`_ )
- `Issac Kelly's 'Consuming Web APIs' talk <https://issackelly.github.com/Consuming-Web-APIs-with-Python-Talk/slides/slides.html>`_
- `Issac Kelly's 'Consuming Web APIs' talk <https://issackelly.github.io/Consuming-Web-APIs-with-Python-Talk/slides/slides.html>`_
- `Blog post about Requests via Yum <https://arunsag.wordpress.com/2011/08/17/new-package-python-requests-http-for-humans/>`_
- `Russian blog post introducing Requests <https://habr.com/post/126262/>`_
- `Sending JSON in Requests <http://www.coglib.com/~icordasc/blog/2014/11/sending-json-in-requests.html>`_

View File

@@ -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

View File

@@ -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

View File

@@ -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 heavilyutilized Python packages in the world.
It is used by major corporations worldwide for all tasks, both small and large — from writing oneoff 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, fulltime), 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 youre 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 patronlevel 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 easytouse APIs, and empowering developers world-over to help humans communicate in meaningful and effective 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 timetotime, 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.
✨🍰✨

View File

@@ -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>`_.

View File

@@ -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

View File

@@ -1,110 +1,5 @@
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.**
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)
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.
Previous CVEs
-------------
- Fixed in 2.20.0
- `CVE 2018-18074 <https://cve.mitre.org/cgi-bin/cvename.cgi?name=2018-18074>`_
- Fixed in 2.6.0
- `CVE 2015-2296 <https://cve.mitre.org/cgi-bin/cvename.cgi?name=2015-2296>`_,
reported by Matthew Daley of `BugFuzz <https://bugfuzz.com/>`_.
- Fixed in 2.3.0
- `CVE 2014-1829 <https://cve.mitre.org/cgi-bin/cvename.cgi?name=2014-1829>`_
- `CVE 2014-1830 <https://cve.mitre.org/cgi-bin/cvename.cgi?name=2014-1830>`_
The latest vulnerability disclosure information can be found on GitHub in our
`Security Policy <https://github.com/psf/requests/blob/main/.github/SECURITY.md>`_.

View File

@@ -58,7 +58,7 @@ master_doc = "index"
# General information about the project.
project = u"Requests"
copyright = u'MMXVIX. A <a href="http://kennethreitz.com/pages/open-projects.html">Kenneth Reitz</a> Project'
copyright = u'MMXVIX. A Kenneth Reitz Project'
author = u"Kenneth Reitz"
# The version info for the project you're documenting, acts as replacement for

View File

@@ -1,6 +1,4 @@
Authors
=======
.. image:: https://static1.squarespace.com/static/533ad9bde4b098d084a846b1/t/534f6e1ce4b09b70f38ee6c1/1432265542589/DSCF3147.jpg?format=2500w
.. include:: ../../AUTHORS.rst

View File

@@ -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,36 +11,28 @@ 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
Code of Conduct
---------------
Be Cordial
----------
The Python community is made up of members from around the globe with a diverse
set of skills, personalities, and experiences. It is through these differences
that our community experiences great successes and continued growth. When you're
working with members of the community, follow the
`Python Software Foundation Code of Conduct`_ to help steer your interactions
and keep Python a positive, successful, and growing community.
**Be cordial or be on your way**. *—Kenneth Reitz*
Requests has one very important rule governing all forms of contribution,
including reporting bugs or requesting features. This golden rule is
"`be cordial or be on your way`_".
**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
.. _Python Software Foundation Code of Conduct: https://policies.python.org/python.org/code-of-conduct/
.. _early-feedback:
@@ -86,7 +76,7 @@ When contributing code, you'll want to follow this checklist:
4. Make your change.
5. Run the entire test suite again, confirming that all tests pass *including
the ones you just added*.
6. Send a GitHub Pull Request to the main repository's ``master`` branch.
6. Send a GitHub Pull Request to the main repository's ``main`` branch.
GitHub Pull Requests are the expected method of code collaboration on this
project.
@@ -101,6 +91,21 @@ event that you object to the code review feedback, you should make your case
clearly and calmly. If, after doing so, the feedback is judged to still apply,
you must either apply the feedback or withdraw your contribution.
Code Style
~~~~~~~~~~
Requests uses a collection of tools to ensure the code base has a consistent
style as it grows. We have these orchestrated using a tool called
`pre-commit`_. This can be installed locally and run over your changes prior
to opening a PR, and will also be run as part of the CI approval process
before a change is merged.
You can find the full list of formatting requirements specified in the
`.pre-commit-config.yaml`_ at the top level directory of Requests.
.. _pre-commit: https://pre-commit.com/
.. _.pre-commit-config.yaml: https://github.com/psf/requests/blob/main/.pre-commit-config.yaml
New Contributors
~~~~~~~~~~~~~~~~
@@ -111,55 +116,6 @@ asking for help.
Please also check the :ref:`early-feedback` section.
Kenneth Reitz's Code Style™
~~~~~~~~~~~~~~~~~~~~~~~~~~~
The Requests codebase uses the `PEP 8`_ code style.
In addition to the standards outlined in PEP 8, we have a few guidelines:
- Line-length can exceed 79 characters, to 100, when convenient.
- Line-length can exceed 100 characters, when doing otherwise would be *terribly* inconvenient.
- Always use single-quoted strings (e.g. ``'#flatearth'``), unless a single-quote occurs within the string.
Additionally, one of the styles that PEP8 recommends for `line continuations`_
completely lacks all sense of taste, and is not to be permitted within
the Requests codebase::
# Aligned with opening delimiter.
foo = long_function_name(var_one, var_two,
var_three, var_four)
No. Just don't. Please.
Docstrings are to follow the following syntaxes::
def the_earth_is_flat():
"""NASA divided up the seas into thirty-three degrees."""
pass
::
def fibonacci_spiral_tool():
"""With my feet upon the ground I lose myself / between the sounds
and open wide to suck it in. / I feel it move across my skin. / I'm
reaching up and reaching out. / I'm reaching for the random or
whatever will bewilder me. / Whatever will bewilder me. / And
following our will and wind we may just go where no one's been. /
We'll ride the spiral to the end and may just go where no one's
been.
Spiral out. Keep going...
"""
pass
All functions, methods, and classes are to contain docstrings. Object data
model methods (e.g. ``__repr__``) are typically the exception to this rule.
Thanks for helping to make the world a better place!
.. _PEP 8: https://pep8.org/
.. _line continuations: https://www.python.org/dev/peps/pep-0008/#indentation
Documentation Contributions
---------------------------
@@ -190,7 +146,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

View File

@@ -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.

View File

@@ -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/

View File

@@ -8,27 +8,24 @@ Requests: HTTP for Humans™
Release v\ |version|. (:ref:`Installation <install>`)
.. image:: https://static.pepy.tech/badge/requests/month
:target: https://pepy.tech/project/requests
:alt: Requests Downloads Per Month Badge
.. image:: https://img.shields.io/pypi/l/requests.svg
:target: https://pypi.org/project/requests/
:alt: License Badge
.. image:: https://img.shields.io/pypi/wheel/requests.svg
:target: https://pypi.org/project/requests/
:alt: Wheel Support Badge
.. image:: https://img.shields.io/pypi/pyversions/requests.svg
:target: https://pypi.org/project/requests/
:alt: Python Version Support Badge
.. 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:: **Requests 2.x** is officially in *maintenance-mode only*. This means we only respond to CVE-level tickets. All of our limited available attention / energy is being allocated towards the development of `Requests III <https://3.python-requests.org/>`_. Technical contributions are welcome!
**Requests** is an elegant and simple HTTP library for Python, built for human beings.
-------------------
@@ -42,48 +39,17 @@ consumption.
>>> 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
----------------
@@ -106,7 +72,7 @@ Requests is ready for today's web.
- Chunked Requests
- ``.netrc`` Support
Requests officially supports Python 2.7 & 3.43.7, and runs great on PyPy.
Requests officially supports Python 3.9+, and runs great on PyPy.
The User Guide
@@ -119,7 +85,6 @@ instructions for getting the most out of Requests.
.. toctree::
:maxdepth: 2
user/intro
user/install
user/quickstart
user/advanced
@@ -135,15 +100,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
-----------------------------
@@ -166,8 +134,6 @@ you.
:maxdepth: 3
dev/contributing
dev/philosophy
dev/todo
dev/authors
There are no more guides. You are now guideless.

3
docs/requirements.txt Normal file
View File

@@ -0,0 +1,3 @@
# Pinning to avoid unexpected breakages.
# Used by RTD to generate docs.
Sphinx==7.2.6

View File

@@ -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
@@ -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
@@ -286,7 +291,7 @@ versions of Requests.
For the sake of security we recommend upgrading certifi frequently!
.. _HTTP persistent connection: https://en.wikipedia.org/wiki/HTTP_persistent_connection
.. _connection pooling: https://urllib3.readthedocs.io/en/latest/reference/index.html#module-urllib3.connectionpool
.. _connection pooling: https://urllib3.readthedocs.io/en/latest/reference/urllib3.connectionpool.html
.. _certifi: https://certifiio.readthedocs.io/
.. _Mozilla trust store: https://hg.mozilla.org/mozilla-central/raw-file/tip/security/nss/lib/ckfw/builtins/certdata.txt
@@ -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/main'
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
{
@@ -441,7 +446,7 @@ argument.
def print_url(r, *args, **kwargs):
print(r.url)
If an error occurs while executing your callback, a warning is given.
Your callback function must handle its own exceptions. Any unhandled exception won't be passed silently and thus should be handled by the code calling Requests.
If the callback function returns a value, it is assumed that it is to
replace the data that was passed in. If the function doesn't return
@@ -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,21 +589,55 @@ 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')
.. warning:: Setting ``session.proxies`` may behave differently than expected.
Values provided will be overwritten by environmental proxies
(those returned by `urllib.request.getproxies <https://docs.python.org/3/library/urllib.request.html#urllib.request.getproxies>`_).
To ensure the use of proxies in the presence of environmental proxies,
explicitly specify the ``proxies`` argument on all individual requests as
initially explained above.
See `#2018 <https://github.com/psf/requests/issues/2018>`_ for details.
When the proxies configuration is not overridden per request as shown above,
Requests relies on the proxy configuration defined by standard
environment variables ``http_proxy``, ``https_proxy``, ``no_proxy``,
and ``all_proxy``. 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"
$ export ALL_PROXY="socks5://10.10.1.10:3434"
$ python
>>> 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 +649,25 @@ 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 ``REQUESTS_CA_BUNDLE``
(or ``CURL_CA_BUNDLE``) environment variable to another file path::
$ export REQUESTS_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:
SOCKS
^^^^^
@@ -623,7 +681,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 +709,21 @@ 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 ``requests`` without specifying ``[use_chardet_on_py3]`` extra,
and ``chardet`` is not already installed, ``requests`` uses ``charset-normalizer``
(MIT-licensed) to guess the encoding.
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 +749,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 +767,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 +804,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 +842,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 +852,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 +872,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 +886,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
@@ -879,7 +948,7 @@ Link Headers
Many HTTP APIs feature Link headers. They make APIs more self describing and
discoverable.
GitHub uses these for `pagination <https://developer.github.com/v3/#pagination>`_
GitHub uses these for `pagination <https://docs.github.com/en/rest/guides/using-pagination-in-the-rest-api>`_
in their API, for example::
>>> url = 'https://api.github.com/users/kennethreitz/repos?page=1&per_page=10'
@@ -900,11 +969,9 @@ Requests will automatically parse these link headers and make them easily consum
Transport Adapters
------------------
As of v1.0.0, Requests has moved to a modular internal design. Part of the
reason this was done was to implement Transport Adapters, originally
`described here`_. Transport Adapters provide a mechanism to define interaction
methods for an HTTP service. In particular, they allow you to apply per-service
configuration.
As of v1.0.0, Requests has moved to a modular internal design using Transport
Adapters. These objects provide a mechanism to define interaction methods for an
HTTP service. In particular, they allow you to apply per-service configuration.
Requests ships with a single Transport Adapter, the :class:`HTTPAdapter
<requests.adapters.HTTPAdapter>`. This adapter provides the default Requests
@@ -927,6 +994,10 @@ The mount call registers a specific instance of a Transport Adapter to a
prefix. Once mounted, any HTTP request made using that session whose URL starts
with the given prefix will use the given Transport Adapter.
.. note:: The adapter will be chosen based on a longest prefix match. Be mindful
prefixes such as ``http://localhost`` will also match ``http://localhost.other.com``
or ``http://localhost@other.com``. It's recommended to terminate full hostnames with a ``/``.
Many of the details of implementing a Transport Adapter are beyond the scope of
this documentation, but take a look at the next example for a simple SSL use-
case. For more than that, you might look at subclassing the
@@ -959,8 +1030,29 @@ library to use SSLv3::
num_pools=connections, maxsize=maxsize,
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
Example: Automatic Retries
^^^^^^^^^^^^^^^^^^^^^^^^^^
By default, Requests does not retry failed connections. However, it is possible
to implement automatic retries with a powerful array of features, including
backoff, within a Requests :class:`Session <requests.Session>` using the
`urllib3.util.Retry`_ class::
from urllib3.util import Retry
from requests import Session
from requests.adapters import HTTPAdapter
s = Session()
retries = Retry(
total=3,
backoff_factor=0.1,
status_forcelist=[502, 503, 504],
allowed_methods={'POST'},
)
s.mount('https://', HTTPAdapter(max_retries=retries))
.. _`urllib3`: https://github.com/urllib3/urllib3
.. _`urllib3.util.Retry`: https://urllib3.readthedocs.io/en/stable/reference/urllib3.util.html#urllib3.util.Retry
.. _blocking-or-nonblocking:
@@ -976,19 +1068,19 @@ 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`_, `requests-futures`_, and `requests-async`_.
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
.. _`requests-async`: https://github.com/encode/requests-async
.. _`httpx`: https://github.com/encode/httpx
Header Ordering
---------------
In unusual circumstances you may want to provide headers in an ordered manner. If you pass an ``OrderedDict`` to the ``headers`` keyword argument, that will provide the headers with an ordering. *However*, the ordering of the default headers used by Requests will be preferred, which means that if you override default headers in the ``headers`` keyword argument, they may appear out of order compared to other headers in that keyword argument.
If this is problematic, users should consider setting the default headers on a :class:`Session <requests.Session>` object, by setting :attr:`Session <requests.Session.headers>` to a custom ``OrderedDict``. That ordering will always be preferred.
If this is problematic, users should consider setting the default headers on a :class:`Session <requests.Session>` object, by setting :attr:`Session.headers <requests.Session.headers>` to a custom ``OrderedDict``. That ordering will always be preferred.
.. _timeouts:
@@ -1004,7 +1096,7 @@ The **connect** timeout is the number of seconds Requests will wait for your
client to establish a connection to a remote machine (corresponding to the
`connect()`_) call on the socket. It's a good practice to set connect timeouts
to slightly larger than a multiple of 3, which is the default `TCP packet
retransmission window <https://www.hjp.at/doc/rfc/rfc2988.txt>`_.
retransmission window <https://datatracker.ietf.org/doc/html/rfc2988>`_.
Once your client has connected to the server and sent the HTTP request, the
**read** timeout is the number of seconds the client will wait for the server
@@ -1029,4 +1121,18 @@ coffee.
r = requests.get('https://github.com', timeout=None)
.. note:: The connect timeout applies to each connection attempt to an IP address.
If multiple addresses exist for a domain name, the underlying ``urllib3`` will
try each address sequentially until one successfully connects.
This may lead to an effective total connection timeout *multiple* times longer
than the specified time, e.g. an unresponsive server having both IPv4 and IPv6
addresses will have its perceived timeout *doubled*, so take that into account
when setting the connection timeout.
.. note:: Neither the connect nor read timeouts are `wall clock`_. This means
that if you start a request, and look at the time, and then look at
the time when the request finishes or times out, the real-world time
may be greater than what you specified.
.. _`wall clock`: https://wiki.php.net/rfc/max_execution_wall_time
.. _`connect()`: https://linux.die.net/man/2/connect

View File

@@ -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.
@@ -21,13 +19,14 @@ the simplest kind, and Requests supports it straight out of the box.
Making requests with HTTP Basic Auth is very simple::
>>> from requests.auth import HTTPBasicAuth
>>> requests.get('https://api.github.com/user', auth=HTTPBasicAuth('user', 'pass'))
>>> basic = HTTPBasicAuth('user', 'pass')
>>> requests.get('https://httpbin.org/basic-auth/user/pass', auth=basic)
<Response [200]>
In fact, HTTP Basic Auth is so common that Requests provides a handy shorthand
for using it::
>>> requests.get('https://api.github.com/user', auth=('user', 'pass'))
>>> requests.get('https://httpbin.org/basic-auth/user/pass', auth=('user', 'pass'))
<Response [200]>
Providing the credentials in a tuple like this is exactly the same as the
@@ -45,6 +44,16 @@ set with `headers=`.
If credentials for the hostname are found, the request is sent with HTTP Basic
Auth.
Requests will search for the netrc file at `~/.netrc`, `~/_netrc`, or at the path
specified by the `NETRC` environment variable. `~` denotes the user's home
directory, which is `$HOME` on Unix based systems and `%USERPROFILE%` on Windows.
Usage of netrc file can be disabled by setting `trust_env` to `False` in the
Requests session::
>>> s = requests.Session()
>>> s.trust_env = False
>>> s.get('https://httpbin.org/basic-auth/user/pass')
Digest Authentication
---------------------

View File

@@ -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 https://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/main>`_::
$ curl -OL https://github.com/requests/requests/tarball/master
$ curl -OL https://github.com/psf/requests/tarball/main
# 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 .

View File

@@ -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

View File

@@ -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
@@ -39,12 +37,12 @@ get all the information we need from this object.
Requests' simple API means that all forms of HTTP request are as obvious. For
example, this is how you make an HTTP POST request::
>>> r = requests.post('https://httpbin.org/post', data = {'key':'value'})
>>> r = requests.post('https://httpbin.org/post', data={'key': 'value'})
Nice, right? What about the other HTTP request types: PUT, DELETE, HEAD and
OPTIONS? These are all just as simple::
>>> r = requests.put('https://httpbin.org/put', data = {'key':'value'})
>>> r = requests.put('https://httpbin.org/put', data={'key': 'value'})
>>> r = requests.delete('https://httpbin.org/delete')
>>> r = requests.head('https://httpbin.org/get')
>>> r = requests.options('https://httpbin.org/get')
@@ -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/brotlicffi>`_ 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 ``requests.exceptions.JSONDecodeError``. This wrapper exception
provides interoperability for multiple exceptions that may be thrown by different
python versions and json serialization libraries.
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
@@ -174,7 +177,7 @@ server, you can access ``r.raw``. If you want to do this, make sure you set
<urllib3.response.HTTPResponse object at 0x101194810>
>>> r.raw.read(10)
'\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03'
b'\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03'
In general, however, you should use a pattern like this to save what is being
streamed to a file::
@@ -198,6 +201,8 @@ may better fit your use cases.
were returned, use ``Response.raw``.
.. _custom-headers:
Custom Headers
--------------
@@ -215,7 +220,9 @@ 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.
Check details in :ref:`netrc authentication <authentication>`.
* 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.
@@ -233,7 +240,7 @@ dictionary of data will automatically be form-encoded when the request is made::
>>> payload = {'key1': 'value1', 'key2': 'value2'}
>>> r = requests.post("https://httpbin.org/post", data=payload)
>>> r = requests.post('https://httpbin.org/post', data=payload)
>>> print(r.text)
{
...
@@ -279,8 +286,12 @@ For example, the GitHub API v3 accepts JSON-Encoded POST/PATCH data::
>>> r = requests.post(url, data=json.dumps(payload))
Instead of encoding the ``dict`` yourself, you can also pass it directly using
the ``json`` parameter (added in version 2.4.2) and it will be encoded automatically::
Please note that the above code will NOT add the ``Content-Type`` header
(so in particular it will NOT set it to ``application/json``).
If you need that header set and you don't want to encode the ``dict`` yourself,
you can also pass it directly using the ``json`` parameter (added in version 2.4.2)
and it will be encoded automatically:
>>> url = 'https://api.github.com/some/endpoint'
>>> payload = {'some': 'data'}
@@ -289,8 +300,6 @@ the ``json`` parameter (added in version 2.4.2) and it will be encoded automatic
Note, the ``json`` parameter is ignored if either ``data`` or ``files`` is passed.
Using the ``json`` parameter in the request will change the ``Content-Type`` in the header to ``application/json``.
POST a Multipart-Encoded File
-----------------------------
@@ -560,6 +569,3 @@ 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
View File

@@ -0,0 +1 @@
Copyright 2019 Kenneth Reitz. All rights reserved.

BIN
ext/flower-of-life.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
ext/kr-compressed.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

BIN
ext/kr.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

BIN
ext/psf-compressed.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
ext/psf.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

BIN
ext/requests-logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

BIN
ext/ss-compressed.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 363 KiB

BIN
ext/ss.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 363 KiB

10
pyproject.toml Normal file
View File

@@ -0,0 +1,10 @@
[tool.isort]
profile = "black"
src_paths = ["src/requests", "test"]
honor_noqa = true
[tool.pytest.ini_options]
addopts = "--doctest-modules"
doctest_optionflags = "NORMALIZE_WHITESPACE ELLIPSIS"
minversion = "6.2"
testpaths = ["tests"]

View File

@@ -1,2 +0,0 @@
[pytest]
addopts = -p no:warnings

View File

@@ -1,131 +0,0 @@
# -*- coding: utf-8 -*-
# __
# /__) _ _ _ _ _/ _
# / ( (- (/ (/ (- _) / _)
# /
"""
Requests HTTP Library
~~~~~~~~~~~~~~~~~~~~~
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
True
... or POST:
>>> payload = dict(key1='value1', key2='value2')
>>> r = requests.post('https://httpbin.org/post', data=payload)
>>> print(r.text)
{
...
"form": {
"key2": "value2",
"key1": "value1"
},
...
}
The other HTTP methods are supported - see `requests.api`. Full documentation
is at <http://python-requests.org>.
: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
def check_compatibility(urllib3_version, chardet_version):
urllib3_version = urllib3_version.split('.')
assert urllib3_version != ['dev'] # Verify urllib3 isn't installed from git.
# Sometimes, urllib3 only reports its version as 16.1.
if len(urllib3_version) == 2:
urllib3_version.append('0')
# Check urllib3 for compatibility.
major, minor, patch = urllib3_version # noqa: F811
major, minor, patch = int(major), int(minor), int(patch)
# urllib3 >= 1.21.1, <= 1.25
assert major == 1
assert minor >= 21
assert minor <= 25
# 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
def _check_cryptography(cryptography_version):
# cryptography < 1.3.4
try:
cryptography_version = list(map(int, cryptography_version.split('.')))
except ValueError:
return
if cryptography_version < [1, 3, 4]:
warning = 'Old version of cryptography ({}) may cause slowdown.'.format(cryptography_version)
warnings.warn(warning, RequestsDependencyWarning)
# Check imported dependencies for compatibility.
try:
check_compatibility(urllib3.__version__, chardet.__version__)
except (AssertionError, ValueError):
warnings.warn("urllib3 ({}) or chardet ({}) doesn't match a supported "
"version!".format(urllib3.__version__, chardet.__version__),
RequestsDependencyWarning)
# Attempt to enable urllib3's SNI support, if possible
try:
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
# urllib3's DependencyWarnings should be silenced.
from urllib3.exceptions import DependencyWarning
warnings.simplefilter('ignore', DependencyWarning)
from .__version__ import __title__, __description__, __url__, __version__
from .__version__ import __build__, __author__, __author_email__, __license__
from .__version__ import __copyright__, __cake__
from . import utils
from . import packages
from .models import Request, Response, PreparedRequest
from .api import request, get, head, post, patch, put, delete, options
from .sessions import session, Session
from .status_codes import codes
from .exceptions import (
RequestException, Timeout, URLRequired,
TooManyRedirects, HTTPError, ConnectionError,
FileModeWarning, ConnectTimeout, ReadTimeout
)
# Set default logging handler to avoid "No handler found" warnings.
import logging
from logging import NullHandler
logging.getLogger(__name__).addHandler(NullHandler())
# FileModeWarnings go off per the default.
warnings.simplefilter('default', FileModeWarning, append=True)

View File

@@ -1,14 +0,0 @@
# .-. .-. .-. . . .-. .-. .-. .-.
# |( |- |.| | | |- `-. | `-.
# ' ' `-' `-`.`-' `-' `-' ' `-'
__title__ = 'requests'
__description__ = 'Python HTTP for Humans.'
__url__ = 'http://python-requests.org'
__version__ = '2.22.0'
__build__ = 0x022200
__author__ = 'Kenneth Reitz'
__author_email__ = 'me@kennethreitz.org'
__license__ = 'Apache 2.0'
__copyright__ = 'Copyright 2019 Kenneth Reitz'
__cake__ = u'\u2728 \U0001f370 \u2728'

View File

@@ -1,70 +0,0 @@
# -*- coding: utf-8 -*-
"""
requests.compat
~~~~~~~~~~~~~~~
This module handles import compatibility issues between Python 2 and
Python 3.
"""
import chardet
import sys
# -------
# Pythons
# -------
# Syntax sugar.
_ver = sys.version_info
#: Python 2.x?
is_py2 = (_ver[0] == 2)
#: Python 3.x?
is_py3 = (_ver[0] == 3)
try:
import simplejson as json
except ImportError:
import json
# ---------
# Specifics
# ---------
if is_py2:
from urllib import (
quote, unquote, quote_plus, unquote_plus, urlencode, getproxies,
proxy_bypass, proxy_bypass_environment, getproxies_environment)
from urlparse import urlparse, urlunparse, urljoin, urlsplit, urldefrag
from urllib2 import parse_http_list
import cookielib
from Cookie import Morsel
from StringIO import StringIO
from collections import Callable, Mapping, MutableMapping, OrderedDict
builtin_str = str
bytes = str
str = unicode
basestring = basestring
numeric_types = (int, long, float)
integer_types = (int, long)
elif is_py3:
from urllib.parse import urlparse, urlunparse, urljoin, urlsplit, urlencode, quote, unquote, quote_plus, unquote_plus, urldefrag
from urllib.request import parse_http_list, getproxies, proxy_bypass, proxy_bypass_environment, getproxies_environment
from http import cookiejar as cookielib
from http.cookies import Morsel
from io import StringIO
from collections import OrderedDict
from collections.abc import Callable, Mapping, MutableMapping
builtin_str = str
str = str
bytes = bytes
basestring = (str, bytes)
numeric_types = (int, float)
integer_types = (int,)

View File

@@ -1,119 +0,0 @@
"""Module containing bug report helper(s)."""
from __future__ import print_function
import json
import platform
import sys
import ssl
import idna
import urllib3
import chardet
from . import __version__ as requests_version
try:
from urllib3.contrib import pyopenssl
except ImportError:
pyopenssl = None
OpenSSL = None
cryptography = None
else:
import OpenSSL
import cryptography
def _implementation():
"""Return a dict with the Python implementation and version.
Provide both the name and the version of the Python implementation
currently running. For example, on CPython 2.7.5 it will return
{'name': 'CPython', 'version': '2.7.5'}.
This function works best on CPython and PyPy: in particular, it probably
doesn't work for Jython or IronPython. Future investigation should be done
to work out the correct shape of the code for those platforms.
"""
implementation = platform.python_implementation()
if implementation == 'CPython':
implementation_version = platform.python_version()
elif implementation == 'PyPy':
implementation_version = '%s.%s.%s' % (sys.pypy_version_info.major,
sys.pypy_version_info.minor,
sys.pypy_version_info.micro)
if sys.pypy_version_info.releaselevel != 'final':
implementation_version = ''.join([
implementation_version, sys.pypy_version_info.releaselevel
])
elif implementation == 'Jython':
implementation_version = platform.python_version() # Complete Guess
elif implementation == 'IronPython':
implementation_version = platform.python_version() # Complete Guess
else:
implementation_version = 'Unknown'
return {'name': implementation, 'version': implementation_version}
def info():
"""Generate information for a bug report."""
try:
platform_info = {
'system': platform.system(),
'release': platform.release(),
}
except IOError:
platform_info = {
'system': 'Unknown',
'release': 'Unknown',
}
implementation_info = _implementation()
urllib3_info = {'version': urllib3.__version__}
chardet_info = {'version': chardet.__version__}
pyopenssl_info = {
'version': None,
'openssl_version': '',
}
if OpenSSL:
pyopenssl_info = {
'version': OpenSSL.__version__,
'openssl_version': '%x' % OpenSSL.SSL.OPENSSL_VERSION_NUMBER,
}
cryptography_info = {
'version': getattr(cryptography, '__version__', ''),
}
idna_info = {
'version': getattr(idna, '__version__', ''),
}
system_ssl = ssl.OPENSSL_VERSION_NUMBER
system_ssl_info = {
'version': '%x' % system_ssl if system_ssl is not None else ''
}
return {
'platform': platform_info,
'implementation': implementation_info,
'system_ssl': system_ssl_info,
'using_pyopenssl': pyopenssl is not None,
'pyOpenSSL': pyopenssl_info,
'urllib3': urllib3_info,
'chardet': chardet_info,
'cryptography': cryptography_info,
'idna': idna_info,
'requests': {
'version': requests_version,
},
}
def main():
"""Pretty-print the bug information as JSON."""
print(json.dumps(info(), sort_keys=True, indent=2))
if __name__ == '__main__':
main()

View File

@@ -1,14 +0,0 @@
import sys
# This code exists for backwards compatibility reasons.
# I don't like it either. Just look the other way. :)
for package in ('urllib3', 'idna', 'chardet'):
locals()[package] = __import__(package)
# This traversal is apparently necessary such that the identities are
# preserved (requests.packages.urllib3.* is urllib3.*)
for mod in list(sys.modules):
if mod == package or mod.startswith(package + '.'):
sys.modules['requests.packages.' + mod] = sys.modules[mod]
# Kinda cool, though, right?

View File

@@ -1,120 +0,0 @@
# -*- coding: utf-8 -*-
r"""
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
Some codes have multiple names, and both upper- and lower-case versions of
the names are allowed. For example, ``codes.ok``, ``codes.OK``, and
``codes.okay`` all correspond to the HTTP status code 200.
"""
from .structures import LookupDict
_codes = {
# Informational.
100: ('continue',),
101: ('switching_protocols',),
102: ('processing',),
103: ('checkpoint',),
122: ('uri_too_long', 'request_uri_too_long'),
200: ('ok', 'okay', 'all_ok', 'all_okay', 'all_good', '\\o/', ''),
201: ('created',),
202: ('accepted',),
203: ('non_authoritative_info', 'non_authoritative_information'),
204: ('no_content',),
205: ('reset_content', 'reset'),
206: ('partial_content', 'partial'),
207: ('multi_status', 'multiple_status', 'multi_stati', 'multiple_stati'),
208: ('already_reported',),
226: ('im_used',),
# Redirection.
300: ('multiple_choices',),
301: ('moved_permanently', 'moved', '\\o-'),
302: ('found',),
303: ('see_other', 'other'),
304: ('not_modified',),
305: ('use_proxy',),
306: ('switch_proxy',),
307: ('temporary_redirect', 'temporary_moved', 'temporary'),
308: ('permanent_redirect',
'resume_incomplete', 'resume',), # These 2 to be removed in 3.0
# Client Error.
400: ('bad_request', 'bad'),
401: ('unauthorized',),
402: ('payment_required', 'payment'),
403: ('forbidden',),
404: ('not_found', '-o-'),
405: ('method_not_allowed', 'not_allowed'),
406: ('not_acceptable',),
407: ('proxy_authentication_required', 'proxy_auth', 'proxy_authentication'),
408: ('request_timeout', 'timeout'),
409: ('conflict',),
410: ('gone',),
411: ('length_required',),
412: ('precondition_failed', 'precondition'),
413: ('request_entity_too_large',),
414: ('request_uri_too_large',),
415: ('unsupported_media_type', 'unsupported_media', 'media_type'),
416: ('requested_range_not_satisfiable', 'requested_range', 'range_not_satisfiable'),
417: ('expectation_failed',),
418: ('im_a_teapot', 'teapot', 'i_am_a_teapot'),
421: ('misdirected_request',),
422: ('unprocessable_entity', 'unprocessable'),
423: ('locked',),
424: ('failed_dependency', 'dependency'),
425: ('unordered_collection', 'unordered'),
426: ('upgrade_required', 'upgrade'),
428: ('precondition_required', 'precondition'),
429: ('too_many_requests', 'too_many'),
431: ('header_fields_too_large', 'fields_too_large'),
444: ('no_response', 'none'),
449: ('retry_with', 'retry'),
450: ('blocked_by_windows_parental_controls', 'parental_controls'),
451: ('unavailable_for_legal_reasons', 'legal_reasons'),
499: ('client_closed_request',),
# Server Error.
500: ('internal_server_error', 'server_error', '/o\\', ''),
501: ('not_implemented',),
502: ('bad_gateway',),
503: ('service_unavailable', 'unavailable'),
504: ('gateway_timeout',),
505: ('http_version_not_supported', 'http_version'),
506: ('variant_also_negotiates',),
507: ('insufficient_storage',),
509: ('bandwidth_limit_exceeded', 'bandwidth'),
510: ('not_extended',),
511: ('network_authentication_required', 'network_auth', 'network_authentication'),
}
codes = LookupDict(name='status_codes')
def _init():
for code, titles in _codes.items():
for title in titles:
setattr(codes, title, code)
if not title.startswith(('\\', '/')):
setattr(codes, title.upper(), code)
def doc(code):
names = ', '.join('``%s``' % n for n in _codes[code])
return '* %d: %s' % (code, names)
global __doc__
__doc__ = (__doc__ + '\n' +
'\n'.join(doc(code) for code in sorted(_codes))
if __doc__ is not None else None)
_init()

7
requirements-dev.txt Normal file
View File

@@ -0,0 +1,7 @@
-e .[socks]
pytest>=2.8.0,<9
pytest-cov
pytest-httpbin==2.1.0
httpbin~=0.10.0
trustme
wheel

View File

@@ -1,5 +1,17 @@
[bdist_wheel]
universal = 1
[metadata]
license_file = LICENSE
provides-extra =
socks
use_chardet_on_py3
requires-dist =
certifi>=2017.4.17
charset_normalizer>=2,<4
idna>=2.5,<4
urllib3>=1.21.1,<3
[flake8]
ignore = E203, E501, W503
per-file-ignores =
src/requests/__init__.py:E402, F401
src/requests/compat.py:E402, F401
tests/compat.py:F401

145
setup.py
View File

@@ -1,108 +1,107 @@
#!/usr/bin/env python
# Learn more: https://github.com/kennethreitz/setup.py
import os
import re
import sys
from codecs import open
from setuptools import setup
from setuptools.command.test import test as TestCommand
here = os.path.abspath(os.path.dirname(__file__))
CURRENT_PYTHON = sys.version_info[:2]
REQUIRED_PYTHON = (3, 9)
class PyTest(TestCommand):
user_options = [('pytest-args=', 'a', "Arguments to pass into py.test")]
if CURRENT_PYTHON < REQUIRED_PYTHON:
sys.stderr.write(
"""
==========================
Unsupported Python version
==========================
This version of Requests requires at least Python {}.{}, but
you're trying to install it on Python {}.{}. To resolve this,
consider upgrading to a supported Python version.
def initialize_options(self):
TestCommand.initialize_options(self)
try:
from multiprocessing import cpu_count
self.pytest_args = ['-n', str(cpu_count()), '--boxed']
except (ImportError, NotImplementedError):
self.pytest_args = ['-n', '1', '--boxed']
If you can't upgrade your Python version, you'll need to
pin to an older version of Requests (<2.32.0).
""".format(
*(REQUIRED_PYTHON + CURRENT_PYTHON)
)
)
sys.exit(1)
def finalize_options(self):
TestCommand.finalize_options(self)
self.test_args = []
self.test_suite = True
def run_tests(self):
import pytest
errno = pytest.main(self.pytest_args)
sys.exit(errno)
# 'setup.py publish' shortcut.
if sys.argv[-1] == 'publish':
os.system('python setup.py sdist bdist_wheel')
os.system('twine upload dist/*')
if sys.argv[-1] == "publish":
os.system("python setup.py sdist bdist_wheel")
os.system("twine upload dist/*")
sys.exit()
packages = ['requests']
requires = [
'chardet>=3.0.2,<3.1.0',
'idna>=2.5,<2.9',
'urllib3>=1.21.1,<1.26,!=1.25.0,!=1.25.1',
'certifi>=2017.4.17'
"charset_normalizer>=2,<4",
"idna>=2.5,<4",
"urllib3>=1.21.1,<3",
"certifi>=2017.4.17",
]
test_requirements = [
'pytest-httpbin==0.0.7',
'pytest-cov',
'pytest-mock',
'pytest-xdist',
'PySocks>=1.5.6, !=1.5.7',
'pytest>=2.8.0'
"pytest-httpbin==2.1.0",
"pytest-cov",
"pytest-mock",
"pytest-xdist",
"PySocks>=1.5.6, !=1.5.7",
"pytest>=3",
]
about = {}
with open(os.path.join(here, 'requests', '__version__.py'), 'r', 'utf-8') as f:
here = os.path.abspath(os.path.dirname(__file__))
with open(os.path.join(here, "src", "requests", "__version__.py"), "r", "utf-8") as f:
exec(f.read(), about)
with open('README.md', '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__'],
version=about['__version__'],
description=about['__description__'],
name=about["__title__"],
version=about["__version__"],
description=about["__description__"],
long_description=readme,
long_description_content_type='text/markdown',
author=about['__author__'],
author_email=about['__author_email__'],
url=about['__url__'],
packages=packages,
package_data={'': ['LICENSE', 'NOTICE'], 'requests': ['*.pem']},
package_dir={'requests': 'requests'},
long_description_content_type="text/markdown",
author=about["__author__"],
author_email=about["__author_email__"],
url=about["__url__"],
packages=["requests"],
package_data={"": ["LICENSE", "NOTICE"]},
package_dir={"": "src"},
include_package_data=True,
python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*",
python_requires=">=3.9",
install_requires=requires,
license=about['__license__'],
license=about["__license__"],
zip_safe=False,
classifiers=[
'Development Status :: 5 - Production/Stable',
'Intended Audience :: Developers',
'Natural Language :: English',
'License :: OSI Approved :: Apache Software License',
'Programming Language :: Python',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: Implementation :: CPython',
'Programming Language :: Python :: Implementation :: PyPy'
"Development Status :: 5 - Production/Stable",
"Environment :: Web Environment",
"Intended Audience :: Developers",
"License :: OSI Approved :: Apache Software License",
"Natural Language :: English",
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: Implementation :: CPython",
"Programming Language :: Python :: Implementation :: PyPy",
"Topic :: Internet :: WWW/HTTP",
"Topic :: Software Development :: Libraries",
],
cmdclass={'test': PyTest},
tests_require=test_requirements,
extras_require={
'security': ['pyOpenSSL >= 0.14', 'cryptography>=1.3.4', 'idna>=2.0.0'],
'socks': ['PySocks>=1.5.6, !=1.5.7'],
'socks:sys_platform == "win32" and python_version == "2.7"': ['win_inet_pton'],
"security": [],
"socks": ["PySocks>=1.5.6, !=1.5.7"],
"use_chardet_on_py3": ["chardet>=3.0.2,<6"],
},
project_urls={
"Documentation": "https://requests.readthedocs.io",
"Source": "https://github.com/psf/requests",
},
)

184
src/requests/__init__.py Normal file
View File

@@ -0,0 +1,184 @@
# __
# /__) _ _ _ _ _/ _
# / ( (- (/ (/ (- _) / _)
# /
"""
Requests HTTP Library
~~~~~~~~~~~~~~~~~~~~~
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
>>> b'Python is a programming language' in r.content
True
... or POST:
>>> payload = dict(key1='value1', key2='value2')
>>> r = requests.post('https://httpbin.org/post', data=payload)
>>> print(r.text)
{
...
"form": {
"key1": "value1",
"key2": "value2"
},
...
}
The other HTTP methods are supported - see `requests.api`. Full documentation
is at <https://requests.readthedocs.io>.
:copyright: (c) 2017 by Kenneth Reitz.
:license: Apache 2.0, see LICENSE for more details.
"""
import warnings
import urllib3
from .exceptions import RequestsDependencyWarning
try:
from charset_normalizer import __version__ as charset_normalizer_version
except ImportError:
charset_normalizer_version = None
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.
# Sometimes, urllib3 only reports its version as 16.1.
if len(urllib3_version) == 2:
urllib3_version.append("0")
# Check urllib3 for compatibility.
major, minor, patch = urllib3_version # noqa: F811
major, minor, patch = int(major), int(minor), int(patch)
# urllib3 >= 1.21.1
assert major >= 1
if major == 1:
assert minor >= 21
# 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, < 6.0.0
assert (3, 0, 2) <= (major, minor, patch) < (6, 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 < 4.0.0
assert (2, 0, 0) <= (major, minor, patch) < (4, 0, 0)
else:
warnings.warn(
"Unable to find acceptable character detection dependency "
"(chardet or charset_normalizer).",
RequestsDependencyWarning,
)
def _check_cryptography(cryptography_version):
# cryptography < 1.3.4
try:
cryptography_version = list(map(int, cryptography_version.split(".")))
except ValueError:
return
if cryptography_version < [1, 3, 4]:
warning = "Old version of cryptography ({}) may cause slowdown.".format(
cryptography_version
)
warnings.warn(warning, RequestsDependencyWarning)
# Check imported dependencies for compatibility.
try:
check_compatibility(
urllib3.__version__, chardet_version, charset_normalizer_version
)
except (AssertionError, ValueError):
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 fallback for SNI support
# if the standard library doesn't support SNI or the
# 'ssl' library isn't available.
try:
try:
import ssl
except ImportError:
ssl = None
if not getattr(ssl, "HAS_SNI", False):
from urllib3.contrib import pyopenssl
pyopenssl.inject_into_urllib3()
# Check cryptography version
from cryptography import __version__ as cryptography_version
_check_cryptography(cryptography_version)
except ImportError:
pass
# urllib3's DependencyWarnings should be silenced.
from urllib3.exceptions import DependencyWarning
warnings.simplefilter("ignore", DependencyWarning)
# Set default logging handler to avoid "No handler found" warnings.
import logging
from logging import NullHandler
from . import packages, utils
from .__version__ import (
__author__,
__author_email__,
__build__,
__cake__,
__copyright__,
__description__,
__license__,
__title__,
__url__,
__version__,
)
from .api import delete, get, head, options, patch, post, put, request
from .exceptions import (
ConnectionError,
ConnectTimeout,
FileModeWarning,
HTTPError,
JSONDecodeError,
ReadTimeout,
RequestException,
Timeout,
TooManyRedirects,
URLRequired,
)
from .models import PreparedRequest, Request, Response
from .sessions import Session, session
from .status_codes import codes
logging.getLogger(__name__).addHandler(NullHandler())
# FileModeWarnings go off per the default.
warnings.simplefilter("default", FileModeWarning, append=True)

View File

@@ -0,0 +1,14 @@
# .-. .-. .-. . . .-. .-. .-. .-.
# |( |- |.| | | |- `-. | `-.
# ' ' `-' `-`.`-' `-' `-' ' `-'
__title__ = "requests"
__description__ = "Python HTTP for Humans."
__url__ = "https://requests.readthedocs.io"
__version__ = "2.32.5"
__build__ = 0x023205
__author__ = "Kenneth Reitz"
__author_email__ = "me@kennethreitz.org"
__license__ = "Apache-2.0"
__copyright__ = "Copyright Kenneth Reitz"
__cake__ = "\u2728 \U0001f370 \u2728"

View File

@@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
"""
requests._internal_utils
~~~~~~~~~~~~~~
@@ -7,11 +5,24 @@ requests._internal_utils
Provides utility functions that are consumed internally by Requests
which depend on extremely few external helpers (such as compat)
"""
import re
from .compat import is_py2, builtin_str, str
from .compat import builtin_str
_VALID_HEADER_NAME_RE_BYTE = re.compile(rb"^[^:\s][^:\r\n]*$")
_VALID_HEADER_NAME_RE_STR = re.compile(r"^[^:\s][^:\r\n]*$")
_VALID_HEADER_VALUE_RE_BYTE = re.compile(rb"^\S[^\r\n]*$|^$")
_VALID_HEADER_VALUE_RE_STR = re.compile(r"^\S[^\r\n]*$|^$")
_HEADER_VALIDATORS_STR = (_VALID_HEADER_NAME_RE_STR, _VALID_HEADER_VALUE_RE_STR)
_HEADER_VALIDATORS_BYTE = (_VALID_HEADER_NAME_RE_BYTE, _VALID_HEADER_VALUE_RE_BYTE)
HEADER_VALIDATORS = {
bytes: _HEADER_VALIDATORS_BYTE,
str: _HEADER_VALIDATORS_STR,
}
def to_native_string(string, encoding='ascii'):
def to_native_string(string, encoding="ascii"):
"""Given a string object, regardless of type, returns a representation of
that string in the native string type, encoding and decoding where
necessary. This assumes ASCII unless told otherwise.
@@ -19,10 +30,7 @@ def to_native_string(string, encoding='ascii'):
if isinstance(string, builtin_str):
out = string
else:
if is_py2:
out = string.encode(encoding)
else:
out = string.decode(encoding)
out = string.decode(encoding)
return out
@@ -36,7 +44,7 @@ def unicode_is_ascii(u_string):
"""
assert isinstance(u_string, str)
try:
u_string.encode('ascii')
u_string.encode("ascii")
return True
except UnicodeEncodeError:
return False

View File

@@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
"""
requests.adapters
~~~~~~~~~~~~~~~~~
@@ -9,57 +7,118 @@ and maintain connections.
"""
import os.path
import socket
import socket # noqa: F401
import typing
import warnings
from urllib3.poolmanager import PoolManager, proxy_from_url
from urllib3.response import HTTPResponse
from urllib3.util import parse_url
from urllib3.util import Timeout as TimeoutSauce
from urllib3.util.retry import Retry
from urllib3.exceptions import ClosedPoolError
from urllib3.exceptions import ConnectTimeoutError
from urllib3.exceptions import ClosedPoolError, ConnectTimeoutError
from urllib3.exceptions import HTTPError as _HTTPError
from urllib3.exceptions import MaxRetryError
from urllib3.exceptions import NewConnectionError
from urllib3.exceptions import InvalidHeader as _InvalidHeader
from urllib3.exceptions import (
LocationValueError,
MaxRetryError,
NewConnectionError,
ProtocolError,
)
from urllib3.exceptions import ProxyError as _ProxyError
from urllib3.exceptions import ProtocolError
from urllib3.exceptions import ReadTimeoutError
from urllib3.exceptions import ReadTimeoutError, ResponseError
from urllib3.exceptions import SSLError as _SSLError
from urllib3.exceptions import ResponseError
from urllib3.exceptions import LocationValueError
from urllib3.poolmanager import PoolManager, proxy_from_url
from urllib3.util import Timeout as TimeoutSauce
from urllib3.util import parse_url
from urllib3.util.retry import Retry
from .models import Response
from .compat import urlparse, basestring
from .utils import (DEFAULT_CA_BUNDLE_PATH, extract_zipped_paths,
get_encoding_from_headers, prepend_scheme_if_needed,
get_auth_from_url, urldefragauth, select_proxy)
from .structures import CaseInsensitiveDict
from .cookies import extract_cookies_to_jar
from .exceptions import (ConnectionError, ConnectTimeout, ReadTimeout, SSLError,
ProxyError, RetryError, InvalidSchema, InvalidProxyURL,
InvalidURL)
from .auth import _basic_auth_str
from .compat import basestring, urlparse
from .cookies import extract_cookies_to_jar
from .exceptions import (
ConnectionError,
ConnectTimeout,
InvalidHeader,
InvalidProxyURL,
InvalidSchema,
InvalidURL,
ProxyError,
ReadTimeout,
RetryError,
SSLError,
)
from .models import Response
from .structures import CaseInsensitiveDict
from .utils import (
DEFAULT_CA_BUNDLE_PATH,
extract_zipped_paths,
get_auth_from_url,
get_encoding_from_headers,
prepend_scheme_if_needed,
select_proxy,
urldefragauth,
)
try:
from urllib3.contrib.socks import SOCKSProxyManager
except ImportError:
def SOCKSProxyManager(*args, **kwargs):
raise InvalidSchema("Missing dependencies for SOCKS support.")
if typing.TYPE_CHECKING:
from .models import PreparedRequest
DEFAULT_POOLBLOCK = False
DEFAULT_POOLSIZE = 10
DEFAULT_RETRIES = 0
DEFAULT_POOL_TIMEOUT = None
class BaseAdapter(object):
def _urllib3_request_context(
request: "PreparedRequest",
verify: "bool | str | None",
client_cert: "typing.Tuple[str, str] | str | None",
poolmanager: "PoolManager",
) -> "(typing.Dict[str, typing.Any], typing.Dict[str, typing.Any])":
host_params = {}
pool_kwargs = {}
parsed_request_url = urlparse(request.url)
scheme = parsed_request_url.scheme.lower()
port = parsed_request_url.port
cert_reqs = "CERT_REQUIRED"
if verify is False:
cert_reqs = "CERT_NONE"
elif isinstance(verify, str):
if not os.path.isdir(verify):
pool_kwargs["ca_certs"] = verify
else:
pool_kwargs["ca_cert_dir"] = verify
pool_kwargs["cert_reqs"] = cert_reqs
if client_cert is not None:
if isinstance(client_cert, tuple) and len(client_cert) == 2:
pool_kwargs["cert_file"] = client_cert[0]
pool_kwargs["key_file"] = client_cert[1]
else:
# According to our docs, we allow users to specify just the client
# cert path
pool_kwargs["cert_file"] = client_cert
host_params = {
"scheme": scheme,
"host": parsed_request_url.hostname,
"port": port,
}
return host_params, pool_kwargs
class BaseAdapter:
"""The Base Transport Adapter"""
def __init__(self):
super(BaseAdapter, self).__init__()
super().__init__()
def send(self, request, stream=False, timeout=None, verify=True,
cert=None, proxies=None):
def send(
self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None
):
"""Sends PreparedRequest object. Returns Response object.
:param request: The :class:`PreparedRequest <PreparedRequest>` being sent.
@@ -107,12 +166,22 @@ class HTTPAdapter(BaseAdapter):
>>> a = requests.adapters.HTTPAdapter(max_retries=3)
>>> s.mount('http://', a)
"""
__attrs__ = ['max_retries', 'config', '_pool_connections', '_pool_maxsize',
'_pool_block']
def __init__(self, pool_connections=DEFAULT_POOLSIZE,
pool_maxsize=DEFAULT_POOLSIZE, max_retries=DEFAULT_RETRIES,
pool_block=DEFAULT_POOLBLOCK):
__attrs__ = [
"max_retries",
"config",
"_pool_connections",
"_pool_maxsize",
"_pool_block",
]
def __init__(
self,
pool_connections=DEFAULT_POOLSIZE,
pool_maxsize=DEFAULT_POOLSIZE,
max_retries=DEFAULT_RETRIES,
pool_block=DEFAULT_POOLBLOCK,
):
if max_retries == DEFAULT_RETRIES:
self.max_retries = Retry(0, read=False)
else:
@@ -120,7 +189,7 @@ class HTTPAdapter(BaseAdapter):
self.config = {}
self.proxy_manager = {}
super(HTTPAdapter, self).__init__()
super().__init__()
self._pool_connections = pool_connections
self._pool_maxsize = pool_maxsize
@@ -140,10 +209,13 @@ class HTTPAdapter(BaseAdapter):
for attr, value in state.items():
setattr(self, attr, value)
self.init_poolmanager(self._pool_connections, self._pool_maxsize,
block=self._pool_block)
self.init_poolmanager(
self._pool_connections, self._pool_maxsize, block=self._pool_block
)
def init_poolmanager(self, connections, maxsize, block=DEFAULT_POOLBLOCK, **pool_kwargs):
def init_poolmanager(
self, connections, maxsize, block=DEFAULT_POOLBLOCK, **pool_kwargs
):
"""Initializes a urllib3 PoolManager.
This method should not be called from user code, and is only
@@ -160,8 +232,12 @@ class HTTPAdapter(BaseAdapter):
self._pool_maxsize = maxsize
self._pool_block = block
self.poolmanager = PoolManager(num_pools=connections, maxsize=maxsize,
block=block, strict=True, **pool_kwargs)
self.poolmanager = PoolManager(
num_pools=connections,
maxsize=maxsize,
block=block,
**pool_kwargs,
)
def proxy_manager_for(self, proxy, **proxy_kwargs):
"""Return urllib3 ProxyManager for the given proxy.
@@ -177,7 +253,7 @@ class HTTPAdapter(BaseAdapter):
"""
if proxy in self.proxy_manager:
manager = self.proxy_manager[proxy]
elif proxy.lower().startswith('socks'):
elif proxy.lower().startswith("socks"):
username, password = get_auth_from_url(proxy)
manager = self.proxy_manager[proxy] = SOCKSProxyManager(
proxy,
@@ -186,7 +262,7 @@ class HTTPAdapter(BaseAdapter):
num_pools=self._pool_connections,
maxsize=self._pool_maxsize,
block=self._pool_block,
**proxy_kwargs
**proxy_kwargs,
)
else:
proxy_headers = self.proxy_headers(proxy)
@@ -196,7 +272,8 @@ class HTTPAdapter(BaseAdapter):
num_pools=self._pool_connections,
maxsize=self._pool_maxsize,
block=self._pool_block,
**proxy_kwargs)
**proxy_kwargs,
)
return manager
@@ -212,8 +289,7 @@ class HTTPAdapter(BaseAdapter):
to a CA bundle to use
:param cert: The SSL certificate to verify.
"""
if url.lower().startswith('https') and verify:
if url.lower().startswith("https") and verify:
cert_loc = None
# Allow self-specified cert location.
@@ -224,17 +300,19 @@ class HTTPAdapter(BaseAdapter):
cert_loc = extract_zipped_paths(DEFAULT_CA_BUNDLE_PATH)
if not cert_loc or not os.path.exists(cert_loc):
raise IOError("Could not find a suitable TLS CA certificate bundle, "
"invalid path: {}".format(cert_loc))
raise OSError(
f"Could not find a suitable TLS CA certificate bundle, "
f"invalid path: {cert_loc}"
)
conn.cert_reqs = 'CERT_REQUIRED'
conn.cert_reqs = "CERT_REQUIRED"
if not os.path.isdir(cert_loc):
conn.ca_certs = cert_loc
else:
conn.ca_cert_dir = cert_loc
else:
conn.cert_reqs = 'CERT_NONE'
conn.cert_reqs = "CERT_NONE"
conn.ca_certs = None
conn.ca_cert_dir = None
@@ -246,11 +324,14 @@ class HTTPAdapter(BaseAdapter):
conn.cert_file = cert
conn.key_file = None
if conn.cert_file and not os.path.exists(conn.cert_file):
raise IOError("Could not find the TLS certificate file, "
"invalid path: {}".format(conn.cert_file))
raise OSError(
f"Could not find the TLS certificate file, "
f"invalid path: {conn.cert_file}"
)
if conn.key_file and not os.path.exists(conn.key_file):
raise IOError("Could not find the TLS key file, "
"invalid path: {}".format(conn.key_file))
raise OSError(
f"Could not find the TLS key file, invalid path: {conn.key_file}"
)
def build_response(self, req, resp):
"""Builds a :class:`Response <requests.Response>` object from a urllib3
@@ -265,10 +346,10 @@ class HTTPAdapter(BaseAdapter):
response = Response()
# Fallback to None if there's no status_code, for whatever reason.
response.status_code = getattr(resp, 'status', None)
response.status_code = getattr(resp, "status", None)
# Make headers case-insensitive.
response.headers = CaseInsensitiveDict(getattr(resp, 'headers', {}))
response.headers = CaseInsensitiveDict(getattr(resp, "headers", {}))
# Set encoding.
response.encoding = get_encoding_from_headers(response.headers)
@@ -276,7 +357,7 @@ class HTTPAdapter(BaseAdapter):
response.reason = response.raw.reason
if isinstance(req.url, bytes):
response.url = req.url.decode('utf-8')
response.url = req.url.decode("utf-8")
else:
response.url = req.url
@@ -289,8 +370,110 @@ class HTTPAdapter(BaseAdapter):
return response
def build_connection_pool_key_attributes(self, request, verify, cert=None):
"""Build the PoolKey attributes used by urllib3 to return a connection.
This looks at the PreparedRequest, the user-specified verify value,
and the value of the cert parameter to determine what PoolKey values
to use to select a connection from a given urllib3 Connection Pool.
The SSL related pool key arguments are not consistently set. As of
this writing, use the following to determine what keys may be in that
dictionary:
* If ``verify`` is ``True``, ``"ssl_context"`` will be set and will be the
default Requests SSL Context
* If ``verify`` is ``False``, ``"ssl_context"`` will not be set but
``"cert_reqs"`` will be set
* If ``verify`` is a string, (i.e., it is a user-specified trust bundle)
``"ca_certs"`` will be set if the string is not a directory recognized
by :py:func:`os.path.isdir`, otherwise ``"ca_cert_dir"`` will be
set.
* If ``"cert"`` is specified, ``"cert_file"`` will always be set. If
``"cert"`` is a tuple with a second item, ``"key_file"`` will also
be present
To override these settings, one may subclass this class, call this
method and use the above logic to change parameters as desired. For
example, if one wishes to use a custom :py:class:`ssl.SSLContext` one
must both set ``"ssl_context"`` and based on what else they require,
alter the other keys to ensure the desired behaviour.
:param request:
The PreparedReqest being sent over the connection.
:type request:
:class:`~requests.models.PreparedRequest`
:param verify:
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.
:param cert:
(optional) Any user-provided SSL certificate for client
authentication (a.k.a., mTLS). This may be a string (i.e., just
the path to a file which holds both certificate and key) or a
tuple of length 2 with the certificate file path and key file
path.
:returns:
A tuple of two dictionaries. The first is the "host parameters"
portion of the Pool Key including scheme, hostname, and port. The
second is a dictionary of SSLContext related parameters.
"""
return _urllib3_request_context(request, verify, cert, self.poolmanager)
def get_connection_with_tls_context(self, request, verify, proxies=None, cert=None):
"""Returns a urllib3 connection for the given request and TLS settings.
This should not be called from user code, and is only exposed for use
when subclassing the :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
:param request:
The :class:`PreparedRequest <PreparedRequest>` object to be sent
over the connection.
:param verify:
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.
:param proxies:
(optional) The proxies dictionary to apply to the request.
:param cert:
(optional) Any user-provided SSL certificate to be used for client
authentication (a.k.a., mTLS).
:rtype:
urllib3.ConnectionPool
"""
proxy = select_proxy(request.url, proxies)
try:
host_params, pool_kwargs = self.build_connection_pool_key_attributes(
request,
verify,
cert,
)
except ValueError as e:
raise InvalidURL(e, request=request)
if proxy:
proxy = prepend_scheme_if_needed(proxy, "http")
proxy_url = parse_url(proxy)
if not proxy_url.host:
raise InvalidProxyURL(
"Please check proxy URL. It is malformed "
"and could be missing the host."
)
proxy_manager = self.proxy_manager_for(proxy)
conn = proxy_manager.connection_from_host(
**host_params, pool_kwargs=pool_kwargs
)
else:
# Only scheme should be lower case
conn = self.poolmanager.connection_from_host(
**host_params, pool_kwargs=pool_kwargs
)
return conn
def get_connection(self, url, proxies=None):
"""Returns a urllib3 connection for the given URL. This should not be
"""DEPRECATED: Users should move to `get_connection_with_tls_context`
for all subclasses of HTTPAdapter using Requests>=2.32.2.
Returns a urllib3 connection for the given URL. This should not be
called from user code, and is only exposed for use when subclassing the
:class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
@@ -298,14 +481,25 @@ class HTTPAdapter(BaseAdapter):
:param proxies: (optional) A Requests-style dictionary of proxies used on this request.
:rtype: urllib3.ConnectionPool
"""
warnings.warn(
(
"`get_connection` has been deprecated in favor of "
"`get_connection_with_tls_context`. Custom HTTPAdapter subclasses "
"will need to migrate for Requests>=2.32.2. Please see "
"https://github.com/psf/requests/pull/6710 for more details."
),
DeprecationWarning,
)
proxy = select_proxy(url, proxies)
if proxy:
proxy = prepend_scheme_if_needed(proxy, 'http')
proxy = prepend_scheme_if_needed(proxy, "http")
proxy_url = parse_url(proxy)
if not proxy_url.host:
raise InvalidProxyURL("Please check proxy URL. It is malformed"
" and could be missing the host.")
raise InvalidProxyURL(
"Please check proxy URL. It is malformed "
"and could be missing the host."
)
proxy_manager = self.proxy_manager_for(proxy)
conn = proxy_manager.connection_from_url(url)
else:
@@ -343,13 +537,16 @@ class HTTPAdapter(BaseAdapter):
proxy = select_proxy(request.url, proxies)
scheme = urlparse(request.url).scheme
is_proxied_http_request = (proxy and scheme != 'https')
is_proxied_http_request = proxy and scheme != "https"
using_socks_proxy = False
if proxy:
proxy_scheme = urlparse(proxy).scheme.lower()
using_socks_proxy = proxy_scheme.startswith('socks')
using_socks_proxy = proxy_scheme.startswith("socks")
url = request.path_url
if url.startswith("//"): # Don't confuse urllib3
url = f"/{url.lstrip('/')}"
if is_proxied_http_request and not using_socks_proxy:
url = urldefragauth(request.url)
@@ -386,12 +583,13 @@ class HTTPAdapter(BaseAdapter):
username, password = get_auth_from_url(proxy)
if username:
headers['Proxy-Authorization'] = _basic_auth_str(username,
password)
headers["Proxy-Authorization"] = _basic_auth_str(username, password)
return headers
def send(self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None):
def send(
self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None
):
"""Sends PreparedRequest object. Returns Response object.
:param request: The :class:`PreparedRequest <PreparedRequest>` being sent.
@@ -409,92 +607,55 @@ class HTTPAdapter(BaseAdapter):
"""
try:
conn = self.get_connection(request.url, proxies)
conn = self.get_connection_with_tls_context(
request, verify, proxies=proxies, cert=cert
)
except LocationValueError as e:
raise InvalidURL(e, request=request)
self.cert_verify(conn, request.url, verify, cert)
url = self.request_url(request, proxies)
self.add_headers(request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies)
self.add_headers(
request,
stream=stream,
timeout=timeout,
verify=verify,
cert=cert,
proxies=proxies,
)
chunked = not (request.body is None or 'Content-Length' in request.headers)
chunked = not (request.body is None or "Content-Length" in request.headers)
if isinstance(timeout, tuple):
try:
connect, read = timeout
timeout = TimeoutSauce(connect=connect, read=read)
except ValueError as e:
# this may raise a string formatting error.
err = ("Invalid timeout {}. Pass a (connect, read) "
"timeout tuple, or a single float to set "
"both timeouts to the same value".format(timeout))
raise ValueError(err)
except ValueError:
raise ValueError(
f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, "
f"or a single float to set both timeouts to the same value."
)
elif isinstance(timeout, TimeoutSauce):
pass
else:
timeout = TimeoutSauce(connect=timeout, read=timeout)
try:
if not chunked:
resp = conn.urlopen(
method=request.method,
url=url,
body=request.body,
headers=request.headers,
redirect=False,
assert_same_host=False,
preload_content=False,
decode_content=False,
retries=self.max_retries,
timeout=timeout
)
resp = conn.urlopen(
method=request.method,
url=url,
body=request.body,
headers=request.headers,
redirect=False,
assert_same_host=False,
preload_content=False,
decode_content=False,
retries=self.max_retries,
timeout=timeout,
chunked=chunked,
)
# Send the request.
else:
if hasattr(conn, 'proxy_pool'):
conn = conn.proxy_pool
low_conn = conn._get_conn(timeout=DEFAULT_POOL_TIMEOUT)
try:
low_conn.putrequest(request.method,
url,
skip_accept_encoding=True)
for header, value in request.headers.items():
low_conn.putheader(header, value)
low_conn.endheaders()
for i in request.body:
low_conn.send(hex(len(i))[2:].encode('utf-8'))
low_conn.send(b'\r\n')
low_conn.send(i)
low_conn.send(b'\r\n')
low_conn.send(b'0\r\n\r\n')
# Receive the response from the server
try:
# For Python 2.7, use buffering of HTTP responses
r = low_conn.getresponse(buffering=True)
except TypeError:
# For compatibility with Python 3.3+
r = low_conn.getresponse()
resp = HTTPResponse.from_httplib(
r,
pool=conn,
connection=low_conn,
preload_content=False,
decode_content=False
)
except:
# If we hit any problems here, clean up the connection.
# Then, reraise so that we can handle the actual exception.
low_conn.close()
raise
except (ProtocolError, socket.error) as err:
except (ProtocolError, OSError) as err:
raise ConnectionError(err, request=request)
except MaxRetryError as e:
@@ -527,6 +688,8 @@ class HTTPAdapter(BaseAdapter):
raise SSLError(e, request=request)
elif isinstance(e, ReadTimeoutError):
raise ReadTimeout(e, request=request)
elif isinstance(e, _InvalidHeader):
raise InvalidHeader(e, request=request)
else:
raise

View File

@@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
"""
requests.api
~~~~~~~~~~~~
@@ -16,7 +14,7 @@ from . import sessions
def request(method, url, **kwargs):
"""Constructs and sends a :class:`Request <Request>`.
:param method: method for the new :class:`Request` object.
:param method: method for the new :class:`Request` object: ``GET``, ``OPTIONS``, ``HEAD``, ``POST``, ``PUT``, ``PATCH``, or ``DELETE``.
:param url: URL for the new :class:`Request` object.
:param params: (optional) Dictionary, list of tuples or bytes to send
in the query string for the :class:`Request`.
@@ -27,7 +25,7 @@ def request(method, url, **kwargs):
:param cookies: (optional) Dict or CookieJar object to send with the :class:`Request`.
:param files: (optional) Dictionary of ``'name': file-like-objects`` (or ``{'name': file-tuple}``) for multipart encoding upload.
``file-tuple`` can be a 2-tuple ``('filename', fileobj)``, 3-tuple ``('filename', fileobj, 'content_type')``
or a 4-tuple ``('filename', fileobj, 'content_type', custom_headers)``, where ``'content-type'`` is a string
or a 4-tuple ``('filename', fileobj, 'content_type', custom_headers)``, where ``'content_type'`` is a string
defining the content type of the given file and ``custom_headers`` a dict-like object containing additional headers
to add for the file.
:param auth: (optional) Auth tuple to enable Basic/Digest/Custom HTTP Auth.
@@ -50,6 +48,7 @@ def request(method, url, **kwargs):
>>> import requests
>>> req = requests.request('GET', 'https://httpbin.org/get')
>>> req
<Response [200]>
"""
@@ -71,8 +70,7 @@ def get(url, params=None, **kwargs):
:rtype: requests.Response
"""
kwargs.setdefault('allow_redirects', True)
return request('get', url, params=params, **kwargs)
return request("get", url, params=params, **kwargs)
def options(url, **kwargs):
@@ -84,21 +82,22 @@ def options(url, **kwargs):
:rtype: requests.Response
"""
kwargs.setdefault('allow_redirects', True)
return request('options', url, **kwargs)
return request("options", url, **kwargs)
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
"""
kwargs.setdefault('allow_redirects', False)
return request('head', url, **kwargs)
kwargs.setdefault("allow_redirects", False)
return request("head", url, **kwargs)
def post(url, data=None, json=None, **kwargs):
@@ -107,13 +106,13 @@ def post(url, data=None, json=None, **kwargs):
:param url: URL for the new :class:`Request` object.
:param data: (optional) Dictionary, list of tuples, bytes, or file-like
object to send in the body of the :class:`Request`.
:param json: (optional) json data 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`.
:param \*\*kwargs: Optional arguments that ``request`` takes.
:return: :class:`Response <Response>` object
:rtype: requests.Response
"""
return request('post', url, data=data, json=json, **kwargs)
return request("post", url, data=data, json=json, **kwargs)
def put(url, data=None, **kwargs):
@@ -122,13 +121,13 @@ def put(url, data=None, **kwargs):
:param url: URL for the new :class:`Request` object.
:param data: (optional) Dictionary, list of tuples, bytes, or file-like
object to send in the body of the :class:`Request`.
:param json: (optional) json data 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`.
:param \*\*kwargs: Optional arguments that ``request`` takes.
:return: :class:`Response <Response>` object
:rtype: requests.Response
"""
return request('put', url, data=data, **kwargs)
return request("put", url, data=data, **kwargs)
def patch(url, data=None, **kwargs):
@@ -137,13 +136,13 @@ def patch(url, data=None, **kwargs):
:param url: URL for the new :class:`Request` object.
:param data: (optional) Dictionary, list of tuples, bytes, or file-like
object to send in the body of the :class:`Request`.
:param json: (optional) json data 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`.
:param \*\*kwargs: Optional arguments that ``request`` takes.
:return: :class:`Response <Response>` object
:rtype: requests.Response
"""
return request('patch', url, data=data, **kwargs)
return request("patch", url, data=data, **kwargs)
def delete(url, **kwargs):
@@ -155,4 +154,4 @@ def delete(url, **kwargs):
:rtype: requests.Response
"""
return request('delete', url, **kwargs)
return request("delete", url, **kwargs)

View File

@@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
"""
requests.auth
~~~~~~~~~~~~~
@@ -7,22 +5,21 @@ requests.auth
This module contains the authentication handlers for Requests.
"""
import hashlib
import os
import re
import time
import hashlib
import threading
import time
import warnings
from base64 import b64encode
from .compat import urlparse, str, basestring
from .cookies import extract_cookies_to_jar
from ._internal_utils import to_native_string
from .compat import basestring, str, urlparse
from .cookies import extract_cookies_to_jar
from .utils import parse_dict_header
CONTENT_TYPE_FORM_URLENCODED = 'application/x-www-form-urlencoded'
CONTENT_TYPE_MULTI_PART = 'multipart/form-data'
CONTENT_TYPE_FORM_URLENCODED = "application/x-www-form-urlencoded"
CONTENT_TYPE_MULTI_PART = "multipart/form-data"
def _basic_auth_str(username, password):
@@ -50,30 +47,30 @@ 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)
# -- End Removal --
if isinstance(username, str):
username = username.encode('latin1')
username = username.encode("latin1")
if isinstance(password, str):
password = password.encode('latin1')
password = password.encode("latin1")
authstr = 'Basic ' + to_native_string(
b64encode(b':'.join((username, password))).strip()
authstr = "Basic " + to_native_string(
b64encode(b":".join((username, password))).strip()
)
return authstr
class AuthBase(object):
class AuthBase:
"""Base class that all auth implementations derive from"""
def __call__(self, r):
raise NotImplementedError('Auth hooks must be callable.')
raise NotImplementedError("Auth hooks must be callable.")
class HTTPBasicAuth(AuthBase):
@@ -84,16 +81,18 @@ class HTTPBasicAuth(AuthBase):
self.password = password
def __eq__(self, other):
return all([
self.username == getattr(other, 'username', None),
self.password == getattr(other, 'password', None)
])
return all(
[
self.username == getattr(other, "username", None),
self.password == getattr(other, "password", None),
]
)
def __ne__(self, other):
return not self == other
def __call__(self, r):
r.headers['Authorization'] = _basic_auth_str(self.username, self.password)
r.headers["Authorization"] = _basic_auth_str(self.username, self.password)
return r
@@ -101,7 +100,7 @@ class HTTPProxyAuth(HTTPBasicAuth):
"""Attaches HTTP Proxy Authentication to a given Request object."""
def __call__(self, r):
r.headers['Proxy-Authorization'] = _basic_auth_str(self.username, self.password)
r.headers["Proxy-Authorization"] = _basic_auth_str(self.username, self.password)
return r
@@ -116,9 +115,9 @@ class HTTPDigestAuth(AuthBase):
def init_per_thread_state(self):
# Ensure state is initialized just once per-thread
if not hasattr(self._thread_local, 'init'):
if not hasattr(self._thread_local, "init"):
self._thread_local.init = True
self._thread_local.last_nonce = ''
self._thread_local.last_nonce = ""
self._thread_local.nonce_count = 0
self._thread_local.chal = {}
self._thread_local.pos = None
@@ -129,44 +128,52 @@ class HTTPDigestAuth(AuthBase):
:rtype: str
"""
realm = self._thread_local.chal['realm']
nonce = self._thread_local.chal['nonce']
qop = self._thread_local.chal.get('qop')
algorithm = self._thread_local.chal.get('algorithm')
opaque = self._thread_local.chal.get('opaque')
realm = self._thread_local.chal["realm"]
nonce = self._thread_local.chal["nonce"]
qop = self._thread_local.chal.get("qop")
algorithm = self._thread_local.chal.get("algorithm")
opaque = self._thread_local.chal.get("opaque")
hash_utf8 = None
if algorithm is None:
_algorithm = 'MD5'
_algorithm = "MD5"
else:
_algorithm = algorithm.upper()
# lambdas assume digest modules are imported at the top level
if _algorithm == 'MD5' or _algorithm == 'MD5-SESS':
if _algorithm == "MD5" or _algorithm == "MD5-SESS":
def md5_utf8(x):
if isinstance(x, str):
x = x.encode('utf-8')
x = x.encode("utf-8")
return hashlib.md5(x).hexdigest()
hash_utf8 = md5_utf8
elif _algorithm == 'SHA':
elif _algorithm == "SHA":
def sha_utf8(x):
if isinstance(x, str):
x = x.encode('utf-8')
x = x.encode("utf-8")
return hashlib.sha1(x).hexdigest()
hash_utf8 = sha_utf8
elif _algorithm == 'SHA-256':
elif _algorithm == "SHA-256":
def sha256_utf8(x):
if isinstance(x, str):
x = x.encode('utf-8')
x = x.encode("utf-8")
return hashlib.sha256(x).hexdigest()
hash_utf8 = sha256_utf8
elif _algorithm == 'SHA-512':
elif _algorithm == "SHA-512":
def sha512_utf8(x):
if isinstance(x, str):
x = x.encode('utf-8')
x = x.encode("utf-8")
return hashlib.sha512(x).hexdigest()
hash_utf8 = sha512_utf8
KD = lambda s, d: hash_utf8("%s:%s" % (s, d))
KD = lambda s, d: hash_utf8(f"{s}:{d}") # noqa:E731
if hash_utf8 is None:
return None
@@ -177,10 +184,10 @@ class HTTPDigestAuth(AuthBase):
#: path is request-uri defined in RFC 2616 which should not be empty
path = p_parsed.path or "/"
if p_parsed.query:
path += '?' + p_parsed.query
path += f"?{p_parsed.query}"
A1 = '%s:%s:%s' % (self.username, realm, self.password)
A2 = '%s:%s' % (method, path)
A1 = f"{self.username}:{realm}:{self.password}"
A2 = f"{method}:{path}"
HA1 = hash_utf8(A1)
HA2 = hash_utf8(A2)
@@ -189,22 +196,20 @@ class HTTPDigestAuth(AuthBase):
self._thread_local.nonce_count += 1
else:
self._thread_local.nonce_count = 1
ncvalue = '%08x' % self._thread_local.nonce_count
s = str(self._thread_local.nonce_count).encode('utf-8')
s += nonce.encode('utf-8')
s += time.ctime().encode('utf-8')
ncvalue = f"{self._thread_local.nonce_count:08x}"
s = str(self._thread_local.nonce_count).encode("utf-8")
s += nonce.encode("utf-8")
s += time.ctime().encode("utf-8")
s += os.urandom(8)
cnonce = (hashlib.sha1(s).hexdigest()[:16])
if _algorithm == 'MD5-SESS':
HA1 = hash_utf8('%s:%s:%s' % (HA1, nonce, cnonce))
cnonce = hashlib.sha1(s).hexdigest()[:16]
if _algorithm == "MD5-SESS":
HA1 = hash_utf8(f"{HA1}:{nonce}:{cnonce}")
if not qop:
respdig = KD(HA1, "%s:%s" % (nonce, HA2))
elif qop == 'auth' or 'auth' in qop.split(','):
noncebit = "%s:%s:%s:%s:%s" % (
nonce, ncvalue, cnonce, 'auth', HA2
)
respdig = KD(HA1, f"{nonce}:{HA2}")
elif qop == "auth" or "auth" in qop.split(","):
noncebit = f"{nonce}:{ncvalue}:{cnonce}:auth:{HA2}"
respdig = KD(HA1, noncebit)
else:
# XXX handle auth-int.
@@ -213,18 +218,20 @@ class HTTPDigestAuth(AuthBase):
self._thread_local.last_nonce = nonce
# XXX should the partial digests be encoded too?
base = 'username="%s", realm="%s", nonce="%s", uri="%s", ' \
'response="%s"' % (self.username, realm, nonce, path, respdig)
base = (
f'username="{self.username}", realm="{realm}", nonce="{nonce}", '
f'uri="{path}", response="{respdig}"'
)
if opaque:
base += ', opaque="%s"' % opaque
base += f', opaque="{opaque}"'
if algorithm:
base += ', algorithm="%s"' % algorithm
base += f', algorithm="{algorithm}"'
if entdig:
base += ', digest="%s"' % entdig
base += f', digest="{entdig}"'
if qop:
base += ', qop="auth", nc=%s, cnonce="%s"' % (ncvalue, cnonce)
base += f', qop="auth", nc={ncvalue}, cnonce="{cnonce}"'
return 'Digest %s' % (base)
return f"Digest {base}"
def handle_redirect(self, r, **kwargs):
"""Reset num_401_calls counter on redirects."""
@@ -239,7 +246,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
@@ -248,13 +255,12 @@ class HTTPDigestAuth(AuthBase):
# Rewind the file position indicator of the body to where
# it was to resend the request.
r.request.body.seek(self._thread_local.pos)
s_auth = r.headers.get('www-authenticate', '')
if 'digest' in s_auth.lower() and self._thread_local.num_401_calls < 2:
s_auth = r.headers.get("www-authenticate", "")
if "digest" in s_auth.lower() and self._thread_local.num_401_calls < 2:
self._thread_local.num_401_calls += 1
pat = re.compile(r'digest ', flags=re.IGNORECASE)
self._thread_local.chal = parse_dict_header(pat.sub('', s_auth, count=1))
pat = re.compile(r"digest ", flags=re.IGNORECASE)
self._thread_local.chal = parse_dict_header(pat.sub("", s_auth, count=1))
# Consume content and release the original connection
# to allow our new request to reuse the same one.
@@ -264,8 +270,9 @@ class HTTPDigestAuth(AuthBase):
extract_cookies_to_jar(prep._cookies, r.request, r.raw)
prep.prepare_cookies(prep._cookies)
prep.headers['Authorization'] = self.build_digest_header(
prep.method, prep.url)
prep.headers["Authorization"] = self.build_digest_header(
prep.method, prep.url
)
_r = r.connection.send(prep, **kwargs)
_r.history.append(r)
_r.request = prep
@@ -280,7 +287,7 @@ class HTTPDigestAuth(AuthBase):
self.init_per_thread_state()
# If we have a saved nonce, skip the 401
if self._thread_local.last_nonce:
r.headers['Authorization'] = self.build_digest_header(r.method, r.url)
r.headers["Authorization"] = self.build_digest_header(r.method, r.url)
try:
self._thread_local.pos = r.body.tell()
except AttributeError:
@@ -289,17 +296,19 @@ class HTTPDigestAuth(AuthBase):
# file position of the previous body. Ensure it's set to
# None.
self._thread_local.pos = None
r.register_hook('response', self.handle_401)
r.register_hook('response', self.handle_redirect)
r.register_hook("response", self.handle_401)
r.register_hook("response", self.handle_redirect)
self._thread_local.num_401_calls = 1
return r
def __eq__(self, other):
return all([
self.username == getattr(other, 'username', None),
self.password == getattr(other, 'password', None)
])
return all(
[
self.username == getattr(other, "username", None),
self.password == getattr(other, "password", None),
]
)
def __ne__(self, other):
return not self == other

View File

@@ -1,5 +1,4 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
requests.certs
@@ -14,5 +13,5 @@ packaged CA bundle.
"""
from certifi import where
if __name__ == '__main__':
if __name__ == "__main__":
print(where())

106
src/requests/compat.py Normal file
View File

@@ -0,0 +1,106 @@
"""
requests.compat
~~~~~~~~~~~~~~~
This module previously handled import compatibility issues
between Python 2 and Python 3. It remains for backwards
compatibility until the next major version.
"""
import importlib
import sys
# -------
# urllib3
# -------
from urllib3 import __version__ as urllib3_version
# Detect which major version of urllib3 is being used.
try:
is_urllib3_1 = int(urllib3_version.split(".")[0]) == 1
except (TypeError, AttributeError):
# If we can't discern a version, prefer old functionality.
is_urllib3_1 = True
# -------------------
# Character Detection
# -------------------
def _resolve_char_detection():
"""Find supported character detection libraries."""
chardet = None
for lib in ("chardet", "charset_normalizer"):
if chardet is None:
try:
chardet = importlib.import_module(lib)
except ImportError:
pass
return chardet
chardet = _resolve_char_detection()
# -------
# Pythons
# -------
# Syntax sugar.
_ver = sys.version_info
#: Python 2.x?
is_py2 = _ver[0] == 2
#: Python 3.x?
is_py3 = _ver[0] == 3
# json/simplejson module import resolution
has_simplejson = False
try:
import simplejson as json
has_simplejson = True
except ImportError:
import json
if has_simplejson:
from simplejson import JSONDecodeError
else:
from json import JSONDecodeError
# Keep OrderedDict for backwards compatibility.
from collections import OrderedDict
from collections.abc import Callable, Mapping, MutableMapping
from http import cookiejar as cookielib
from http.cookies import Morsel
from io import StringIO
# --------------
# Legacy Imports
# --------------
from urllib.parse import (
quote,
quote_plus,
unquote,
unquote_plus,
urldefrag,
urlencode,
urljoin,
urlparse,
urlsplit,
urlunparse,
)
from urllib.request import (
getproxies,
getproxies_environment,
parse_http_list,
proxy_bypass,
proxy_bypass_environment,
)
builtin_str = str
str = str
bytes = bytes
basestring = (str, bytes)
numeric_types = (int, float)
integer_types = (int,)

View File

@@ -1,20 +1,18 @@
# -*- coding: utf-8 -*-
"""
requests.cookies
~~~~~~~~~~~~~~~~
Compatibility code to be able to use `cookielib.CookieJar` with requests.
Compatibility code to be able to use `http.cookiejar.CookieJar` with requests.
requests.utils imports from here, so be careful with imports.
"""
import calendar
import copy
import time
import calendar
from ._internal_utils import to_native_string
from .compat import cookielib, urlparse, urlunparse, Morsel, MutableMapping
from .compat import Morsel, MutableMapping, cookielib, urlparse, urlunparse
try:
import threading
@@ -22,10 +20,10 @@ except ImportError:
import dummy_threading as threading
class MockRequest(object):
class MockRequest:
"""Wraps a `requests.Request` to mimic a `urllib2.Request`.
The code in `cookielib.CookieJar` expects this interface in order to correctly
The code in `http.cookiejar.CookieJar` expects this interface in order to correctly
manage cookie policies, i.e., determine whether a cookie can be set, given the
domains of the request and the cookie.
@@ -51,16 +49,22 @@ class MockRequest(object):
def get_full_url(self):
# Only return the response's URL if the user hadn't set the Host
# header
if not self._r.headers.get('Host'):
if not self._r.headers.get("Host"):
return self._r.url
# If they did set it, retrieve it and reconstruct the expected domain
host = to_native_string(self._r.headers['Host'], encoding='utf-8')
host = to_native_string(self._r.headers["Host"], encoding="utf-8")
parsed = urlparse(self._r.url)
# Reconstruct the URL as we expect it
return urlunparse([
parsed.scheme, host, parsed.path, parsed.params, parsed.query,
parsed.fragment
])
return urlunparse(
[
parsed.scheme,
host,
parsed.path,
parsed.params,
parsed.query,
parsed.fragment,
]
)
def is_unverifiable(self):
return True
@@ -72,8 +76,10 @@ class MockRequest(object):
return self._r.headers.get(name, self._new_headers.get(name, default))
def add_header(self, key, val):
"""cookielib has no legitimate use for this method; add it back if you find one."""
raise NotImplementedError("Cookie headers should be added with add_unredirected_header()")
"""cookiejar has no legitimate use for this method; add it back if you find one."""
raise NotImplementedError(
"Cookie headers should be added with add_unredirected_header()"
)
def add_unredirected_header(self, name, value):
self._new_headers[name] = value
@@ -94,15 +100,15 @@ class MockRequest(object):
return self.get_host()
class MockResponse(object):
class MockResponse:
"""Wraps a `httplib.HTTPMessage` to mimic a `urllib.addinfourl`.
...what? Basically, expose the parsed HTTP headers from the server response
the way `cookielib` expects to see them.
the way `http.cookiejar` expects to see them.
"""
def __init__(self, headers):
"""Make a MockResponse for `cookielib` to read.
"""Make a MockResponse for `cookiejar` to read.
:param headers: a httplib.HTTPMessage or analogous carrying the headers
"""
@@ -118,12 +124,11 @@ class MockResponse(object):
def extract_cookies_to_jar(jar, request, response):
"""Extract the cookies from the response into a CookieJar.
:param jar: cookielib.CookieJar (not necessarily a RequestsCookieJar)
:param jar: http.cookiejar.CookieJar (not necessarily a RequestsCookieJar)
:param request: our own requests.Request object
:param response: urllib3.HTTPResponse object
"""
if not (hasattr(response, '_original_response') and
response._original_response):
if not (hasattr(response, "_original_response") and response._original_response):
return
# the _original_response field is the wrapped httplib.HTTPResponse object,
req = MockRequest(request)
@@ -140,7 +145,7 @@ def get_cookie_header(jar, request):
"""
r = MockRequest(request)
jar.add_cookie_header(r)
return r.get_new_headers().get('Cookie')
return r.get_new_headers().get("Cookie")
def remove_cookie_by_name(cookiejar, name, domain=None, path=None):
@@ -169,7 +174,7 @@ class CookieConflictError(RuntimeError):
class RequestsCookieJar(cookielib.CookieJar, MutableMapping):
"""Compatibility class; is a cookielib.CookieJar, but exposes a dict
"""Compatibility class; is a http.cookiejar.CookieJar, but exposes a dict
interface.
This is the CookieJar we create by default for requests and sessions that
@@ -205,7 +210,9 @@ class RequestsCookieJar(cookielib.CookieJar, MutableMapping):
"""
# support client code that unsets cookies by assignment of a None value:
if value is None:
remove_cookie_by_name(self, name, domain=kwargs.get('domain'), path=kwargs.get('path'))
remove_cookie_by_name(
self, name, domain=kwargs.get("domain"), path=kwargs.get("path")
)
return
if isinstance(value, Morsel):
@@ -305,16 +312,15 @@ class RequestsCookieJar(cookielib.CookieJar, MutableMapping):
"""
dictionary = {}
for cookie in iter(self):
if (
(domain is None or cookie.domain == domain) and
(path is None or cookie.path == path)
if (domain is None or cookie.domain == domain) and (
path is None or cookie.path == path
):
dictionary[cookie.name] = cookie.value
return dictionary
def __contains__(self, name):
try:
return super(RequestsCookieJar, self).__contains__(name)
return super().__contains__(name)
except CookieConflictError:
return True
@@ -335,15 +341,19 @@ class RequestsCookieJar(cookielib.CookieJar, MutableMapping):
self.set(name, value)
def __delitem__(self, name):
"""Deletes a cookie given a name. Wraps ``cookielib.CookieJar``'s
"""Deletes a cookie given a name. Wraps ``http.cookiejar.CookieJar``'s
``remove_cookie_by_name()``.
"""
remove_cookie_by_name(self, name)
def set_cookie(self, cookie, *args, **kwargs):
if hasattr(cookie.value, 'startswith') and cookie.value.startswith('"') and cookie.value.endswith('"'):
cookie.value = cookie.value.replace('\\"', '')
return super(RequestsCookieJar, self).set_cookie(cookie, *args, **kwargs)
if (
hasattr(cookie.value, "startswith")
and cookie.value.startswith('"')
and cookie.value.endswith('"')
):
cookie.value = cookie.value.replace('\\"', "")
return super().set_cookie(cookie, *args, **kwargs)
def update(self, other):
"""Updates this jar with cookies from another CookieJar or dict-like"""
@@ -351,7 +361,7 @@ class RequestsCookieJar(cookielib.CookieJar, MutableMapping):
for cookie in other:
self.set_cookie(copy.copy(cookie))
else:
super(RequestsCookieJar, self).update(other)
super().update(other)
def _find(self, name, domain=None, path=None):
"""Requests uses this method internally to get cookie values.
@@ -371,7 +381,7 @@ class RequestsCookieJar(cookielib.CookieJar, MutableMapping):
if path is None or cookie.path == path:
return cookie.value
raise KeyError('name=%r, domain=%r, path=%r' % (name, domain, path))
raise KeyError(f"name={name!r}, domain={domain!r}, path={path!r}")
def _find_no_duplicates(self, name, domain=None, path=None):
"""Both ``__get_item__`` and ``get`` call this function: it's never
@@ -390,25 +400,29 @@ class RequestsCookieJar(cookielib.CookieJar, MutableMapping):
if cookie.name == name:
if domain is None or cookie.domain == domain:
if path is None or cookie.path == path:
if toReturn is not None: # if there are multiple cookies that meet passed in criteria
raise CookieConflictError('There are multiple cookies with name, %r' % (name))
toReturn = cookie.value # we will eventually return this as long as no cookie conflict
if toReturn is not None:
# if there are multiple cookies that meet passed in criteria
raise CookieConflictError(
f"There are multiple cookies with name, {name!r}"
)
# we will eventually return this as long as no cookie conflict
toReturn = cookie.value
if toReturn:
return toReturn
raise KeyError('name=%r, domain=%r, path=%r' % (name, domain, path))
raise KeyError(f"name={name!r}, domain={domain!r}, path={path!r}")
def __getstate__(self):
"""Unlike a normal CookieJar, this class is pickleable."""
state = self.__dict__.copy()
# remove the unpickleable RLock object
state.pop('_cookies_lock')
state.pop("_cookies_lock")
return state
def __setstate__(self, state):
"""Unlike a normal CookieJar, this class is pickleable."""
self.__dict__.update(state)
if '_cookies_lock' not in self.__dict__:
if "_cookies_lock" not in self.__dict__:
self._cookies_lock = threading.RLock()
def copy(self):
@@ -427,7 +441,7 @@ def _copy_cookie_jar(jar):
if jar is None:
return None
if hasattr(jar, 'copy'):
if hasattr(jar, "copy"):
# We're dealing with an instance of RequestsCookieJar
return jar.copy()
# We're dealing with a generic CookieJar instance
@@ -445,31 +459,32 @@ def create_cookie(name, value, **kwargs):
and sent on every request (this is sometimes called a "supercookie").
"""
result = {
'version': 0,
'name': name,
'value': value,
'port': None,
'domain': '',
'path': '/',
'secure': False,
'expires': None,
'discard': True,
'comment': None,
'comment_url': None,
'rest': {'HttpOnly': None},
'rfc2109': False,
"version": 0,
"name": name,
"value": value,
"port": None,
"domain": "",
"path": "/",
"secure": False,
"expires": None,
"discard": True,
"comment": None,
"comment_url": None,
"rest": {"HttpOnly": None},
"rfc2109": False,
}
badargs = set(kwargs) - set(result)
if badargs:
err = 'create_cookie() got unexpected keyword arguments: %s'
raise TypeError(err % list(badargs))
raise TypeError(
f"create_cookie() got unexpected keyword arguments: {list(badargs)}"
)
result.update(kwargs)
result['port_specified'] = bool(result['port'])
result['domain_specified'] = bool(result['domain'])
result['domain_initial_dot'] = result['domain'].startswith('.')
result['path_specified'] = bool(result['path'])
result["port_specified"] = bool(result["port"])
result["domain_specified"] = bool(result["domain"])
result["domain_initial_dot"] = result["domain"].startswith(".")
result["path_specified"] = bool(result["path"])
return cookielib.Cookie(**result)
@@ -478,30 +493,28 @@ def morsel_to_cookie(morsel):
"""Convert a Morsel object into a Cookie containing the one k/v pair."""
expires = None
if morsel['max-age']:
if morsel["max-age"]:
try:
expires = int(time.time() + int(morsel['max-age']))
expires = int(time.time() + int(morsel["max-age"]))
except ValueError:
raise TypeError('max-age: %s must be integer' % morsel['max-age'])
elif morsel['expires']:
time_template = '%a, %d-%b-%Y %H:%M:%S GMT'
expires = calendar.timegm(
time.strptime(morsel['expires'], time_template)
)
raise TypeError(f"max-age: {morsel['max-age']} must be integer")
elif morsel["expires"]:
time_template = "%a, %d-%b-%Y %H:%M:%S GMT"
expires = calendar.timegm(time.strptime(morsel["expires"], time_template))
return create_cookie(
comment=morsel['comment'],
comment_url=bool(morsel['comment']),
comment=morsel["comment"],
comment_url=bool(morsel["comment"]),
discard=False,
domain=morsel['domain'],
domain=morsel["domain"],
expires=expires,
name=morsel.key,
path=morsel['path'],
path=morsel["path"],
port=None,
rest={'HttpOnly': morsel['httponly']},
rest={"HttpOnly": morsel["httponly"]},
rfc2109=False,
secure=bool(morsel['secure']),
secure=bool(morsel["secure"]),
value=morsel.value,
version=morsel['version'] or 0,
version=morsel["version"] or 0,
)
@@ -534,11 +547,10 @@ def merge_cookies(cookiejar, cookies):
:rtype: CookieJar
"""
if not isinstance(cookiejar, cookielib.CookieJar):
raise ValueError('You can only merge into CookieJar')
raise ValueError("You can only merge into CookieJar")
if isinstance(cookies, dict):
cookiejar = cookiejar_from_dict(
cookies, cookiejar=cookiejar, overwrite=False)
cookiejar = cookiejar_from_dict(cookies, cookiejar=cookiejar, overwrite=False)
elif isinstance(cookies, cookielib.CookieJar):
try:
cookiejar.update(cookies)

View File

@@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
"""
requests.exceptions
~~~~~~~~~~~~~~~~~~~
@@ -8,6 +6,8 @@ This module contains the set of Requests' exceptions.
"""
from urllib3.exceptions import HTTPError as BaseHTTPError
from .compat import JSONDecodeError as CompatJSONDecodeError
class RequestException(IOError):
"""There was an ambiguous exception that occurred while handling your
@@ -16,13 +16,40 @@ class RequestException(IOError):
def __init__(self, *args, **kwargs):
"""Initialize RequestException with `request` and `response` objects."""
response = kwargs.pop('response', None)
response = kwargs.pop("response", None)
self.response = response
self.request = kwargs.pop('request', None)
if (response is not None and not self.request and
hasattr(response, 'request')):
self.request = kwargs.pop("request", None)
if response is not None and not self.request and hasattr(response, "request"):
self.request = self.response.request
super(RequestException, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
class InvalidJSONError(RequestException):
"""A JSON error occurred."""
class JSONDecodeError(InvalidJSONError, CompatJSONDecodeError):
"""Couldn't decode the text into json"""
def __init__(self, *args, **kwargs):
"""
Construct the JSONDecodeError instance first with all
args. Then use it's args to construct the IOError so that
the json specific args aren't used as IOError specific args
and the error message from JSONDecodeError is preserved.
"""
CompatJSONDecodeError.__init__(self, *args)
InvalidJSONError.__init__(self, *self.args, **kwargs)
def __reduce__(self):
"""
The __reduce__ method called when pickling the object must
be the one from the JSONDecodeError (be it json/simplejson)
as it expects all the arguments for instantiation, not just
one like the IOError, and the MRO would by default call the
__reduce__ method from the IOError due to the inheritance order.
"""
return CompatJSONDecodeError.__reduce__(self)
class HTTPError(RequestException):
@@ -70,11 +97,11 @@ class TooManyRedirects(RequestException):
class MissingSchema(RequestException, ValueError):
"""The URL schema (e.g. http or https) is missing."""
"""The URL scheme (e.g. http or https) is missing."""
class InvalidSchema(RequestException, ValueError):
"""See defaults.py for valid schemas."""
"""The URL scheme provided is either invalid or unsupported."""
class InvalidURL(RequestException, ValueError):
@@ -94,11 +121,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 +133,19 @@ 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

134
src/requests/help.py Normal file
View File

@@ -0,0 +1,134 @@
"""Module containing bug report helper(s)."""
import json
import platform
import ssl
import sys
import idna
import urllib3
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:
pyopenssl = None
OpenSSL = None
cryptography = None
else:
import cryptography
import OpenSSL
def _implementation():
"""Return a dict with the Python implementation and version.
Provide both the name and the version of the Python implementation
currently running. For example, on CPython 3.10.3 it will return
{'name': 'CPython', 'version': '3.10.3'}.
This function works best on CPython and PyPy: in particular, it probably
doesn't work for Jython or IronPython. Future investigation should be done
to work out the correct shape of the code for those platforms.
"""
implementation = platform.python_implementation()
if implementation == "CPython":
implementation_version = platform.python_version()
elif implementation == "PyPy":
implementation_version = "{}.{}.{}".format(
sys.pypy_version_info.major,
sys.pypy_version_info.minor,
sys.pypy_version_info.micro,
)
if sys.pypy_version_info.releaselevel != "final":
implementation_version = "".join(
[implementation_version, sys.pypy_version_info.releaselevel]
)
elif implementation == "Jython":
implementation_version = platform.python_version() # Complete Guess
elif implementation == "IronPython":
implementation_version = platform.python_version() # Complete Guess
else:
implementation_version = "Unknown"
return {"name": implementation, "version": implementation_version}
def info():
"""Generate information for a bug report."""
try:
platform_info = {
"system": platform.system(),
"release": platform.release(),
}
except OSError:
platform_info = {
"system": "Unknown",
"release": "Unknown",
}
implementation_info = _implementation()
urllib3_info = {"version": urllib3.__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,
"openssl_version": "",
}
if OpenSSL:
pyopenssl_info = {
"version": OpenSSL.__version__,
"openssl_version": f"{OpenSSL.SSL.OPENSSL_VERSION_NUMBER:x}",
}
cryptography_info = {
"version": getattr(cryptography, "__version__", ""),
}
idna_info = {
"version": getattr(idna, "__version__", ""),
}
system_ssl = ssl.OPENSSL_VERSION_NUMBER
system_ssl_info = {"version": f"{system_ssl:x}" if system_ssl is not None else ""}
return {
"platform": platform_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": {
"version": requests_version,
},
}
def main():
"""Pretty-print the bug information as JSON."""
print(json.dumps(info(), sort_keys=True, indent=2))
if __name__ == "__main__":
main()

View File

@@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
"""
requests.hooks
~~~~~~~~~~~~~~
@@ -11,12 +9,13 @@ Available hooks:
``response``:
The response generated from a Request.
"""
HOOKS = ['response']
HOOKS = ["response"]
def default_hooks():
return {event: [] for event in HOOKS}
# TODO: response is the only one
@@ -25,7 +24,7 @@ def dispatch_hook(key, hooks, hook_data, **kwargs):
hooks = hooks or {}
hooks = hooks.get(key)
if hooks:
if hasattr(hooks, '__call__'):
if hasattr(hooks, "__call__"):
hooks = [hooks]
for hook in hooks:
_hook_data = hook(hook_data, **kwargs)

View File

@@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
"""
requests.models
~~~~~~~~~~~~~~~
@@ -8,46 +6,72 @@ This module contains the primary objects that power Requests.
"""
import datetime
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.
import encodings.idna
# such as in Embedded Python. See https://github.com/psf/requests/issues/3578.
import encodings.idna # noqa: F401
from io import UnsupportedOperation
from urllib3.exceptions import (
DecodeError,
LocationParseError,
ProtocolError,
ReadTimeoutError,
SSLError,
)
from urllib3.fields import RequestField
from urllib3.filepost import encode_multipart_formdata
from urllib3.util import parse_url
from urllib3.exceptions import (
DecodeError, ReadTimeoutError, ProtocolError, LocationParseError)
from io import UnsupportedOperation
from .hooks import default_hooks
from .structures import CaseInsensitiveDict
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)
from ._internal_utils import to_native_string, unicode_is_ascii
from .utils import (
guess_filename, get_auth_from_url, requote_uri,
stream_decode_response_unicode, to_key_val_list, parse_header_links,
iter_slices, guess_json_utf, super_len, check_header_validity)
from .auth import HTTPBasicAuth
from .compat import (
Callable, Mapping,
cookielib, urlunparse, urlsplit, urlencode, str, bytes,
is_py2, chardet, builtin_str, basestring)
Callable,
JSONDecodeError,
Mapping,
basestring,
builtin_str,
chardet,
cookielib,
)
from .compat import json as complexjson
from .compat import urlencode, urlsplit, urlunparse
from .cookies import _copy_cookie_jar, cookiejar_from_dict, get_cookie_header
from .exceptions import (
ChunkedEncodingError,
ConnectionError,
ContentDecodingError,
HTTPError,
InvalidJSONError,
InvalidURL,
)
from .exceptions import JSONDecodeError as RequestsJSONDecodeError
from .exceptions import MissingSchema
from .exceptions import SSLError as RequestsSSLError
from .exceptions import StreamConsumedError
from .hooks import default_hooks
from .status_codes import codes
from .structures import CaseInsensitiveDict
from .utils import (
check_header_validity,
get_auth_from_url,
guess_filename,
guess_json_utf,
iter_slices,
parse_header_links,
requote_uri,
stream_decode_response_unicode,
super_len,
to_key_val_list,
)
#: The set of HTTP status codes that indicate an automatically
#: processable redirect.
REDIRECT_STATI = (
codes.moved, # 301
codes.found, # 302
codes.other, # 303
codes.moved, # 301
codes.found, # 302
codes.other, # 303
codes.temporary_redirect, # 307
codes.permanent_redirect, # 308
)
@@ -57,7 +81,7 @@ CONTENT_CHUNK_SIZE = 10 * 1024
ITER_CHUNK_SIZE = 512
class RequestEncodingMixin(object):
class RequestEncodingMixin:
@property
def path_url(self):
"""Build the path URL to use."""
@@ -68,16 +92,16 @@ class RequestEncodingMixin(object):
path = p.path
if not path:
path = '/'
path = "/"
url.append(path)
query = p.query
if query:
url.append('?')
url.append("?")
url.append(query)
return ''.join(url)
return "".join(url)
@staticmethod
def _encode_params(data):
@@ -90,18 +114,21 @@ class RequestEncodingMixin(object):
if isinstance(data, (str, bytes)):
return data
elif hasattr(data, 'read'):
elif hasattr(data, "read"):
return data
elif hasattr(data, '__iter__'):
elif hasattr(data, "__iter__"):
result = []
for k, vs in to_key_val_list(data):
if isinstance(vs, basestring) or not hasattr(vs, '__iter__'):
if isinstance(vs, basestring) or not hasattr(vs, "__iter__"):
vs = [vs]
for v in vs:
if v is not None:
result.append(
(k.encode('utf-8') if isinstance(k, str) else k,
v.encode('utf-8') if isinstance(v, str) else v))
(
k.encode("utf-8") if isinstance(k, str) else k,
v.encode("utf-8") if isinstance(v, str) else v,
)
)
return urlencode(result, doseq=True)
else:
return data
@@ -116,7 +143,7 @@ class RequestEncodingMixin(object):
The tuples may be 2-tuples (filename, fileobj), 3-tuples (filename, fileobj, contentype)
or 4-tuples (filename, fileobj, contentype, custom_headers).
"""
if (not files):
if not files:
raise ValueError("Files must be provided.")
elif isinstance(data, basestring):
raise ValueError("Data must not be a string.")
@@ -126,7 +153,7 @@ class RequestEncodingMixin(object):
files = to_key_val_list(files or {})
for field, val in fields:
if isinstance(val, basestring) or not hasattr(val, '__iter__'):
if isinstance(val, basestring) or not hasattr(val, "__iter__"):
val = [val]
for v in val:
if v is not None:
@@ -135,10 +162,15 @@ class RequestEncodingMixin(object):
v = str(v)
new_fields.append(
(field.decode('utf-8') if isinstance(field, bytes) else field,
v.encode('utf-8') if isinstance(v, str) else v))
(
field.decode("utf-8")
if isinstance(field, bytes)
else field,
v.encode("utf-8") if isinstance(v, str) else v,
)
)
for (k, v) in files:
for k, v in files:
# support for explicit filename
ft = None
fh = None
@@ -155,7 +187,7 @@ class RequestEncodingMixin(object):
if isinstance(fp, (str, bytes, bytearray)):
fdata = fp
elif hasattr(fp, 'read'):
elif hasattr(fp, "read"):
fdata = fp.read()
elif fp is None:
continue
@@ -171,16 +203,16 @@ class RequestEncodingMixin(object):
return body, content_type
class RequestHooksMixin(object):
class RequestHooksMixin:
def register_hook(self, event, hook):
"""Properly register a hook."""
if event not in self.hooks:
raise ValueError('Unsupported event specified, with event name "%s"' % (event))
raise ValueError(f'Unsupported event specified, with event name "{event}"')
if isinstance(hook, Callable):
self.hooks[event].append(hook)
elif hasattr(hook, '__iter__'):
elif hasattr(hook, "__iter__"):
self.hooks[event].extend(h for h in hook if isinstance(h, Callable))
def deregister_hook(self, event, hook):
@@ -223,10 +255,19 @@ class Request(RequestHooksMixin):
<PreparedRequest [GET]>
"""
def __init__(self,
method=None, url=None, headers=None, files=None, data=None,
params=None, auth=None, cookies=None, hooks=None, json=None):
def __init__(
self,
method=None,
url=None,
headers=None,
files=None,
data=None,
params=None,
auth=None,
cookies=None,
hooks=None,
json=None,
):
# Default empty dicts for dict params.
data = [] if data is None else data
files = [] if files is None else files
@@ -235,7 +276,7 @@ class Request(RequestHooksMixin):
hooks = {} if hooks is None else hooks
self.hooks = default_hooks()
for (k, v) in list(hooks.items()):
for k, v in list(hooks.items()):
self.register_hook(event=k, hook=v)
self.method = method
@@ -249,7 +290,7 @@ class Request(RequestHooksMixin):
self.cookies = cookies
def __repr__(self):
return '<Request [%s]>' % (self.method)
return f"<Request [{self.method}]>"
def prepare(self):
"""Constructs a :class:`PreparedRequest <PreparedRequest>` for transmission and returns it."""
@@ -273,13 +314,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()
@@ -304,9 +348,19 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
#: integer denoting starting position of a readable file-like body.
self._body_position = None
def prepare(self,
method=None, url=None, headers=None, files=None, data=None,
params=None, auth=None, cookies=None, hooks=None, json=None):
def prepare(
self,
method=None,
url=None,
headers=None,
files=None,
data=None,
params=None,
auth=None,
cookies=None,
hooks=None,
json=None,
):
"""Prepares the entire request with the given parameters."""
self.prepare_method(method)
@@ -323,7 +377,7 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
self.prepare_hooks(hooks)
def __repr__(self):
return '<PreparedRequest [%s]>' % (self.method)
return f"<PreparedRequest [{self.method}]>"
def copy(self):
p = PreparedRequest()
@@ -347,7 +401,7 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
import idna
try:
host = idna.encode(host, uts46=True).decode('utf-8')
host = idna.encode(host, uts46=True).decode("utf-8")
except idna.IDNAError:
raise UnicodeError
return host
@@ -358,11 +412,11 @@ 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')
url = url.decode("utf8")
else:
url = unicode(url) if is_py2 else str(url)
url = str(url)
# Remove leading whitespaces from url
url = url.lstrip()
@@ -370,7 +424,7 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
# Don't do any URL preparation for non-HTTP schemes like `mailto`,
# `data` etc to work around exceptions from `url_parse`, which
# handles RFC 3986 only.
if ':' in url and not url.lower().startswith('http'):
if ":" in url and not url.lower().startswith("http"):
self.url = url
return
@@ -381,13 +435,13 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
raise InvalidURL(*e.args)
if not scheme:
error = ("Invalid URL {0!r}: No schema supplied. Perhaps you meant http://{0}?")
error = error.format(to_native_string(url, 'utf8'))
raise MissingSchema(error)
raise MissingSchema(
f"Invalid URL {url!r}: No scheme supplied. "
f"Perhaps you meant https://{url}?"
)
if not host:
raise InvalidURL("Invalid URL %r: No host supplied" % url)
raise InvalidURL(f"Invalid URL {url!r}: No host supplied")
# In general, we want to try IDNA encoding the hostname if the string contains
# non-ASCII characters. This allows users to automatically get the correct IDNA
@@ -397,33 +451,21 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
try:
host = self._get_idna_encoded_host(host)
except UnicodeError:
raise InvalidURL('URL has an invalid label.')
elif host.startswith(u'*'):
raise InvalidURL('URL has an invalid label.')
raise InvalidURL("URL has an invalid label.")
elif host.startswith(("*", ".")):
raise InvalidURL("URL has an invalid label.")
# Carefully reconstruct the network location
netloc = auth or ''
netloc = auth or ""
if netloc:
netloc += '@'
netloc += "@"
netloc += host
if port:
netloc += ':' + str(port)
netloc += f":{port}"
# Bare domains aren't valid URLs.
if not path:
path = '/'
if is_py2:
if isinstance(scheme, str):
scheme = scheme.encode('utf-8')
if isinstance(netloc, str):
netloc = netloc.encode('utf-8')
if isinstance(path, str):
path = path.encode('utf-8')
if isinstance(query, str):
query = query.encode('utf-8')
if isinstance(fragment, str):
fragment = fragment.encode('utf-8')
path = "/"
if isinstance(params, (str, bytes)):
params = to_native_string(params)
@@ -431,7 +473,7 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
enc_params = self._encode_params(params)
if enc_params:
if query:
query = '%s&%s' % (query, enc_params)
query = f"{query}&{enc_params}"
else:
query = enc_params
@@ -462,42 +504,51 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
if not data and json is not None:
# 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)
content_type = "application/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')
body = body.encode("utf-8")
is_stream = all([
hasattr(data, '__iter__'),
not isinstance(data, (basestring, list, tuple, Mapping))
])
try:
length = super_len(data)
except (TypeError, AttributeError, UnsupportedOperation):
length = None
is_stream = all(
[
hasattr(data, "__iter__"),
not isinstance(data, (basestring, list, tuple, Mapping)),
]
)
if is_stream:
try:
length = super_len(data)
except (TypeError, AttributeError, UnsupportedOperation):
length = None
body = data
if getattr(body, 'tell', None) is not None:
if getattr(body, "tell", None) is not None:
# Record the current file position before reading.
# This will allow us to rewind a file in the event
# of a redirect.
try:
self._body_position = body.tell()
except (IOError, OSError):
except OSError:
# This differentiates from None, allowing us to catch
# a failed `tell()` later when trying to rewind the body
self._body_position = object()
if files:
raise NotImplementedError('Streamed bodies and files are mutually exclusive.')
raise NotImplementedError(
"Streamed bodies and files are mutually exclusive."
)
if length:
self.headers['Content-Length'] = builtin_str(length)
self.headers["Content-Length"] = builtin_str(length)
else:
self.headers['Transfer-Encoding'] = 'chunked'
self.headers["Transfer-Encoding"] = "chunked"
else:
# Multi-part file uploads.
if files:
@@ -505,16 +556,16 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
else:
if data:
body = self._encode_params(data)
if isinstance(data, basestring) or hasattr(data, 'read'):
if isinstance(data, basestring) or hasattr(data, "read"):
content_type = None
else:
content_type = 'application/x-www-form-urlencoded'
content_type = "application/x-www-form-urlencoded"
self.prepare_content_length(body)
# Add content-type if it wasn't explicitly provided.
if content_type and ('content-type' not in self.headers):
self.headers['Content-Type'] = content_type
if content_type and ("content-type" not in self.headers):
self.headers["Content-Type"] = content_type
self.body = body
@@ -525,13 +576,16 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
if length:
# If length exists, set it. Otherwise, we fallback
# to Transfer-Encoding: chunked.
self.headers['Content-Length'] = builtin_str(length)
elif self.method not in ('GET', 'HEAD') and self.headers.get('Content-Length') is None:
self.headers["Content-Length"] = builtin_str(length)
elif (
self.method not in ("GET", "HEAD")
and self.headers.get("Content-Length") is None
):
# Set Content-Length to 0 for methods that can have a body
# but don't provide one. (i.e. not GET or HEAD)
self.headers['Content-Length'] = '0'
self.headers["Content-Length"] = "0"
def prepare_auth(self, auth, url=''):
def prepare_auth(self, auth, url=""):
"""Prepares the given HTTP auth data."""
# If no Auth is explicitly provided, extract it from the URL first.
@@ -571,7 +625,7 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
cookie_header = get_cookie_header(self._cookies, self)
if cookie_header is not None:
self.headers['Cookie'] = cookie_header
self.headers["Cookie"] = cookie_header
def prepare_hooks(self, hooks):
"""Prepares the given hooks."""
@@ -583,14 +637,22 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
self.register_hook(event, hooks[event])
class Response(object):
class Response:
"""The :class:`Response <Response>` object, which contains a
server's response to an HTTP request.
"""
__attrs__ = [
'_content', 'status_code', 'headers', 'url', 'history',
'encoding', 'reason', 'cookies', 'elapsed', 'request'
"_content",
"status_code",
"headers",
"url",
"history",
"encoding",
"reason",
"cookies",
"elapsed",
"request",
]
def __init__(self):
@@ -608,7 +670,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.
@@ -659,11 +721,11 @@ class Response(object):
setattr(self, name, value)
# pickled objects do not have .raw
setattr(self, '_content_consumed', True)
setattr(self, 'raw', None)
setattr(self, "_content_consumed", True)
setattr(self, "raw", None)
def __repr__(self):
return '<Response [%s]>' % (self.status_code)
return f"<Response [{self.status_code}]>"
def __bool__(self):
"""Returns True if :attr:`status_code` is less than 400.
@@ -709,12 +771,15 @@ class Response(object):
"""True if this Response is a well-formed HTTP redirect that could have
been processed automatically (by :meth:`Session.resolve_redirects`).
"""
return ('location' in self.headers and self.status_code in REDIRECT_STATI)
return "location" in self.headers and self.status_code in REDIRECT_STATI
@property
def is_permanent_redirect(self):
"""True if this Response one of the permanent versions of redirect."""
return ('location' in self.headers and self.status_code in (codes.moved_permanently, codes.permanent_redirect))
return "location" in self.headers and self.status_code in (
codes.moved_permanently,
codes.permanent_redirect,
)
@property
def next(self):
@@ -723,8 +788,13 @@ class Response(object):
@property
def apparent_encoding(self):
"""The apparent encoding, provided by the chardet library."""
return chardet.detect(self.content)['encoding']
"""The apparent encoding, provided by the charset_normalizer or chardet libraries."""
if chardet is not None:
return chardet.detect(self.content)["encoding"]
else:
# If no character detection library is available, we'll fall back
# to a standard Python utf-8 str.
return "utf-8"
def iter_content(self, chunk_size=1, decode_unicode=False):
"""Iterates over the response data. When stream=True is set on the
@@ -745,16 +815,17 @@ class Response(object):
def generate():
# Special case for urllib3.
if hasattr(self.raw, 'stream'):
if hasattr(self.raw, "stream"):
try:
for chunk in self.raw.stream(chunk_size, decode_content=True):
yield chunk
yield from self.raw.stream(chunk_size, decode_content=True)
except ProtocolError as e:
raise ChunkedEncodingError(e)
except DecodeError as e:
raise ContentDecodingError(e)
except ReadTimeoutError as e:
raise ConnectionError(e)
except SSLError as e:
raise RequestsSSLError(e)
else:
# Standard file-like object.
while True:
@@ -768,7 +839,9 @@ class Response(object):
if self._content_consumed and isinstance(self._content, bool):
raise StreamConsumedError()
elif chunk_size is not None and not isinstance(chunk_size, int):
raise TypeError("chunk_size must be an int, it is instead a %s." % type(chunk_size))
raise TypeError(
f"chunk_size must be an int, it is instead a {type(chunk_size)}."
)
# simulate reading small chunks of the content
reused_chunks = iter_slices(self._content, chunk_size)
@@ -781,7 +854,9 @@ class Response(object):
return chunks
def iter_lines(self, chunk_size=ITER_CHUNK_SIZE, decode_unicode=False, 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.
@@ -791,8 +866,9 @@ class Response(object):
pending = None
for chunk in self.iter_content(chunk_size=chunk_size, decode_unicode=decode_unicode):
for chunk in self.iter_content(
chunk_size=chunk_size, decode_unicode=decode_unicode
):
if pending is not None:
chunk = pending + chunk
@@ -806,8 +882,7 @@ class Response(object):
else:
pending = None
for line in lines:
yield line
yield from lines
if pending is not None:
yield pending
@@ -819,13 +894,12 @@ class Response(object):
if self._content is False:
# Read the contents.
if self._content_consumed:
raise RuntimeError(
'The content for this response was already consumed')
raise RuntimeError("The content for this response was already consumed")
if self.status_code == 0 or self.raw is None:
self._content = None
else:
self._content = b''.join(self.iter_content(CONTENT_CHUNK_SIZE)) or b''
self._content = b"".join(self.iter_content(CONTENT_CHUNK_SIZE)) or b""
self._content_consumed = True
# don't need to release the connection; that's been handled by urllib3
@@ -837,7 +911,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
@@ -850,7 +924,7 @@ class Response(object):
encoding = self.encoding
if not self.content:
return str('')
return ""
# Fallback to auto-detected encoding.
if self.encoding is None:
@@ -858,7 +932,7 @@ class Response(object):
# Decode unicode from given encoding.
try:
content = str(self.content, encoding, errors='replace')
content = str(self.content, encoding, errors="replace")
except (LookupError, TypeError):
# A LookupError is raised if the encoding was not found which could
# indicate a misspelling or similar mistake.
@@ -866,75 +940,87 @@ class Response(object):
# A TypeError can be raised if encoding is None
#
# So we try blindly encoding.
content = str(self.content, errors='replace')
content = str(self.content, errors="replace")
return content
def json(self, **kwargs):
r"""Returns the json-encoded content of a response, if any.
r"""Decodes the JSON response body (if any) as a Python object.
This may return a dictionary, list, etc. depending on what is in the response.
:param \*\*kwargs: Optional arguments that ``json.loads`` takes.
:raises ValueError: If the response body does not contain valid json.
:raises requests.exceptions.JSONDecodeError: If the response body does not
contain valid json.
"""
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:
try:
return complexjson.loads(
self.content.decode(encoding), **kwargs
)
return complexjson.loads(self.content.decode(encoding), **kwargs)
except UnicodeDecodeError:
# Wrong UTF codec detected; usually because it's not UTF-8
# but some other 8-bit codec. This is an RFC violation,
# and the server didn't bother to tell us what codec *was*
# used.
pass
return complexjson.loads(self.text, **kwargs)
except JSONDecodeError as e:
raise RequestsJSONDecodeError(e.msg, e.doc, e.pos)
try:
return complexjson.loads(self.text, **kwargs)
except JSONDecodeError as e:
# Catch JSON-related errors and raise as requests.JSONDecodeError
# This aliases json.JSONDecodeError and simplejson.JSONDecodeError
raise RequestsJSONDecodeError(e.msg, e.doc, e.pos)
@property
def links(self):
"""Returns the parsed header links of the response, if any."""
header = self.headers.get('link')
header = self.headers.get("link")
# l = MultiDict()
l = {}
resolved_links = {}
if header:
links = parse_header_links(header)
for link in links:
key = link.get('rel') or link.get('url')
l[key] = link
key = link.get("rel") or link.get("url")
resolved_links[key] = link
return l
return resolved_links
def raise_for_status(self):
"""Raises stored :class:`HTTPError`, if one occurred."""
"""Raises :class:`HTTPError`, if one occurred."""
http_error_msg = ''
http_error_msg = ""
if isinstance(self.reason, bytes):
# We attempt to decode utf-8 first because some servers
# choose to localize their reason strings. If the string
# isn't utf-8, we fall back to iso-8859-1 for all other
# encodings. (See PR #3538)
try:
reason = self.reason.decode('utf-8')
reason = self.reason.decode("utf-8")
except UnicodeDecodeError:
reason = self.reason.decode('iso-8859-1')
reason = self.reason.decode("iso-8859-1")
else:
reason = self.reason
if 400 <= self.status_code < 500:
http_error_msg = u'%s Client Error: %s for url: %s' % (self.status_code, reason, self.url)
http_error_msg = (
f"{self.status_code} Client Error: {reason} for url: {self.url}"
)
elif 500 <= self.status_code < 600:
http_error_msg = u'%s Server Error: %s for url: %s' % (self.status_code, reason, self.url)
http_error_msg = (
f"{self.status_code} Server Error: {reason} for url: {self.url}"
)
if http_error_msg:
raise HTTPError(http_error_msg, response=self)
@@ -948,6 +1034,6 @@ class Response(object):
if not self._content_consumed:
self.raw.close()
release_conn = getattr(self.raw, 'release_conn', None)
release_conn = getattr(self.raw, "release_conn", None)
if release_conn is not None:
release_conn()

23
src/requests/packages.py Normal file
View File

@@ -0,0 +1,23 @@
import sys
from .compat import chardet
# This code exists for backwards compatibility reasons.
# I don't like it either. Just look the other way. :)
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.*)
for mod in list(sys.modules):
if mod == package or mod.startswith(f"{package}."):
sys.modules[f"requests.packages.{mod}"] = sys.modules[mod]
if chardet is not None:
target = chardet.__name__
for mod in list(sys.modules):
if mod == target or mod.startswith(f"{target}."):
imported_mod = sys.modules[mod]
sys.modules[f"requests.packages.{mod}"] = imported_mod
mod = mod.replace(target, "chardet")
sys.modules[f"requests.packages.{mod}"] = imported_mod

View File

@@ -1,8 +1,6 @@
# -*- coding: utf-8 -*-
"""
requests.session
~~~~~~~~~~~~~~~~
requests.sessions
~~~~~~~~~~~~~~~~~
This module provides a Session object to manage and persist settings across
requests (cookies, auth, proxies).
@@ -10,38 +8,52 @@ requests (cookies, auth, proxies).
import os
import sys
import time
from collections import OrderedDict
from datetime import timedelta
from .auth import _basic_auth_str
from .compat import cookielib, is_py3, OrderedDict, urljoin, urlparse, Mapping
from .cookies import (
cookiejar_from_dict, extract_cookies_to_jar, RequestsCookieJar, merge_cookies)
from .models import Request, PreparedRequest, DEFAULT_REDIRECT_LIMIT
from .hooks import default_hooks, dispatch_hook
from ._internal_utils import to_native_string
from .utils import to_key_val_list, default_headers, DEFAULT_PORTS
from .exceptions import (
TooManyRedirects, InvalidSchema, ChunkedEncodingError, ContentDecodingError)
from .structures import CaseInsensitiveDict
from .adapters import HTTPAdapter
from .utils import (
requote_uri, get_environ_proxies, get_netrc_auth, should_bypass_proxies,
get_auth_from_url, rewind_body
from .auth import _basic_auth_str
from .compat import Mapping, cookielib, urljoin, urlparse
from .cookies import (
RequestsCookieJar,
cookiejar_from_dict,
extract_cookies_to_jar,
merge_cookies,
)
from .status_codes import codes
from .exceptions import (
ChunkedEncodingError,
ContentDecodingError,
InvalidSchema,
TooManyRedirects,
)
from .hooks import default_hooks, dispatch_hook
# formerly defined here, reexposed here for backward compatibility
from .models import REDIRECT_STATI
from .models import ( # noqa: F401
DEFAULT_REDIRECT_LIMIT,
REDIRECT_STATI,
PreparedRequest,
Request,
)
from .status_codes import codes
from .structures import CaseInsensitiveDict
from .utils import ( # noqa: F401
DEFAULT_PORTS,
default_headers,
get_auth_from_url,
get_environ_proxies,
get_netrc_auth,
requote_uri,
resolve_proxies,
rewind_body,
should_bypass_proxies,
to_key_val_list,
)
# Preferred clock, based on which one is more accurate on a given system.
if sys.platform == 'win32':
try: # Python 3.4+
preferred_clock = time.perf_counter
except AttributeError: # Earlier than Python 3.
preferred_clock = time.clock
if sys.platform == "win32":
preferred_clock = time.perf_counter
else:
preferred_clock = time.time
@@ -60,8 +72,7 @@ def merge_setting(request_setting, session_setting, dict_class=OrderedDict):
# Bypass if not a dictionary (e.g. verify)
if not (
isinstance(session_setting, Mapping) and
isinstance(request_setting, Mapping)
isinstance(session_setting, Mapping) and isinstance(request_setting, Mapping)
):
return request_setting
@@ -83,17 +94,16 @@ def merge_hooks(request_hooks, session_hooks, dict_class=OrderedDict):
This is necessary because when request_hooks == {'response': []}, the
merge breaks Session hooks entirely.
"""
if session_hooks is None or session_hooks.get('response') == []:
if session_hooks is None or session_hooks.get("response") == []:
return request_hooks
if request_hooks is None or request_hooks.get('response') == []:
if request_hooks is None or request_hooks.get("response") == []:
return session_hooks
return merge_setting(request_hooks, session_hooks, dict_class)
class SessionRedirectMixin(object):
class SessionRedirectMixin:
def get_redirect_target(self, resp):
"""Receives a Response. Returns a redirect URI or ``None``"""
# Due to the nature of how requests processes redirects this method will
@@ -103,16 +113,15 @@ class SessionRedirectMixin(object):
# to cache the redirect location onto the response object as a private
# attribute.
if resp.is_redirect:
location = resp.headers['location']
location = resp.headers["location"]
# Currently the underlying http module on py3 decode headers
# in latin1, but empirical evidence suggests that latin1 is very
# rarely used with non-ASCII characters in HTTP headers.
# It is more likely to get UTF8 header rather than latin1.
# This causes incorrect handling of UTF8 encoded location headers.
# To solve this, we re-encode the location in latin1.
if is_py3:
location = location.encode('latin1')
return to_native_string(location, 'utf8')
location = location.encode("latin1")
return to_native_string(location, "utf8")
return None
def should_strip_auth(self, old_url, new_url):
@@ -125,23 +134,40 @@ class SessionRedirectMixin(object):
# ports. This isn't specified by RFC 7235, but is kept to avoid
# breaking backwards compatibility with older versions of requests
# that allowed any redirects on the same host.
if (old_parsed.scheme == 'http' and old_parsed.port in (80, None)
and new_parsed.scheme == 'https' and new_parsed.port in (443, None)):
if (
old_parsed.scheme == "http"
and old_parsed.port in (80, None)
and new_parsed.scheme == "https"
and new_parsed.port in (443, None)
):
return False
# Handle default port usage corresponding to scheme.
changed_port = old_parsed.port != new_parsed.port
changed_scheme = old_parsed.scheme != new_parsed.scheme
default_port = (DEFAULT_PORTS.get(old_parsed.scheme, None), None)
if (not changed_scheme and old_parsed.port in default_port
and new_parsed.port in default_port):
if (
not changed_scheme
and old_parsed.port in default_port
and new_parsed.port in default_port
):
return False
# Standard case: root URI must match
return changed_port or changed_scheme
def resolve_redirects(self, resp, req, stream=False, timeout=None,
verify=True, cert=None, proxies=None, yield_requests=False, **adapter_kwargs):
def resolve_redirects(
self,
resp,
req,
stream=False,
timeout=None,
verify=True,
cert=None,
proxies=None,
yield_requests=False,
**adapter_kwargs,
):
"""Receives a Response. Returns a generator of Responses or Requests."""
hist = [] # keep track of history
@@ -162,19 +188,21 @@ 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(
f"Exceeded {self.max_redirects} redirects.", response=resp
)
# Release the connection back into the pool.
resp.close()
# Handle redirection without scheme (see: RFC 1808 Section 4)
if url.startswith('//'):
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)
if parsed.fragment == '' and previous_fragment:
if parsed.fragment == "" and previous_fragment:
parsed = parsed._replace(fragment=previous_fragment)
elif parsed.fragment:
previous_fragment = parsed.fragment
@@ -192,19 +220,19 @@ class SessionRedirectMixin(object):
self.rebuild_method(prepared_request, resp)
# https://github.com/requests/requests/issues/1084
if resp.status_code not in (codes.temporary_redirect, codes.permanent_redirect):
# https://github.com/requests/requests/issues/3490
purged_headers = ('Content-Length', 'Content-Type', 'Transfer-Encoding')
# https://github.com/psf/requests/issues/1084
if resp.status_code not in (
codes.temporary_redirect,
codes.permanent_redirect,
):
# 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
@@ -220,9 +248,8 @@ class SessionRedirectMixin(object):
# A failed tell() sets `_body_position` to `object()`. This non-None
# value ensures `rewindable` will be True, allowing us to raise an
# UnrewindableBodyError, instead of hanging the connection.
rewindable = (
prepared_request._body_position is not None and
('Content-Length' in headers or 'Transfer-Encoding' in headers)
rewindable = prepared_request._body_position is not None and (
"Content-Length" in headers or "Transfer-Encoding" in headers
)
# Attempt to rewind consumed file-like object.
@@ -235,7 +262,6 @@ class SessionRedirectMixin(object):
if yield_requests:
yield req
else:
resp = self.send(
req,
stream=stream,
@@ -244,7 +270,7 @@ class SessionRedirectMixin(object):
cert=cert,
proxies=proxies,
allow_redirects=False,
**adapter_kwargs
**adapter_kwargs,
)
extract_cookies_to_jar(self.cookies, prepared_request, resp.raw)
@@ -261,18 +287,18 @@ class SessionRedirectMixin(object):
headers = prepared_request.headers
url = prepared_request.url
if 'Authorization' in headers and self.should_strip_auth(response.request.url, url):
if "Authorization" in headers and self.should_strip_auth(
response.request.url, url
):
# If we get redirected to a new host, we should strip out any
# authentication headers.
del headers['Authorization']
del headers["Authorization"]
# .netrc might have more auth for us on our new host.
new_auth = get_netrc_auth(url) if self.trust_env else None
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
environment variables. If we are redirected to a URL covered by
@@ -285,32 +311,22 @@ class SessionRedirectMixin(object):
:rtype: dict
"""
proxies = proxies if proxies is not None else {}
headers = prepared_request.headers
url = prepared_request.url
scheme = urlparse(url).scheme
new_proxies = proxies.copy()
no_proxy = proxies.get('no_proxy')
scheme = urlparse(prepared_request.url).scheme
new_proxies = resolve_proxies(prepared_request, proxies, self.trust_env)
bypass_proxy = should_bypass_proxies(url, no_proxy=no_proxy)
if self.trust_env and not bypass_proxy:
environ_proxies = get_environ_proxies(url, no_proxy=no_proxy)
proxy = environ_proxies.get(scheme, environ_proxies.get('all'))
if proxy:
new_proxies.setdefault(scheme, proxy)
if 'Proxy-Authorization' in headers:
del headers['Proxy-Authorization']
if "Proxy-Authorization" in headers:
del headers["Proxy-Authorization"]
try:
username, password = get_auth_from_url(new_proxies[scheme])
except KeyError:
username, password = None, None
if username and password:
headers['Proxy-Authorization'] = _basic_auth_str(username, password)
# urllib3 handles proxy authorization for us in the standard adapter.
# Avoid appending this to TLS tunneled requests where it may be leaked.
if not scheme.startswith("https") and username and password:
headers["Proxy-Authorization"] = _basic_auth_str(username, password)
return new_proxies
@@ -321,18 +337,18 @@ class SessionRedirectMixin(object):
method = prepared_request.method
# https://tools.ietf.org/html/rfc7231#section-6.4.4
if response.status_code == codes.see_other and method != 'HEAD':
method = 'GET'
if response.status_code == codes.see_other and method != "HEAD":
method = "GET"
# Do what the browsers do, despite standards...
# First, turn 302s into GETs.
if response.status_code == codes.found and method != 'HEAD':
method = 'GET'
if response.status_code == codes.found and method != "HEAD":
method = "GET"
# Second, if a POST is responded to with a 301, turn it into a GET.
# This bizarre behaviour is explained in Issue 1704.
if response.status_code == codes.moved and method == 'POST':
method = 'GET'
if response.status_code == codes.moved and method == "POST":
method = "GET"
prepared_request.method = method
@@ -352,18 +368,26 @@ 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',
'max_redirects',
"headers",
"cookies",
"auth",
"proxies",
"hooks",
"params",
"verify",
"cert",
"adapters",
"stream",
"trust_env",
"max_redirects",
]
def __init__(self):
#: A case-insensitive dictionary of headers to be sent on each
#: :class:`Request <Request>` sent from this
#: :class:`Session <Session>`.
@@ -390,6 +414,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
@@ -414,8 +445,8 @@ class Session(SessionRedirectMixin):
# Default connection adapters.
self.adapters = OrderedDict()
self.mount('https://', HTTPAdapter())
self.mount('http://', HTTPAdapter())
self.mount("https://", HTTPAdapter())
self.mount("http://", HTTPAdapter())
def __enter__(self):
return self
@@ -441,7 +472,8 @@ class Session(SessionRedirectMixin):
# Merge with session cookies
merged_cookies = merge_cookies(
merge_cookies(RequestsCookieJar(), self.cookies), cookies)
merge_cookies(RequestsCookieJar(), self.cookies), cookies
)
# Set environment's basic authentication if not explicitly set.
auth = request.auth
@@ -455,7 +487,9 @@ class Session(SessionRedirectMixin):
files=request.files,
data=request.data,
json=request.json,
headers=merge_setting(request.headers, self.headers, dict_class=CaseInsensitiveDict),
headers=merge_setting(
request.headers, self.headers, dict_class=CaseInsensitiveDict
),
params=merge_setting(request.params, self.params),
auth=merge_setting(auth, self.auth),
cookies=merged_cookies,
@@ -463,10 +497,25 @@ class Session(SessionRedirectMixin):
)
return p
def request(self, method, url,
params=None, data=None, headers=None, cookies=None, files=None,
auth=None, timeout=None, allow_redirects=True, proxies=None,
hooks=None, stream=None, verify=None, cert=None, json=None):
def request(
self,
method,
url,
params=None,
data=None,
headers=None,
cookies=None,
files=None,
auth=None,
timeout=None,
allow_redirects=True,
proxies=None,
hooks=None,
stream=None,
verify=None,
cert=None,
json=None,
):
"""Constructs a :class:`Request <Request>`, prepares it and sends it.
Returns :class:`Response <Response>` object.
@@ -486,7 +535,7 @@ class Session(SessionRedirectMixin):
for multipart encoding upload.
:param auth: (optional) Auth tuple or callable to enable
Basic/Digest/Custom HTTP Auth.
:param timeout: (optional) How long to wait for the server to send
:param timeout: (optional) How many seconds to wait for the server to send
data before giving up, as a float, or a :ref:`(connect timeout,
read timeout) <timeouts>` tuple.
:type timeout: float or tuple
@@ -494,11 +543,18 @@ class Session(SessionRedirectMixin):
:type allow_redirects: bool
:param proxies: (optional) Dictionary mapping protocol or protocol and
hostname to the URL of the proxy.
:param hooks: (optional) Dictionary mapping hook name to one event or
list of events, event must be callable.
:param stream: (optional) whether to immediately download the response
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
@@ -526,8 +582,8 @@ class Session(SessionRedirectMixin):
# Send the request.
send_kwargs = {
'timeout': timeout,
'allow_redirects': allow_redirects,
"timeout": timeout,
"allow_redirects": allow_redirects,
}
send_kwargs.update(settings)
resp = self.send(prep, **send_kwargs)
@@ -542,8 +598,8 @@ class Session(SessionRedirectMixin):
:rtype: requests.Response
"""
kwargs.setdefault('allow_redirects', True)
return self.request('GET', url, **kwargs)
kwargs.setdefault("allow_redirects", True)
return self.request("GET", url, **kwargs)
def options(self, url, **kwargs):
r"""Sends a OPTIONS request. Returns :class:`Response` object.
@@ -553,8 +609,8 @@ class Session(SessionRedirectMixin):
:rtype: requests.Response
"""
kwargs.setdefault('allow_redirects', True)
return self.request('OPTIONS', url, **kwargs)
kwargs.setdefault("allow_redirects", True)
return self.request("OPTIONS", url, **kwargs)
def head(self, url, **kwargs):
r"""Sends a HEAD request. Returns :class:`Response` object.
@@ -564,8 +620,8 @@ class Session(SessionRedirectMixin):
:rtype: requests.Response
"""
kwargs.setdefault('allow_redirects', False)
return self.request('HEAD', url, **kwargs)
kwargs.setdefault("allow_redirects", False)
return self.request("HEAD", url, **kwargs)
def post(self, url, data=None, json=None, **kwargs):
r"""Sends a POST request. Returns :class:`Response` object.
@@ -578,7 +634,7 @@ class Session(SessionRedirectMixin):
:rtype: requests.Response
"""
return self.request('POST', url, data=data, json=json, **kwargs)
return self.request("POST", url, data=data, json=json, **kwargs)
def put(self, url, data=None, **kwargs):
r"""Sends a PUT request. Returns :class:`Response` object.
@@ -590,7 +646,7 @@ class Session(SessionRedirectMixin):
:rtype: requests.Response
"""
return self.request('PUT', url, data=data, **kwargs)
return self.request("PUT", url, data=data, **kwargs)
def patch(self, url, data=None, **kwargs):
r"""Sends a PATCH request. Returns :class:`Response` object.
@@ -602,7 +658,7 @@ class Session(SessionRedirectMixin):
:rtype: requests.Response
"""
return self.request('PATCH', url, data=data, **kwargs)
return self.request("PATCH", url, data=data, **kwargs)
def delete(self, url, **kwargs):
r"""Sends a DELETE request. Returns :class:`Response` object.
@@ -612,7 +668,7 @@ class Session(SessionRedirectMixin):
:rtype: requests.Response
"""
return self.request('DELETE', url, **kwargs)
return self.request("DELETE", url, **kwargs)
def send(self, request, **kwargs):
"""Send a given PreparedRequest.
@@ -621,19 +677,20 @@ class Session(SessionRedirectMixin):
"""
# Set defaults that the hooks can utilize to ensure they always have
# the correct parameters to reproduce the previous request.
kwargs.setdefault('stream', self.stream)
kwargs.setdefault('verify', self.verify)
kwargs.setdefault('cert', self.cert)
kwargs.setdefault('proxies', self.proxies)
kwargs.setdefault("stream", self.stream)
kwargs.setdefault("verify", self.verify)
kwargs.setdefault("cert", self.cert)
if "proxies" not in kwargs:
kwargs["proxies"] = resolve_proxies(request, self.proxies, self.trust_env)
# It's possible that users might accidentally send a Request object.
# Guard against that specific failure case.
if isinstance(request, Request):
raise ValueError('You can only send PreparedRequests.')
raise ValueError("You can only send PreparedRequests.")
# Set up variables needed for resolve_redirects and dispatching of hooks
allow_redirects = kwargs.pop('allow_redirects', True)
stream = kwargs.get('stream')
allow_redirects = kwargs.pop("allow_redirects", True)
stream = kwargs.get("stream")
hooks = request.hooks
# Get the appropriate adapter to use
@@ -650,22 +707,23 @@ class Session(SessionRedirectMixin):
r.elapsed = timedelta(seconds=elapsed)
# Response manipulation hooks
r = dispatch_hook('response', hooks, r, **kwargs)
r = dispatch_hook("response", hooks, r, **kwargs)
# Persist cookies
if r.history:
# If the hooks create history then we want those cookies too
for resp in r.history:
extract_cookies_to_jar(self.cookies, resp.request, resp.raw)
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:
@@ -678,7 +736,9 @@ class Session(SessionRedirectMixin):
# If redirects aren't being followed, store the response on the Request for Response.next().
if not allow_redirects:
try:
r._next = next(self.resolve_redirects(r, request, yield_requests=True, **kwargs))
r._next = next(
self.resolve_redirects(r, request, yield_requests=True, **kwargs)
)
except StopIteration:
pass
@@ -696,16 +756,19 @@ class Session(SessionRedirectMixin):
# Gather clues from the surrounding environment.
if self.trust_env:
# Set environment's proxies.
no_proxy = proxies.get('no_proxy') if proxies is not None else None
no_proxy = proxies.get("no_proxy") if proxies is not None else None
env_proxies = get_environ_proxies(url, no_proxy=no_proxy)
for (k, v) in env_proxies.items():
for k, v in env_proxies.items():
proxies.setdefault(k, v)
# Look for requests environment configuration and be compatible
# with cURL.
# Look for requests environment configuration
# and be compatible with cURL.
if verify is True or verify is None:
verify = (os.environ.get('REQUESTS_CA_BUNDLE') or
os.environ.get('CURL_CA_BUNDLE'))
verify = (
os.environ.get("REQUESTS_CA_BUNDLE")
or os.environ.get("CURL_CA_BUNDLE")
or verify
)
# Merge all the kwargs.
proxies = merge_setting(proxies, self.proxies)
@@ -713,8 +776,7 @@ class Session(SessionRedirectMixin):
verify = merge_setting(verify, self.verify)
cert = merge_setting(cert, self.cert)
return {'verify': verify, 'proxies': proxies, 'stream': stream,
'cert': cert}
return {"proxies": proxies, "stream": stream, "verify": verify, "cert": cert}
def get_adapter(self, url):
"""
@@ -722,13 +784,12 @@ class Session(SessionRedirectMixin):
:rtype: requests.adapters.BaseAdapter
"""
for (prefix, adapter) in self.adapters.items():
for prefix, adapter in self.adapters.items():
if url.lower().startswith(prefix.lower()):
return adapter
# Nothing matches :-/
raise InvalidSchema("No connection adapters were found for '%s'" % url)
raise InvalidSchema(f"No connection adapters were found for {url!r}")
def close(self):
"""Closes all adapters and as such the session"""

View File

@@ -0,0 +1,128 @@
r"""
The ``codes`` object defines a mapping from common names for HTTP statuses
to their numerical codes, accessible either as attributes or as dictionary
items.
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
``codes.okay`` all correspond to the HTTP status code 200.
"""
from .structures import LookupDict
_codes = {
# Informational.
100: ("continue",),
101: ("switching_protocols",),
102: ("processing", "early-hints"),
103: ("checkpoint",),
122: ("uri_too_long", "request_uri_too_long"),
200: ("ok", "okay", "all_ok", "all_okay", "all_good", "\\o/", ""),
201: ("created",),
202: ("accepted",),
203: ("non_authoritative_info", "non_authoritative_information"),
204: ("no_content",),
205: ("reset_content", "reset"),
206: ("partial_content", "partial"),
207: ("multi_status", "multiple_status", "multi_stati", "multiple_stati"),
208: ("already_reported",),
226: ("im_used",),
# Redirection.
300: ("multiple_choices",),
301: ("moved_permanently", "moved", "\\o-"),
302: ("found",),
303: ("see_other", "other"),
304: ("not_modified",),
305: ("use_proxy",),
306: ("switch_proxy",),
307: ("temporary_redirect", "temporary_moved", "temporary"),
308: (
"permanent_redirect",
"resume_incomplete",
"resume",
), # "resume" and "resume_incomplete" to be removed in 3.0
# Client Error.
400: ("bad_request", "bad"),
401: ("unauthorized",),
402: ("payment_required", "payment"),
403: ("forbidden",),
404: ("not_found", "-o-"),
405: ("method_not_allowed", "not_allowed"),
406: ("not_acceptable",),
407: ("proxy_authentication_required", "proxy_auth", "proxy_authentication"),
408: ("request_timeout", "timeout"),
409: ("conflict",),
410: ("gone",),
411: ("length_required",),
412: ("precondition_failed", "precondition"),
413: ("request_entity_too_large", "content_too_large"),
414: ("request_uri_too_large", "uri_too_long"),
415: ("unsupported_media_type", "unsupported_media", "media_type"),
416: (
"requested_range_not_satisfiable",
"requested_range",
"range_not_satisfiable",
),
417: ("expectation_failed",),
418: ("im_a_teapot", "teapot", "i_am_a_teapot"),
421: ("misdirected_request",),
422: ("unprocessable_entity", "unprocessable", "unprocessable_content"),
423: ("locked",),
424: ("failed_dependency", "dependency"),
425: ("unordered_collection", "unordered", "too_early"),
426: ("upgrade_required", "upgrade"),
428: ("precondition_required", "precondition"),
429: ("too_many_requests", "too_many"),
431: ("header_fields_too_large", "fields_too_large"),
444: ("no_response", "none"),
449: ("retry_with", "retry"),
450: ("blocked_by_windows_parental_controls", "parental_controls"),
451: ("unavailable_for_legal_reasons", "legal_reasons"),
499: ("client_closed_request",),
# Server Error.
500: ("internal_server_error", "server_error", "/o\\", ""),
501: ("not_implemented",),
502: ("bad_gateway",),
503: ("service_unavailable", "unavailable"),
504: ("gateway_timeout",),
505: ("http_version_not_supported", "http_version"),
506: ("variant_also_negotiates",),
507: ("insufficient_storage",),
509: ("bandwidth_limit_exceeded", "bandwidth"),
510: ("not_extended",),
511: ("network_authentication_required", "network_auth", "network_authentication"),
}
codes = LookupDict(name="status_codes")
def _init():
for code, titles in _codes.items():
for title in titles:
setattr(codes, title, code)
if not title.startswith(("\\", "/")):
setattr(codes, title.upper(), code)
def doc(code):
names = ", ".join(f"``{n}``" for n in _codes[code])
return "* %d: %s" % (code, names)
global __doc__
__doc__ = (
__doc__ + "\n" + "\n".join(doc(code) for code in sorted(_codes))
if __doc__ is not None
else None
)
_init()

View File

@@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
"""
requests.structures
~~~~~~~~~~~~~~~~~~~
@@ -7,7 +5,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):
@@ -62,11 +62,7 @@ class CaseInsensitiveDict(MutableMapping):
def lower_items(self):
"""Like iteritems(), but with all lowercase keys."""
return (
(lowerkey, keyval[1])
for (lowerkey, keyval)
in self._store.items()
)
return ((lowerkey, keyval[1]) for (lowerkey, keyval) in self._store.items())
def __eq__(self, other):
if isinstance(other, Mapping):
@@ -89,10 +85,10 @@ class LookupDict(dict):
def __init__(self, name=None):
self.name = name
super(LookupDict, self).__init__()
super().__init__()
def __repr__(self):
return '<lookup \'%s\'>' % (self.name)
return f"<lookup '{self.name}'>"
def __getitem__(self, key):
# We allow fall-through here, so values default to None

Some files were not shown because too many files have changed in this diff Show More