Skip to content

Python Requests Library: A Guide

Python Requests Library Complete Guide Cover image

The Python requests library in Python allows you to send HTTP requests easily. The library abstracts much of the complexity of making requests, by using a simple and consistent API. This guide provides an in-depth view of the essential aspects of the requests library and points to further guides that go even deeper.

By the end of this guide, you’ll have learned:

  • How to make HTTP requests, including GET and POST requests
  • How to customize HTTP requests by using headers and query strings
  • How to authenticate requests using different authentication methods
  • How to understand the responses you get back, including converting them to Python dictionaries
  • How to use proxies for your HTTP requests
  • How to create sessions to streamline making multi-part requests
  • How to work with timeouts to keep your program running optimally

What is the Python Requests Library?

The Python requests library is a Python library that handles making HTTP requests. The library is well known for being simple and elegant, by abstracting away much of the complexity of working with HTTP requests.

The library is also one of the more popular libraries available in Python: it currently draws around 30,000,000 downloads per week and is in use by over 1,000,000 repositories on Github.

How Do You Install the Python Requests Library?

The simplest way to install the requests library is to use the Python pip package manager. In order to install the latest version of the library, you can simply call the following command in the command prompt or terminal.

python -m pip install requests

To install a specific version of the library, such as version 2.28.1, you can write the following command:

python -m pip install requests==2.28.1

It’s as easy as that! In the following section, you’ll learn how to install the requests library on macOS using the pip package manager.

Making HTTP GET Requests with the Python Requests Library

An HTTP GET request is used to retrieve data from the specified resource, such as a website. When using the Python requests library, you can use the .get() function to create a GET request for a specified resource.

The .get() function accepts two parameters:

  1. A url, which points to a resource, and
  2. params, which accepts a dictionary or tuples to send in the query string

Let’s see how we can use the get() function to make a GET request:

# Making a GET Request with requests.get()
import requests

resp = requests.get('https://reqres.in/api/users')
print(resp)

# Returns:
# <Response [200]>

Let’s break down what we did in the code above:

  1. We imported the requests library
  2. We created a new variable, resp, which is the result of passing our endpoint into the get() function
  3. We then printed out the variable, which returned a Response object

The Response object has a number of different properties and methods that we can access to learn more about the data that has been returned.

Some of the key properties and methods available to a Response object include:

  • .status_code, which is the integer code of the responded HTTP status, such as 200 or 404
  • .ok, which return True is the status code of the response is less than 400, otherwise False
  • .json(), which returns the JSON-encoded content of a response
  • .content, which contains the content of the response
  • .next, which returns a request for the new request in a redirect chain, if there is one

In the following section, you’ll learn how to make POST requests using the Python requests library.

Making HTTP POST Requests with the Python Requests Library

An HTTP POST request is used to send data to a server, where data are shared via the body of a request. In the request.post() function, data are sent with the data parameter, which accepts a dictionary, a list of tuples, bytes or a file object.

Let’s take a look at what the requests.post() function looks like in Python:

# Understanding the requests.post() Function
import requests

requests.post(
   url, 
   data=None,
   json=None,
   **kwargs
)

We can see that the function accepts three parameters:

  1. url, which defines the URL to post to
  2. data, which accepts a dictionary, list of tuples, butes, or a file-like object to send in the body of the request
  3. json, which represents json data to send in the body of the request

To illustrate using this function, we’ll be using the https://httpbin.org/ website, which allows us to place actual POST requests.

Let’s create our first POST request using Python:

# Creating a POST Request with requests.post
import requests
resp = requests.post('https://httpbin.org/post')
print(resp)

# Returns:
# <Response [200]>

In the example above, we simply pass the URL to the /post endpoint into the requests.post() function. We then print the response that we get back, which returns a Response object.

Customizing Headers in HTTP Requests Using Python Requests

HTTP headers allow the client and server to pass additional information while sending an HTTP request or receiving a subsequent response. These headers are case-insensitive, meaning that the header of 'User-Agent' could also be written as 'user-agent'.

Additionally, HTTP headers in the requests library are passed in using Python dictionaries, where the key represents the header name and the value represents the header value.

HTTP headers allow the client and server to pass additional information while sending an HTTP request or receiving a subsequent response. These headers are case-insensitive, meaning that the header of 'User-Agent' could also be written as 'user-agent'.

Additionally, HTTP headers in the requests library are passed in using Python dictionaries, where the key represents the header name and the value represents the header value.

# Passing HTTP Heades into a Python requests.get() Function
import requests

url = 'https://httpbin.org/get'
headers = {'Content-Type': 'text/html'}

print(requests.get(url, headers=headers))

# Returns: <Response [200]>

Customizing Query String in HTTP Requests Using Python Requests

Query string parameters allow you to customize a GET request by passing values directly into the URL or into the params= parameter.

There are three ways to accomplish creating query parameters:

  1. Pass in a dictionary of parameters into the params= parameter, such as {'page': '2'}
  2. Pass in a list of tuples into the params= parameter, such as [('page', '2')]
  3. Directly modify the URL string by appending ?page=2 to the URL

Let’s see how we can use the first method to accomplish this:

# Passing in Query Parameters Into Our GET Request
import requests
params = {'page': '2'}
resp = requests.get('https://reqres.in/api/users', params=params)

Even when you don’t pass in headers, headers will be returned in a Response object. The headers are accessible via the .headers attribute, which returns a dictionary.

Let’s see how we can return the headers available in a Response object:

# Checking the Headers of a Response Object
import requests

response = requests.get('https://httpbin.org/get')
print(response.headers)

# Returns:
# {'Date': 'Wed, 03 Aug 2022 14:12:50 GMT', 'Content-Type': 'application/json', 'Content-Length': '312', 'Connection': 'keep-alive', 'Server': 'gunicorn/19.9.0', 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Credentials': 'true'}

In the code block above, we used a get() function call to get a Response object. We then accessed the headers of the response by accessing the .headers attribute.

How to Understand Responses from HTTP Requests in Python Requests

The Python requests library returns a Response object when any type of request is made, including POST and GET requests. The Response object contains useful attributes and methods that help in understand the response.

Before diving further, let’s see how we can create a Response object and verify its type:

# Getting a requests Response Object
import requests

resp = requests.get('https://reqres.in/api/users')
print(type(resp))

# Returns: <class 'requests.models.Response'>

We can see that when we make a request, in this case a GET request, a Response object is returned.

Understanding whether or not a request was successful is, of course, a very important part of understanding a response. The requests.Response object provides a number of different ways to do this. Let’s explore two key attributes:

  1. Response.status_code returns an integer value representing the status of the response
  2. Response.ok returns a boolean value indicating success

A common task you’ll want to take on is seeing the body of a response that gets returned when a request is made. There are a number of simple ways in which we can do this:

  1. .content returns the actual content in bytes
  2. .text returns the content converted to a string, using a character encoding such as UTF-8

Both of these methods work well for accessing the content of the response. Using the .text attribute simply converts the values to a string for easier access.

How to Convert Python Requests Responses to JSON

The requests library comes with a helpful method, .json(), that helps serialize the response of the request. In order to look at an example, let’s the public endpoints provided by the website reqres.in. These endpoints work without signing up, so following along with the tutorial is easy.

Let’s see how we can access the /users endpoint and serialize the response into a Python dictionary using the .json() method:

# Serializing a GET Request with .json()
import requests
resp = requests.get('https://reqres.in/api/users')
resp_dict = resp.json()

print(type(resp_dict))

# Returns: <class 'dict'>

From the code above, we can see that applying the .json() method to our response created a Python dictionary.

How to Authenticate HTTP Requests with Python Requests

The Python requests library provides a number of different ways to authenticate requests, which are covered in detail in this post. Let’s first take a look at basic authentication.

Basic authentication refers to using a username and password for authentication a request. Generally, this is done by using the HTTPBasicAuth class provided by the requests library. However, as you’ll later learn, the requests library makes this much easier, as well, by using the auth= parameter.

Let’s see how we can pass in a username and password into a simple GET request using the HTTPBasicAuth class:

# Authentication in Requests with HTTPBasicAuth
import requests
from requests.auth import HTTPBasicAuth
auth = HTTPBasicAuth('user', 'pass')

print(requests.get('https://httpbin.org/basic-auth/user/pass', auth=auth))

# Returns: <Response [200]>

Let’s break down what we did in the code above:

  1. We imported both the requests library as well as only the HTTPBasicAuth class
  2. We then created a new HTTPBasicAuth object, auth, which contains a string for the username and password
  3. Finally, we printed the Response we returned when passing our auth variable into the auth= parameter of the get() function

If you were using this method, you’d change 'user' and 'pass' to the username and password of your choice.

Because the basic authentication method is used so frequently, the requests library abstracts away some of this complexity. Rather than needing to create a new HTTPBasicAuth object each time, you can simply pass a tuple containing your username and password into the auth= parameter.

Let’s see what this looks like:

# Simplifying Basic Authentication with Python requests
import requests

print(requests.get('https://httpbin.org/basic-auth/user/pass', auth=('user', 'pass')))

# Returns: <Response [200]>

In the code above, we were able to significantly reduce the complexity of our code. The Python requests library handles a lot of the boilerplate code for us!

To learn more about other forms of authentication, check out this dedicated article on authenticating HTTP requests with Python.

How to Create Sessions with Python Requests

A Session object in the Python requests library allows you to persist parameters across different requests being made. Similarly, it allows you to persist cookies across requests. Finally, it also used connection pooling, which can make subsequent requests gain significant performance improvements.

What’s great about requests Session objects is that they allow you to persist items, such as authentication, across multiple requests. This allows you to, for example, scrape websites much more elegantly than you may otherwise.

An important thing to note is that a session object has access to all the methods of the main Requests API.

You can create a session object by instantiating a Session class, as shown below:

# Creating a Session Object
import requests
s = requests.Session()

In the following section, you’ll learn how to set headers for a Python requests Session.

For example, you can persist in authenticating requests using Python Session objects. This allows you to pass in authentication to the Session object. This can be done by setting the .auth attribute of the session directly.

Let’s see how this can be done using Python:

# Persisting Authentication for Python requests Sessions
import requests

s = requests.Session()
s.auth = ('username', 'password')

In the example above, we created a Session object. Then, we assigned a tuple containing a username and password to the .auth attribute of the Session object.

How to Set Timeouts for HTTP Requests with Python Requests

By default, the Python requests library does not set a timeout for any request it sends. This is true for GET, POST, and PUT requests. While this can prevent unexpected errors, it can result in your request running indefinitely.

Because of this, it’s important to set a timeout to prevent unexpected behavior.

In order to set a timeout in an HTTP request made via the requests library, you can use the timeout parameter. The parameter accepts either an integer or a floating point value, which describes the time in seconds.

It’s important to note that this behavior is different from many other HTTP request libraries, such as those in JavaScript. In other libraries or languages, this behavior tends to be expressed in milliseconds.

Let’s take a look at an example of how we can send a GET request with a timeout:

# Setting a Timeout on a GET Request with an Integer
import requests
resp = requests.get('https://datagy.io', timeout=3)

In the example above, we set a timeout of 3 seconds. We used an integer to represent the time of our timeout. If we wanted to be more precise, we could also pass in a floating point value:

# Setting a Timeout on a GET Request with a Floating Point Value
import requests
resp = requests.get('https://datagy.io', timeout=3.5)

By passing in a single value, we set a timeout for the request. If we wanted to set different timeouts for connecting and reading a request, we can pass in a tuple of values.

How to Use Proxies When Using Python Requests

In order to use proxies in the requests Python library, you need to create a dictionary that defines the HTTP, HTTPS, and FTP connections. This allows each connection to map to an individual URL and port. This process is the same for any request being made, including GET requests and POST requests.

It’s important to note that while the connections map to individual URLs and ports, they can actually point to the same URL and port.

Let’s see how you can define a set of proxies for the Python requests library:

# Setting up Proxies with the requests Library
import requests

proxy_servers = {
   'http': 'http://proxy.sample.com:8080',
   'https': 'http://secureproxy.sample.com:8080',
}

response = requests.get('sample.abc', proxies=proxy_servers)

Let’s break down what we did above:

  1. We imported the requests library
  2. We defined a dictionary, proxy_servers, which mapped URLs and ports to HTTP and HTTPS connections
  3. We then made a GET request and passed in our dictionary into the proxies= argument

Conclusion

In this guide, you learned how to use the Python requests library to make HTTP requests. The library provides a lot of functionality to streamline and simplify making HTTP requests and working with their responses.

First, you learned how to make HTTP requests, including GET and POST requests. Then, you learned how to customize these requests using headers and query strings. You also learned how to authenticate requests in various ways.

Following this, you learned how to understand the responses that get returned. You also learned how to use sessions to make requests simpler and persistent. Then, you also learned how to use proxies and timeouts to manage the requests that you make.

Additional Resources

To learn more about related topics, check out the tutorials below:

Nik Piepenbreier

Nik is the author of datagy.io and has over a decade of experience working with data analytics, data science, and Python. He specializes in teaching developers how to use Python for data science using hands-on tutorials.View Author posts

Leave a Reply

Your email address will not be published. Required fields are marked *