Quick start
First, import HTTPX:
>>> import httpx
Copy the code
Now, let’s try to get a web page.
>>> r = httpx.get('https://httpbin.org/get')
>>> r
<Response [200 OK]>
Copy the code
Also, make an HTTP POST request:
>>> r = httpx.post('https://httpbin.org/post', data={'key': 'value'})
Copy the code
PUT, DELETE, HEAD, and OPTIONS requests all follow the same style:
>>> r = httpx.put('https://httpbin.org/put', data={'key': 'value'})
>>> r = httpx.delete('https://httpbin.org/delete')
>>> r = httpx.head('https://httpbin.org/get')
>>> r = httpx.options('https://httpbin.org/get')
Copy the code
Pass parameters in the URL
To include URL query parameters in the request, use the params keyword:
>>> params = {'key1': 'value1'.'key2': 'value2'}
>>> r = httpx.get('https://httpbin.org/get', params=params)
Copy the code
To see how these values are encoded as URL strings, we can examine the resulting URL used to make the request:
>>> r.url
URL('https://httpbin.org/get?key2=value2&key1=value1'))Copy the code
You can also pass the list of items as values:
>>> params = {'key1': 'value1'.'key2': ['value2'.'value3']}
>>> r = httpx.get('https://httpbin.org/get', params=params)
>>> r.url
URL('https://httpbin.org/get?key1=value1&key2=value2&key2=value3')
Copy the code
Response content
HTTPX will automatically handle decoding the response content into Unicode text.
>>> r = httpx.get('https://www.example.org/')
>>> r.text
'
\n\n\nExample Domain ... '
Copy the code
You can check which encoding has been used to decode the response.
>>> r.encoding
'UTF-8'
Copy the code
If you need to override standard behavior and explicitly set the encoding to use, you can do so as well.
>>> r.encoding = 'ISO-8859-1'
Copy the code
Binary response content
For non-text responses, the response content can also be accessed in bytes:
>>> r.content
b'
\n\n\nExample Domain ... '
Copy the code
Any GZIP and deflateHTTP response encodings are automatically decoded for you. If Brotlipy is installed, brotli will also support response encoding.
For example, to create an image based on the binary data returned by the request, use the following code:
>>> from PIL import Image
>>> from io import BytesIO
>>> i = Image.open(BytesIO(r.content))
Copy the code
Returns the JSON response content
Typically, the Web API response will be encoded as JSON.
>>> r = httpx.get('https://api.github.com/events')
>>> r.json()
[{u'repository': {u'open_issues': 0, u'url': 'https://github.com/... '. }}]Copy the code
Custom Headers
To include additional headers in an outgoing request, use the HEADERS keyword argument:
>>> url = 'http://httpbin.org/headers'
>>> headers = {'user-agent': 'my - app / 0.0.1'}
>>> r = httpx.get(url, headers=headers)
Copy the code
Sending form data
Some types of HTTP requests, such as POST and PUT requests, can contain data in the request body. One common way to add is as form-encoded data for HTML forms.
>>> data = {'key1': 'value1'.'key2': 'value2'}
>>> r = httpx.post("https://httpbin.org/post", data=data)
>>> print(r.text)
{
...
"form": {
"key2": "value2"."key1": "value1"},... }Copy the code
Form-encoded data can also include multiple values for a given key.
>>> data = {'key1': ['value1'.'value2']}
>>> r = httpx.post("https://httpbin.org/post", data=data)
>>> print(r.text)
{
...
"form": {
"key1": [
"value1"."value2"]},... }Copy the code
Send segmented file uploads
You can also upload files using HTTP fragment encoding:
>>> files = {'upload-file': open('report.xls'.'rb')}
>>> r = httpx.post("https://httpbin.org/post", files=files)
>>> print(r.text)
{
...
"files": {
"upload-file": "<... binary content ... >"},... }Copy the code
You can also explicitly set the filename and content type by using item tuples as file values:
>>> files = {'upload-file': ('report.xls', open('report.xls'.'rb'), 'application/vnd.ms-excel')}
>>> r = httpx.post("https://httpbin.org/post", files=files)
>>> print(r.text)
{
...
"files": {
"upload-file": "<... binary content ... >"},... }Copy the code
Send JSON-encoded data
If you only need a simple key-value data structure, you can use form-encoded data. For more complex data structures, you usually need to switch to JSON encoding.
>>> data = {'integer': 123, 'boolean': True, 'list': ['a'.'b'.'c']}
>>> r = httpx.post("https://httpbin.org/post", json=data)
>>> print(r.text)
{
...
"json": {
"boolean": true."integer": 123,
"list": [
"a"."b"."c"]},... }Copy the code
Send binary request data
For other encodings, use the type bytesyield or generator bytes.
Content-type You may also need to set custom headers when uploading binary data.
Response status code
We can check the HTTP status code of the response:
>>> r = httpx.get('https://httpbin.org/get')
>>> r.status_code
200
Copy the code
HTTPX also includes a simple shortcut for accessing the status code through its text phrases.
>>> r.status_code == httpx.codes.OK
True
Copy the code
We can throw an exception for any client or server error response (4XX or 5XX status code) :
>>> not_found = httpx.get('https://httpbin.org/status/404')
>>> not_found.status_code
404
>>> not_found.raise_for_status()
Traceback (most recent call last):
File "/Users/tomchristie/GitHub/encode/httpcore/httpx/models.py", line 776, in raise_for_status
raise HttpError(message)
httpx.exceptions.HttpError: 404 Not Found
Copy the code
Any successful response code will simply return None rather than throw an exception.
>>> r.status_code == httpx.codes.OK
True
Copy the code
The response Headers
The response header can be used as a dictionary-like interface.
>>> r.headers
Headers({
'content-encoding': 'gzip'.'transfer-encoding': 'chunked'.'connection': 'close'.'server': 'nginx / 1.0.4'.'x-runtime': '148ms'.'etag': '"e1ca502697e5c9317743dc078f67693f"'.'content-type': 'application/json'
})
Copy the code
The Headers data type is case insensitive, so you can use any capital.
>>> r.headers['Content-Type']
'application/json'
>>> r.headers.get('content-type')
'application/json'
Copy the code
According to RFC 7230, multiple values of a single response headers are represented as a single comma-separated value:
The receiver can combine multiple header fields with the same field name into a pair of “Field name: Field value” without changing the semantics of the message by appending each subsequent field value sequentially to the combined field value, separated by the following delimiters. The comma.
Flow response
For large downloads, you may need to use a streaming response that does 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.iter_bytes():
... print(data)
Copy the code
Or respond to text…
>>> with httpx.stream("GET"."https://www.example.com") as r:
... for text in r.iter_text():
... print(text)
Copy the code
Or stream text line by line…
>>> with httpx.stream("GET"."https://www.example.com") as r:
... for line in r.iter_lines():
... print(line)
Copy the code
HTTPX will use the generic line end, normalizing all cases to \n.
In some cases, you might want to access the raw bytes on the response without applying any HTTP content decoding. In this case any content encoded by the Web server such as gZIP, Deflate or Brotli will not be automatically decoded.
>>> with httpx.stream("GET"."https://www.example.com") as r:
... for chunk in r.iter_raw():
... print(chunk)
Copy the code
If you use a streaming response in either of the above ways, the response.contentand response.text properties will not be available and will raise an error if accessed. However, you can also use the response flow feature to conditionally load the response body:
>>> with httpx.stream("GET"."https://www.example.com") as r:
... if r.headers['Content-Length'] < TOO_LONG:
... r.read()
... print(r.text)
Copy the code
Cookies
You can easily access any cookies set in the response:
>>> r = httpx.get('http://httpbin.org/cookies/set?chocolate=chip', allow_redirects=False)
>>> r.cookies['chocolate']
'chip'
Copy the code
To include cookies in outgoing requests, use the cookies parameter:
>>> cookies = {"peanut": "butter"}
>>> r = httpx.get('http://httpbin.org/cookies', cookies=cookies)
>>> r.json()
{'cookies': {'peanut': 'butter'}}
Copy the code
Cookies are returned in an instance of Cookies, a dict-like data structure with additional apis for accessing Cookies by their domain or path.
>>> cookies = httpx.Cookies()
>>> cookies.set('cookie_on_domain'.'hello, there! ', domain='httpbin.org')
>>> cookies.set('cookie_off_domain'.'nope.', domain='example.org')
>>> r = httpx.get('http://httpbin.org/cookies', cookies=cookies)
>>> r.json()
{'cookies': {'cookie_on_domain': 'hello, there! '}}
Copy the code
Url redirection and history
By default, HTTPX will perform any action on a redirection other than a HEAD request.
The property of the history response can be used to check all subsequent redirects. It contains a list of all the redirected responses that follow their order.
For example, GitHub redirects all HTTP requests to HTTPS.
>>> r = httpx.get('http://github.com/')
>>> r.url
URL('https://github.com/')
>>> r.status_code
200
>>> r.history
[<Response [301 Moved Permanently]>]
Copy the code
You can modify the default redirect handling using the allow_redirects parameter:
>>> r = httpx.get('http://github.com/', allow_redirects=False)
>>> r.status_code
301
>>> r.history
[]
Copy the code
If a HEAD request is to be made, it can be used to enable redirection:
>>> r = httpx.head('http://github.com/', allow_redirects=True)
>>> r.url
'https://github.com/'
>>> r.history
[<Response [301 Moved Permanently]>]
Copy the code
timeout
HTTPX defaults to include reasonable timeouts for all network operations, which means that if the connection is not properly established, it should always raise an error rather than hang indefinitely.
The default timeout for network inactivity is five seconds. You can change the value to be more or less strict:
>>> httpx.get('https://github.com/'Timeout = 0.001)Copy the code
You can also disable timeout behavior completely…
>>> httpx.get('https://github.com/', timeout=None)
Copy the code
For advanced timeout management, see Timeout Tuning.
authentication
HTTPX supports both basic and digest HTTP authentication.
To provide the basic authentication credentials, pass two tuples of plain text STR or bytes objects as auth arguments to the requester function:
>>> httpx.get("https://example.com", auth=("my_user"."password123"))
Copy the code
To provide credentials for digest authentication, you need DigestAuth to instantiate an object with a plain text username and password as parameters. This object can then be passed to the above request method as an auth parameter:
>>> auth = httpx.DigestAuth("my_user"."password123")
>>> httpx.get("https://example.com", auth=auth)
<Response [200 OK]>
Copy the code