Getting Started with HTTPX in Python: Practical Examples and Usage Tips

Feb 5, 2024 ยท 5 min read

HTTPX is a powerful and modern HTTP client for Python that builds on the well-known Requests library. In this comprehensive guide, we'll cover practical examples of using HTTPX to make API calls, upload files, manage authentication, timeouts, and more.

We'll also share tips and tricks for getting the most out of HTTPX based on real-world usage. Whether you're new to HTTPX or looking to use it more effectively, read on!

Making a Simple GET Request

Let's start with a basic HTTP GET request to retrieve data from a URL. This is the simplest usage of HTTPX:

import httpx

response = httpx.get('https://api.example.com/users')
print(response.json()) 

We use the get() method and pass the URL. HTTPX handles encoding the request, sending it, and decoding the response. We can access the JSON body using response.json().

Posting Form Data

Submitting forms and multipart data is common. HTTPX makes this easy and handles encoding the data:

data = {'key1': 'value1', 'key2': 'value2'}

response = httpx.post("https://api.example.com/form", data=data)

The data dictionary will form-encoded automatically. For JSON data, use the json parameter instead.

Uploading Files

Uploading files requires multipart encoding. HTTPX handles this complexity for you:

files = {'file': open('report.pdf', 'rb')}

response = httpx.post("https://api.example.com/upload", files=files)

This encodes the file as multipart/form-data and uploads it. Much easier than manually handling encodings!

Setting Request Headers

To set custom headers, pass a dictionary to the headers parameter:

headers = {
  'User-Agent': 'My App v1.0',
  'Authorization': 'Bearer mytoken123' 
}

response = httpx.get('https://api.example.com/users', headers=headers)

This sets the User-Agent and an authorization header. HTTPX will automatically add other default headers too.

Handling HTTP Redirects

By default, HTTPX follows redirects up to a maximum of 20. To customize this, use the follow_redirects parameter:

response = httpx.get('https://example.com', follow_redirects=True) 

Set to True to follow all redirects. Or set an integer to follow up to a certain number of redirects.

Setting Request Timeout

To avoid hanging requests, you can set a timeout. This raises an exception if the server doesn't respond in time:

timeout = httpx.Timeout(10.0) # 10 second timeout

response = httpx.get('https://api.example.com', timeout=timeout)  

The timeout is set in seconds. You can also set connection and read timeouts separately if needed.

Making Async HTTP Requests

HTTPX supports both synchronous and asynchronous requests. Here is an example async request:

import httpx

async def main():
  async with httpx.AsyncClient() as client:
    response = await client.get('https://api.example.com')
    print(response.json())
    
asyncio.run(main())

We use an async context manager to create the client. Then await on each request within the async block.

Authenticating with HTTP Basic Auth

To use HTTP basic authentication, pass the username and password:

auth = ('username', 'password123')

response = httpx.get('https://api.example.com', auth=auth)

HTTPX handles encoding the credentials into the Authorization header automatically.

Authenticating with OAuth 2.0

For OAuth 2.0 authentication, HTTPX provides helper classes to simplify the authorization code flow:

from httpx_oauth.oauth2_authentication_flow import OAuth2Authentication

auth = OAuth2Authentication(
    token_url="https://api.example.com/oauth2/token",
    authorization_url="https://api.example.com/oauth2/authorize",
    client_id="myclientid123",
    client_secret="mysecret456")
    
auth.retrieve_access_token(
    code="authcode789"
)

response = httpx.get("https://api.example.com", auth=auth) 

This handles the access token request and refresh for you automatically!

Streaming Response Content

For large responses, you may want to stream the content instead of loading into memory. This can be done as follows:

with httpx.stream("GET", "https://api.example.com") as response:
  for data in response.iter_bytes():
    process_data(data) 

The iter_bytes() method yields the response chunk-by-chunk for processing or saving to disk.

Handling HTTP Errors

When a 4xx or 5xx status code occurs, HTTPX raises httpx.HTTPError. You can catch this and handle:

try:
  response = httpx.get('https://api.example.com')
  response.raise_for_status()
  
except httpx.HTTPError as exc:
  print(f'Error response {exc.response.status_code}.')

Check the status code to determine the issue. Common codes are 400 Bad Request, 401 Unauthorized, etc.

Configuring a Client Session

Making a new HTTPX client for every request adds overhead. For efficiency, reuse a Client instance:

client = httpx.Client()

response = client.get('https://api.example.com/users')
print(response.json())

The client handles connection pooling, retries, and persists headers/timeouts between requests. Much better performance!

When done, close the client:

client.close()

This releases the connections and sockets its holding open.

Summary

That covers the main practical usage patterns and examples of HTTPX!

Key takeways:

  • HTTPX provides an easy yet powerful Python HTTP client built on Requests
  • Easily make GET, POST, PUT requests just like Requests
  • Handles JSON, forms, files, headers automatically
  • Supports authentication, redirects, timeouts
  • Async support for non-blocking requests
  • Reuse client session for best performance
  • Robust error handling and streaming responses
  • With these examples, you should be able to start integrating HTTPX into your Python apps for calling REST APIs with ease.

    The full documentation provides info on more advanced features like proxies, SOCKS support, testing, and customization.

    Browse by tags:

    Browse by language:

    Tired of getting blocked while scraping the web?

    ProxiesAPI handles headless browsers and rotates proxies for you.
    Get access to 1,000 free API credits, no credit card required!