Q&A library Python

How do I make an HTTP request in Python with requests?

Python Intermediate apihttprequests

Short answer

Use requests.get with a params dict for the query string, then check status_code and call json to parse the body. Set a timeout, and raise for status so failed requests do not pass silently.

The short version

Use requests.get(url, params=...) to fetch a URL, then check response.status_code and call response.json() to parse a JSON body. Always pass a timeout so a hung server cannot freeze your program, and call raise_for_status() so a failed request raises instead of quietly returning an error page.

A basic GET request

import requests

response = requests.get(
    "https://example.com/api/items",
    params={"category": "books", "limit": 10},
    timeout=10,
)
response.raise_for_status()
data = response.json()

params builds the query string for you, so you do not concatenate ?category=books&limit=10 by hand, and it handles escaping special characters correctly.

Checking the result

The status_code tells you what happened: 200 means success, 404 not found, 500 a server error. Rather than checking it by hand every time, raise_for_status() turns any error code into an exception.

if response.status_code == 200:
    data = response.json()

raise_for_status() is usually cleaner, because it stops a failed request from silently flowing on as if it succeeded, which is a common and costly mistake.

Always set a timeout

Without a timeout, a request can hang indefinitely if the server never responds, freezing your program. Set one on every request.

requests.get(url, timeout=10)   # give up after 10 seconds

This is the single most important habit with requests, because the default is to wait forever.

Parsing the body

response.json() parses a JSON response into Python dicts and lists. For plain text, use response.text, and for binary data (an image, a file), use response.content.

response.json()     # parsed JSON
response.text       # the body as a string
response.content    # the body as bytes

Calling .json() on a non-JSON response raises, so make sure the endpoint returns JSON before using it.

Sending data with POST

To send data, use requests.post with json= for a JSON body, which also sets the correct content-type header.

requests.post(url, json={"name": "widget"}, timeout=10)

Handling failures

Network calls fail in many ways (no connection, a timeout, an error status), so wrap them in a try/except around requests.exceptions.RequestException, the base class for the library's errors.

try:
    response = requests.get(url, timeout=10)
    response.raise_for_status()
except requests.exceptions.RequestException as err:
    print("request failed:", err)

Reusing a connection

For several requests to the same host, a requests.Session reuses the underlying connection and shares headers, which is faster and tidier than separate calls. Use a session whenever you make more than a couple of requests to the same service.

Need this solved on your own data?

The library is free and always will be. When the problem is bigger than an answer, we take on the work.

Start a project