Install using ...
$ pip install --pre httpx
$ pip install --pre ahttpx
First, start by importing httpx...
>>> import httpx
>>> import ahttpx
Now, let’s try to get a webpage.
>>> r = httpx.get('https://httpbin.org/get')
>>> r
<Response [200 OK]>
>>> r = await ahttpx.get('https://httpbin.org/get')
>>> r
<Response [200 OK]>
To make an HTTP POST request, including some content...
>>> form = httpx.Form({'key': 'value'})
>>> r = httpx.post('https://httpbin.org/post', content=form)
>>> form = httpx.Form({'key': 'value'})
>>> r = await ahttpx.post('https://httpbin.org/post', content=form)
Shortcut methods for PUT, PATCH, and DELETE requests follow the same style...
>>> r = httpx.put('https://httpbin.org/put', content=form)
>>> r = httpx.patch('https://httpbin.org/patch', content=form)
>>> r = httpx.delete('https://httpbin.org/delete')
>>> r = await ahttpx.put('https://httpbin.org/put', content=form)
>>> r = await ahttpx.patch('https://httpbin.org/patch', content=form)
>>> r = await ahttpx.delete('https://httpbin.org/delete')
To include URL query parameters in the request, construct a URL using the params keyword...
>>> params = {'key1': 'value1', 'key2': 'value2'}
>>> url = httpx.URL('https://httpbin.org/get', params=params)
>>> r = httpx.get(url)
>>> params = {'key1': 'value1', 'key2': 'value2'}
>>> url = ahttpx.URL('https://httpbin.org/get', params=params)
>>> r = await ahttpx.get(url)
You can also pass a list of items as a value...
>>> params = {'key1': 'value1', 'key2': ['value2', 'value3']}
>>> url = httpx.URL('https://httpbin.org/get', params=params)
>>> r = httpx.get(url)
>>> params = {'key1': 'value1', 'key2': ['value2', 'value3']}
>>> url = ahttpx.URL('https://httpbin.org/get', params=params)
>>> r = await ahttpx.get(url)
To include additional headers in the outgoing request, use the headers keyword argument...
>>> url = 'https://httpbin.org/headers'
>>> headers = {'User-Agent': 'my-app/0.0.1'}
>>> r = httpx.get(url, headers=headers)
>>> url = 'https://httpbin.org/headers'
>>> headers = {'User-Agent': 'my-app/0.0.1'}
>>> r = await ahttpx.get(url, headers=headers)
HTTPX will automatically handle decoding the response content into unicode text.
>>> r = httpx.get('https://www.example.org/')
>>> r.text
'<!doctype html>\n<html>\n<head>\n<title>Example Domain</title>...'
>>> r = await ahttpx.get('https://www.example.org/')
>>> r.text
'<!doctype html>\n<html>\n<head>\n<title>Example Domain</title>...'
The response content can also be accessed as bytes, for non-text responses.
>>> r.body
b'<!doctype html>\n<html>\n<head>\n<title>Example Domain</title>...'
>>> r.body
b'<!doctype html>\n<html>\n<head>\n<title>Example Domain</title>...'
Often Web API responses will be encoded as JSON.
>>> r = httpx.get('https://httpbin.org/get')
>>> r.json()
{'args': {}, 'headers': {'Host': 'httpbin.org', 'User-Agent': 'dev', 'X-Amzn-Trace-Id': 'Root=1-679814d5-0f3d46b26686f5013e117085'}, 'origen': '21.35.60.128', 'url': 'https://httpbin.org/get'}
>>> r = await ahttpx.get('https://httpbin.org/get')
>>> await r.json()
{'args': {}, 'headers': {'Host': 'httpbin.org', 'User-Agent': 'dev', 'X-Amzn-Trace-Id': 'Root=1-679814d5-0f3d46b26686f5013e117085'}, 'origen': '21.35.60.128', 'url': 'https://httpbin.org/get'}
Some types of HTTP requests, such as POST and PUT requests, can include data in the request body. One common way of including that is as form-encoded data, which is used for HTML forms.
>>> form = httpx.Form({'key1': 'value1', 'key2': 'value2'})
>>> r = httpx.post("https://httpbin.org/post", content=form)
>>> r.json()
{
...
"form": {
"key2": "value2",
"key1": "value1"
},
...
}
>>> form = ahttpx.Form({'key1': 'value1', 'key2': 'value2'})
>>> r = await ahttpx.post("https://httpbin.org/post", content=form)
>>> await r.json()
{
...
"form": {
"key2": "value2",
"key1": "value1"
},
...
}
Form encoded data can also include multiple values from a given key.
>>> form = httpx.Form({'key1': ['value1', 'value2']})
>>> r = httpx.post("https://httpbin.org/post", content=form)
>>> r.json()
{
...
"form": {
"key1": [
"value1",
"value2"
]
},
...
}
>>> form = ahttpx.Form({'key1': ['value1', 'value2']})
>>> r = await ahttpx.post("https://httpbin.org/post", content=form)
>>> await r.json()
{
...
"form": {
"key1": [
"value1",
"value2"
]
},
...
}
You can also upload files, using HTTP multipart encoding.
>>> files = httpx.Files({'upload': httpx.File('uploads/report.xls')})
>>> r = httpx.post("https://httpbin.org/post", content=files)
>>> r.json()
{
...
"files": {
"upload": "<... binary content ...>"
},
...
}
>>> files = ahttpx.Files({'upload': httpx.File('uploads/report.xls')})
>>> r = await ahttpx.post("https://httpbin.org/post", content=files)
>>> await r.json()
{
...
"files": {
"upload": "<... binary content ...>"
},
...
}
If you need to include non-file data fields in the multipart form, use the data=... parameter:
>>> form = {'message': 'Hello, world!'}
>>> files = {'upload': httpx.File('uploads/report.xls')}
>>> data = httpx.MultiPart(form=form, files=files)
>>> r = httpx.post("https://httpbin.org/post", content=data)
>>> r.json()
{
...
"files": {
"upload": "<... binary content ...>"
},
"form": {
"message": "Hello, world!",
},
...
}
>>> form = {'message': 'Hello, world!'}
>>> files = {'upload': httpx.File('uploads/report.xls')}
>>> data = ahttpx.MultiPart(form=form, files=files)
>>> r = await ahttpx.post("https://httpbin.org/post", content=data)
>>> await r.json()
{
...
"files": {
"upload": "<... binary content ...>"
},
"form": {
"message": "Hello, world!",
},
...
}
Form encoded data is okay if all you need is a simple key-value data structure. For more complicated data structures you'll often want to use JSON encoding instead.
>>> data = {'integer': 123, 'boolean': True, 'list': ['a', 'b', 'c']}
>>> r = httpx.post("https://httpbin.org/post", content=httpx.JSON(data))
>>> r.json()
{
...
"json": {
"boolean": true,
"integer": 123,
"list": [
"a",
"b",
"c"
]
},
...
}
>>> data = {'integer': 123, 'boolean': True, 'list': ['a', 'b', 'c']}
>>> r = await ahttpx.post("https://httpbin.org/post", content=httpx.JSON(data))
>>> await r.json()
{
...
"json": {
"boolean": true,
"integer": 123,
"list": [
"a",
"b",
"c"
]
},
...
}
For other encodings, you should use the content=... parameter, passing
either a bytes type or a generator that yields bytes.
>>> content = b'Hello, world'
>>> r = httpx.post("https://httpbin.org/post", content=content)
>>> content = b'Hello, world'
>>> r = await ahttpx.post("https://httpbin.org/post", content=content)
You may also want to set a custom Content-Type header when uploading
binary data.
We can inspect the HTTP status code of the response:
>>> r = httpx.get('https://httpbin.org/get')
>>> r.status_code
200
>>> r = await ahttpx.get('https://httpbin.org/get')
>>> r.status_code
200
The response headers are available as a dictionary-like interface.
>>> r.headers
<Headers {
'Content-Encoding': 'gzip',
'Connection': 'close',
'Server': 'nginx/1.0.4',
'ETag': 'e1ca502697e5c9317743dc078f67693f',
'Content-Type': 'application/json',
'Content-Length': 2126,
}>
>>> r.headers
<Headers {
'Content-Encoding': 'gzip',
'Connection': 'close',
'Server': 'nginx/1.0.4',
'ETag': 'e1ca502697e5c9317743dc078f67693f',
'Content-Type': 'application/json',
'Content-Length': 2126,
}>
The Headers data type is case-insensitive, so you can use any capitalization.
>>> r.headers.get('Content-Type')
'application/json'
>>> r.headers.get('content-type')
'application/json'
>>> r.headers.get('Content-Type')
'application/json'
>>> r.headers.get('content-type')
'application/json'
For large downloads you may want to use streaming responses that do not load the entire response body into memory at once.
You can stream the binary content of the response...
>>> with httpx.stream("GET", "https://www.example.com") as r:
... for data in r.stream:
... print(data)
>>> async with ahttpx.stream("GET", "https://www.example.com") as r:
... async for data in r.stream:
... print(data)