Skip to content

Commit

Permalink
Merge branch 'master' into support-https-proxies
Browse files Browse the repository at this point in the history
  • Loading branch information
karpetrosyan authored Sep 11, 2023
2 parents 580850d + adbcd0e commit 98ac759
Show file tree
Hide file tree
Showing 19 changed files with 55 additions and 45 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
- uses: "actions/checkout@v3"
- uses: "actions/setup-python@v4"
with:
python-version: 3.7
python-version: 3.8
- name: "Install dependencies"
run: "scripts/install"
- name: "Build package & docs"
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test-suite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:

strategy:
matrix:
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"]
python-version: ["3.8", "3.9", "3.10", "3.11"]

steps:
- uses: "actions/checkout@v3"
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

## Unreleased

### Removed

* Drop support for Python 3.7. (#2813)

### Added

* Support HTTPS proxies. (#2845)
* Change the type of `Extensions` from `Mapping[Str, Any]` to `MutableMapping[Str, Any]`. (#2803)
* Add `socket_options` argument to `httpx.HTTPTransport` and `httpx.AsyncHTTPTransport` classes. (#2716)
* The `Response.raise_for_status()` method now returns the response instance. For example: `data = httpx.get('...').raise_for_status().json()`. (#2776)

### Fixed

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ Or, to include the optional HTTP/2 support, use:
$ pip install httpx[http2]
```

HTTPX requires Python 3.7+.
HTTPX requires Python 3.8+.

## Documentation

Expand Down
2 changes: 1 addition & 1 deletion README_chinese.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ $ pip install httpx
$ pip install httpx[http2]
```

HTTPX 要求 Python 3.7+ 版本。
HTTPX 要求 Python 3.8+ 版本。

## 文档

Expand Down
2 changes: 1 addition & 1 deletion docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
* The amount of time elapsed between sending the request and calling `close()` on the corresponding response received for that request.
[total_seconds()](https://docs.python.org/3/library/datetime.html#datetime.timedelta.total_seconds) to correctly get
the total elapsed seconds.
* `def .raise_for_status()` - **None**
* `def .raise_for_status()` - **Response**
* `def .json()` - **Any**
* `def .read()` - **bytes**
* `def .iter_raw([chunk_size])` - **bytes iterator**
Expand Down
2 changes: 1 addition & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,6 @@ To include the optional brotli decoder support, use:
$ pip install httpx[brotli]
```

HTTPX requires Python 3.7+
HTTPX requires Python 3.8+

[sync-support]: https://github.com/encode/httpx/issues/572
2 changes: 1 addition & 1 deletion docs/logging.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ DEBUG [2023-03-16 14:36:21] httpcore - connection.close.started
DEBUG [2023-03-16 14:36:21] httpcore - connection.close.complete
```

Logging output includes information from both the high-level `httpx` logger, and the network-level `httpcore` logger, which can be configured seperately.
Logging output includes information from both the high-level `httpx` logger, and the network-level `httpcore` logger, which can be configured separately.

For handling more complex logging configurations you might want to use the dictionary configuration style...

Expand Down
9 changes: 8 additions & 1 deletion docs/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -288,12 +288,19 @@ httpx._exceptions.HTTPStatusError: 404 Client Error: Not Found for url: https://
For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/404
```

Any successful response codes will simply return `None` rather than raising an exception.
Any successful response codes will return the `Response` instance rather than raising an exception.

```pycon
>>> r.raise_for_status()
```

The method returns the response instance, allowing you to use it inline. For example:

```pycon
>>> r = httpx.get('...').raise_for_status()
>>> data = httpx.get('...').raise_for_status().json()
```

## Response Headers

The response headers are available as a dictionary-like interface.
Expand Down
2 changes: 1 addition & 1 deletion httpx/_compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
brotli = None

if sys.version_info >= (3, 10) or (
sys.version_info >= (3, 7) and ssl.OPENSSL_VERSION_INFO >= (1, 1, 0, 7)
sys.version_info >= (3, 8) and ssl.OPENSSL_VERSION_INFO >= (1, 1, 0, 7)
):

def set_minimum_tls_version_1_2(context: ssl.SSLContext) -> None:
Expand Down
6 changes: 3 additions & 3 deletions httpx/_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,7 @@ def __init__(
# the client will set `response.next_request`.
self.next_request: typing.Optional[Request] = None

self.extensions = {} if extensions is None else extensions
self.extensions: ResponseExtensions = {} if extensions is None else extensions
self.history = [] if history is None else list(history)

self.is_closed = False
Expand Down Expand Up @@ -711,7 +711,7 @@ def has_redirect_location(self) -> bool:
and "Location" in self.headers
)

def raise_for_status(self) -> None:
def raise_for_status(self) -> "Response":
"""
Raise the `HTTPStatusError` if one occurred.
"""
Expand All @@ -723,7 +723,7 @@ def raise_for_status(self) -> None:
)

if self.is_success:
return
return self

if self.has_redirect_location:
message = (
Expand Down
5 changes: 3 additions & 2 deletions httpx/_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
Iterator,
List,
Mapping,
MutableMapping,
NamedTuple,
Optional,
Sequence,
Expand Down Expand Up @@ -87,7 +88,7 @@

RequestContent = Union[str, bytes, Iterable[bytes], AsyncIterable[bytes]]
ResponseContent = Union[str, bytes, Iterable[bytes], AsyncIterable[bytes]]
ResponseExtensions = Mapping[str, Any]
ResponseExtensions = MutableMapping[str, Any]

RequestData = Mapping[str, Any]

Expand All @@ -104,7 +105,7 @@
]
RequestFiles = Union[Mapping[str, FileTypes], Sequence[Tuple[str, FileTypes]]]

RequestExtensions = Mapping[str, Any]
RequestExtensions = MutableMapping[str, Any]


class SyncByteStream:
Expand Down
3 changes: 1 addition & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ build-backend = "hatchling.build"
name = "httpx"
description = "The next generation HTTP client."
license = "BSD-3-Clause"
requires-python = ">=3.7"
requires-python = ">=3.8"
authors = [
{ name = "Tom Christie", email = "tom@tomchristie.com" },
]
Expand All @@ -20,7 +20,6 @@ classifiers = [
"Operating System :: OS Independent",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
Expand Down
20 changes: 10 additions & 10 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,27 @@

# Optional charset auto-detection
# Used in our test cases
chardet==5.1.0
chardet==5.2.0
types-chardet==5.0.4.5

# Documentation
mkdocs==1.4.3
mkdocs==1.5.2
mkautodoc==0.2.0
mkdocs-material==9.1.17
mkdocs-material==9.2.6

# Packaging
build==0.10.0
twine==4.0.2

# Tests & Linting
black==23.3.0
coverage[toml]==7.2.7
cryptography==41.0.2
mypy==1.4.1
black==23.7.0
coverage[toml]==7.3.0
cryptography==41.0.3
mypy==1.5.1
types-certifi==2021.10.8.2
pytest==7.4.0
ruff==0.0.275
trio==0.22.0
ruff==0.0.286
trio==0.22.2
trio-typing==0.8.0
trustme==1.0.0
trustme==1.1.0
uvicorn==0.22.0
2 changes: 1 addition & 1 deletion scripts/check
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ export SOURCE_FILES="httpx tests"
set -x

./scripts/sync-version
${PREFIX}black --check --diff --target-version=py37 $SOURCE_FILES
${PREFIX}black --check --diff $SOURCE_FILES
${PREFIX}mypy $SOURCE_FILES
${PREFIX}ruff check $SOURCE_FILES
4 changes: 2 additions & 2 deletions scripts/lint
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
#!/bin/sh -e

export PREFIX=""
if [ -d 'venv' ] ; then
if [ -d 'venv' ]; then
export PREFIX="venv/bin/"
fi
export SOURCE_FILES="httpx tests"

set -x

${PREFIX}ruff --fix $SOURCE_FILES
${PREFIX}black --target-version=py37 $SOURCE_FILES
${PREFIX}black $SOURCE_FILES
2 changes: 1 addition & 1 deletion tests/client/test_async_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ async def test_raise_for_status(server):
response.raise_for_status()
assert exc_info.value.response == response
else:
assert response.raise_for_status() is None # type: ignore
assert response.raise_for_status() is response


@pytest.mark.anyio
Expand Down
2 changes: 1 addition & 1 deletion tests/client/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ def test_raise_for_status(server):
assert exc_info.value.response == response
assert exc_info.value.request.url.path == f"/status/{status_code}"
else:
assert response.raise_for_status() is None # type: ignore
assert response.raise_for_status() is response


def test_options(server):
Expand Down
25 changes: 11 additions & 14 deletions tests/test_config.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import os
import ssl
import sys
from pathlib import Path

import certifi
Expand Down Expand Up @@ -176,28 +175,26 @@ def test_timeout_repr():
not hasattr(ssl.SSLContext, "keylog_filename"),
reason="requires OpenSSL 1.1.1 or higher",
)
@pytest.mark.skipif(sys.version_info < (3, 8), reason="requires python3.8 or higher")
def test_ssl_config_support_for_keylog_file(tmpdir, monkeypatch): # pragma: no cover
if sys.version_info > (3, 8):
with monkeypatch.context() as m:
m.delenv("SSLKEYLOGFILE", raising=False)
with monkeypatch.context() as m:
m.delenv("SSLKEYLOGFILE", raising=False)

context = httpx.create_ssl_context(trust_env=True)
context = httpx.create_ssl_context(trust_env=True)

assert context.keylog_filename is None
assert context.keylog_filename is None

filename = str(tmpdir.join("test.log"))
filename = str(tmpdir.join("test.log"))

with monkeypatch.context() as m:
m.setenv("SSLKEYLOGFILE", filename)
with monkeypatch.context() as m:
m.setenv("SSLKEYLOGFILE", filename)

context = httpx.create_ssl_context(trust_env=True)
context = httpx.create_ssl_context(trust_env=True)

assert context.keylog_filename == filename
assert context.keylog_filename == filename

context = httpx.create_ssl_context(trust_env=False)
context = httpx.create_ssl_context(trust_env=False)

assert context.keylog_filename is None
assert context.keylog_filename is None


def test_proxy_from_url():
Expand Down

0 comments on commit 98ac759

Please sign in to comment.