httpx
httpx claims to be:
The next generation HTTP client.
and to be more specific:
HTTPX is a fully featured HTTP client for Python 3, which provides sync and async APIs, and support for both HTTP/1.1 and HTTP/2.
and the features include:
HTTPX builds on the well-established usability of requests, and gives you:
-A broadly requests-compatible API.
-Standard synchronous interface, but with async support if you need it.
-HTTP/1.1 and HTTP/2 support.
-Ability to make requests directly to WSGI applications or ASGI applications.
-Strict timeouts everywhere.
-Fully type annotated.
-100% test coverage.
Fact check
pypi | pypi |
---|---|
version | 0.21.1 (as of 2021-12-23) |
source | github |
documentation | python-httpx.org |
minimum python ver | 3.6 |
Test drive environment
OS | Ubuntu 20.04.3 LTS (focal) |
---|---|
python | 3.9.5; [GCC 9.3.0] on linux |
pip | 21.3.1 |
Package dependencies (after pip install)
pip install httpx==0.21.1 && pip list
gives:
Package Version
------------------ ---------
anyio 3.4.0
certifi 2021.10.8
charset-normalizer 2.0.9
h11 0.12.0
httpcore 0.14.3
httpx 0.21.1
idna 3.3
pip 21.3.1
pkg_resources 0.0.0
rfc3986 1.5.0
setuptools 60.0.4
sniffio 1.2.0
Bonus: Enable the command line client
pip install httpx[cli]==0.21.1 && pip list
gives:
Package Version
------------------ ---------
anyio 3.4.0
certifi 2021.10.8
charset-normalizer 2.0.9
click 8.0.3
colorama 0.4.4
commonmark 0.9.1
h11 0.12.0
httpcore 0.14.3
httpx 0.21.1
idna 3.3
pip 21.3.1
pkg_resources 0.0.0
Pygments 2.10.0
rfc3986 1.5.0
rich 10.16.1
setuptools 60.0.4
sniffio 1.2.0
Test drive
Synchronous code:
# sync.py
import httpx
def main() -> None:
response = httpx.get("https://www.baidu.com")
if (code := response.status_code) != httpx.codes.OK:
print(f"status code: {code}")
exit(1)
print(f"content type: {response.headers['content-type']}")
print(f"text: {response.text[:50]}")
print("Goodbye ...")
if __name__ == "__main__":
main()
gives:
content type: text/html
text: <html>
<head>
<script>
location.replace(loca
Goodbye ...
Asynchronous alternative:
# async.py
import asyncio
import httpx
async def main() -> None:
async with httpx.AsyncClient() as client:
response = await client.get("https://www.baidu.com")
if (code := response.status_code) != httpx.codes.OK:
print(f"status code: {code}")
exit(1)
print(f"content type: {response.headers['content-type']}")
print(f"text: {response.text[:50]}")
print("Goodbye ...")
if __name__ == "__main__":
asyncio.run(main()) # This requires python 3.7+
also gives:
content type: text/html
text: <html>
<head>
<script>
location.replace(loca
Goodbye ...
which is expected.
Sending out HTTP requests:
# post.py
import asyncio
import httpx
async def main() -> None:
async with httpx.AsyncClient() as client:
response = await client.post(
"http://httpbin.org/anything",
json={"name": "Joe Bloggs"},
)
print(response.json()["json"])
print("Goodbye...")
if __name__ == "__main__":
asyncio.run(main()) # This requires python 3.7+
gives:
{'name': 'Joe Bloggs'}
Goodbye...
which represents the same API as requests
(link)
Sending out request using the CLI client:
httpx -m get http://httpbin.org/anything
gives:
HTTP/1.1 200 OK
Date: ****** GMT
Content-Type: application/json
Content-Length: 392
Connection: keep-alive
Server: gunicorn/19.9.0
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
{
"args": {},
"data": "",
"files": {},
"form": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Host": "httpbin.org",
"User-Agent": "python-httpx/0.21.1",
"X-Amzn-Trace-Id": "Root=******"
},
"json": null,
"method": "GET",
"origin": "******",
"url": "http://httpbin.org/anything"
}
This makes httpx
an alternative to httpie
's CLI client (http
/ https
).