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