Compare commits

...

15 Commits

Author SHA1 Message Date
Tom Christie
7c10773193
Merge branch 'master' into async-dependencies-optional 2024-09-27 17:07:44 +01:00
Tom Christie
85886d7d43
Update README.md 2024-09-27 17:05:51 +01:00
Tom Christie
6a4ea7a1fe
Update README.md 2024-09-27 17:04:54 +01:00
Tom Christie
4e58ae69e9
Merge branch 'master' into async-dependencies-optional 2024-09-27 13:00:30 +01:00
Tom Christie
3ebb3a5b9b
Update docs/http2.md
Co-authored-by: T-256 <132141463+T-256@users.noreply.github.com>
2024-09-27 09:48:50 +01:00
Tom Christie
88d9324081
Update docs/async.md
Co-authored-by: Zanie Blue <contact@zanie.dev>
2024-01-15 16:57:22 +00:00
Tom Christie
0e34e2ce25
Merge branch 'master' into async-dependencies-optional 2024-01-11 13:02:27 +00:00
Tom Christie
aa9ca07104
Merge branch 'master' into async-dependencies-optional 2024-01-08 14:12:29 +00:00
Tom Christie
9b36a208b3
Update httpx/_transports/default.py 2023-12-28 20:35:16 +00:00
Tom Christie
3741513647
Merge branch 'master' into async-dependencies-optional 2023-12-28 14:21:57 +00:00
Kar Petrosyan
e4e8fb2d71
Merge branch 'master' into async-dependencies-optional 2023-10-25 06:31:19 -04:00
Tom Christie
56b2fb0533
Update README.md
Co-authored-by: T-256 <132141463+T-256@users.noreply.github.com>
2023-10-12 10:42:02 +01:00
Tom Christie
40aa60c2c6
Merge branch 'master' into async-dependencies-optional 2023-10-10 13:43:40 +01:00
Tom Christie
f4dd500f0e Fix dependency formatting 2023-09-20 10:10:12 +01:00
Tom Christie
0dd72fce4a Make async dependencies optional. 2023-09-20 09:46:39 +01:00
8 changed files with 54 additions and 34 deletions

View File

@ -97,10 +97,12 @@ Install with pip:
$ pip install httpx
```
Or, to include the optional HTTP/2 support, use:
There are also a number of optional dependancies.
For example to include asyncio and HTTP/2 support, use:
```shell
$ pip install httpx[http2]
$ pip install 'httpx[asyncio,http2]'
```
HTTPX requires Python 3.8+.
@ -129,15 +131,17 @@ The HTTPX project relies on these excellent libraries:
* `h11` - HTTP/1.1 support.
* `certifi` - SSL certificates.
* `idna` - Internationalized domain name support.
* `sniffio` - Async library autodetection.
As well as these optional installs:
* `h2` - HTTP/2 support. *(Optional, with `httpx[http2]`)*
* `socksio` - SOCKS proxy support. *(Optional, with `httpx[socks]`)*
* `rich` - Rich terminal support. *(Optional, with `httpx[cli]`)*
* `click` - Command line client support. *(Optional, with `httpx[cli]`)*
* `brotli` or `brotlicffi` - Decoding for "brotli" compressed responses. *(Optional, with `httpx[brotli]`)*
* `anyio` - Async support for `asyncio`. *(Optional, with `httpx['asyncio']`)*
* `trio` - Async support for `trio`. *(Optional, with `httpx['trio']`)*
* `h2` - HTTP/2 support. *(Optional, with `httpx['http2']`)*
* `socksio` - SOCKS proxy support. *(Optional, with `httpx['socks']`)*
* `click` - Command line client support. *(Optional, with `httpx['cli']`)*
* `rich` - Command line client support. *(Optional, with `httpx['cli']`)*
* `pygments` - Command line client support. *(Optional, with `httpx['cli']`)*
* `brotli` or `brotlicffi` - Decoding for "brotli" compressed responses. *(Optional, with `httpx['brotli']`)*
* `zstandard` - Decoding for "zstd" compressed responses. *(Optional, with `httpx[zstd]`)*
A huge amount of credit is due to `requests` for the API layout that

View File

@ -10,6 +10,24 @@ long-lived network connections such as WebSockets.
If you're working with an async web framework then you'll also want to use an
async client for sending outgoing HTTP requests.
## Enabling Async support
To enable async support you'll need to install some additional dependencies:
If you're using Python's [standard `asyncio` support](https://docs.python.org/3/library/asyncio.html) then:
```shell
$ pip install "httpx[asyncio]"
```
Or, if you're working with the [`trio` third party package](https://trio.readthedocs.io/en/stable/):
```shell
$ pip install httpx['trio']
```
We highly recommend `trio` for async support. The `trio` project [pioneered the principles of structured concurrency](https://en.wikipedia.org/wiki/Structured_concurrency), and has a more carefully constrained API against which to work from.
## Making Async requests
To make asynchronous requests, you'll need an `AsyncClient`.

View File

@ -28,7 +28,7 @@ trying out our HTTP/2 support. You can do so by first making sure to install
the optional HTTP/2 dependencies...
```shell
$ pip install httpx[http2]
$ pip install 'httpx[http2]'
```
And then instantiating a client with HTTP/2 support enabled:

View File

@ -2,8 +2,6 @@ from __future__ import annotations
import typing
import sniffio
from .._models import Request, Response
from .._types import AsyncByteStream
from .base import AsyncBaseTransport
@ -28,7 +26,9 @@ _ASGIApp = typing.Callable[
__all__ = ["ASGITransport"]
def create_event() -> Event:
def create_event() -> "Event":
import sniffio
if sniffio.current_async_library() == "trio":
import trio

View File

@ -277,6 +277,14 @@ class AsyncHTTPTransport(AsyncBaseTransport):
retries: int = 0,
socket_options: typing.Iterable[SOCKET_OPTION] | None = None,
) -> None:
try:
import sniffio # noqa: F401
except ImportError: # pragma: nocover
raise RuntimeError(
"Using httpx in async mode, but neither "
"httpx['asyncio'] or asyncio['trio'] is installed."
)
ssl_context = create_ssl_context(verify=verify, cert=cert, trust_env=trust_env)
proxy = Proxy(url=proxy) if isinstance(proxy, (str, URL)) else proxy

View File

@ -11,8 +11,6 @@ import typing
from pathlib import Path
from urllib.request import getproxies
import sniffio
from ._types import PrimitiveData
if typing.TYPE_CHECKING: # pragma: no cover
@ -291,29 +289,18 @@ def peek_filelike_length(stream: typing.Any) -> int | None:
class Timer:
async def _get_time(self) -> float:
library = sniffio.current_async_library()
if library == "trio":
import trio
return trio.current_time()
else:
import asyncio
return asyncio.get_event_loop().time()
def sync_start(self) -> None:
self.started = time.perf_counter()
async def async_start(self) -> None:
self.started = await self._get_time()
self.started = time.perf_counter()
def sync_elapsed(self) -> float:
now = time.perf_counter()
return now - self.started
async def async_elapsed(self) -> float:
now = await self._get_time()
now = time.perf_counter()
return now - self.started

View File

@ -29,10 +29,8 @@ classifiers = [
]
dependencies = [
"certifi",
"httpcore==1.*",
"anyio",
"httpcore>=1.0.0,<2.0.0",
"idna",
"sniffio",
]
dynamic = ["readme", "version"]
@ -47,10 +45,16 @@ cli = [
"rich>=10,<14",
]
http2 = [
"h2>=3,<5",
"httpcore[http2]",
]
socks = [
"socksio==1.*",
"httpcore[socks]",
]
asyncio = [
"httpcore[asyncio]"
]
trio = [
"httpcore[trio]"
]
zstd = [
"zstandard>=0.18.0",

View File

@ -2,7 +2,7 @@
# On the other hand, we're not pinning package dependencies, because our tests
# needs to pass with the latest version of the packages.
# Reference: https://github.com/encode/httpx/pull/1721#discussion_r661241588
-e .[brotli,cli,http2,socks,zstd]
-e .[asyncio,trio,brotli,cli,http2,socks,zstd]
# Optional charset auto-detection
# Used in our test cases
@ -24,6 +24,5 @@ mypy==1.11.2
pytest==8.3.2
ruff==0.6.3
trio==0.26.2
trio-typing==0.10.0
trustme==1.1.0
uvicorn==0.30.6