requests β HTTP for Humans#
What it is#
requests is the most widely used Python HTTP client. It wraps urllib3 and exposes a clean, human-friendly API for GET, POST, PUT, DELETE, and streaming. Over a billion downloads per month on PyPI.
Install#
pip install requests
Quick example#
import requests
resp = requests.get("https://httpbin.org/json")
resp.raise_for_status() # raises HTTPError for 4xx/5xx
data = resp.json()
print(resp.status_code)
print(data["slideshow"]["title"])
Output:
200
Sample Slide Show
When / why to use it#
- Any synchronous HTTP call β REST APIs, scraping, file downloads.
- When you need a battle-tested, widely-supported client with broad documentation.
- When you donβt need async (
httpxis the async-capable alternative).
Common pitfalls#
[!WARNING] No timeout by default β
requests.get(url)will hang indefinitely if the server stalls. Always passtimeout=(connect, read):requests.get(url, timeout=(3.05, 27))
[!WARNING] SSL verification β never disable
verify=Falsein production. It silently makes every request vulnerable to MITM attacks. If a corporate proxy breaks SSL, install the proxyβs CA cert instead.
[!WARNING]
raise_for_status()placement β call it before trying to parse.json(). A 4xx/5xx response body may not be valid JSON.
Richer example β sessions and retries#
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
session = requests.Session()
retry = Retry(total=3, backoff_factor=0.5, status_forcelist=[500, 502, 503, 504])
session.mount("https://", HTTPAdapter(max_retries=retry))
resp = session.post(
"https://httpbin.org/post",
json={"user": "alice", "action": "login"},
headers={"X-App-Version": "1.0"},
timeout=(3.05, 10),
)
resp.raise_for_status()
body = resp.json()
print(body["json"])
print(body["headers"]["Content-Type"])
Output:
{'action': 'login', 'user': 'alice'}
application/json
Essential options reference#
| Parameter | Example | Notes |
|---|---|---|
params | params={"page": 1} | Appended as query string |
json | json={"k": "v"} | Encodes body as JSON, sets Content-Type header |
data | data={"field": "val"} | Form-encoded body |
headers | headers={"Auth": "Bearer tok"} | Merged with session headers |
timeout | timeout=(3, 10) | (connect timeout, read timeout) in seconds |
auth | auth=("user", "pass") | HTTP Basic auth |
stream | stream=True | Stream large responses without buffering |
verify | verify="/path/to/ca.pem" | CA bundle for TLS verification |
Streaming large downloads#
with requests.get("https://example.com/large.zip", stream=True, timeout=30) as r:
r.raise_for_status()
with open("large.zip", "wb") as f:
for chunk in r.iter_content(chunk_size=8192):
f.write(chunk)
print("Download complete")
Output:
Download complete