How do I make an HTTP request in Python with requests?
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.