Consume REST APIs with Python and requests
The requests library is the standard for HTTP requests in Python: GET, POST, authentication, pagination, file downloads and error handling.
Installation
pip install requests
Basic GET Request
import requests
resp = requests.get("https://jsonplaceholder.typicode.com/posts/1")
resp.raise_for_status() # Raises exception on HTTP errors
data = resp.json()
print(f"Title: {data['title']}")
print(f"Body: {data['body'][:80]}")
print(f"Status: {resp.status_code} | Time: {resp.elapsed.total_seconds():.2f}s")
URL Parameters and Headers
import requests
def search_users(query, page=1, per_page=10):
resp = requests.get(
"https://api.example.com/users",
params={
"q": query,
"page": page,
"per_page": per_page,
},
headers={
"Accept": "application/json",
"User-Agent": "MyApp/1.0",
},
timeout=10
)
resp.raise_for_status()
return resp.json()
results = search_users("python", page=1)
print(f"Results: {len(results)}")
POST, PUT and DELETE
import requests
BASE = "https://jsonplaceholder.typicode.com"
def create_post(title, body, user_id):
resp = requests.post(f"{BASE}/posts",
json={"title": title, "body": body, "userId": user_id},
headers={"Content-Type": "application/json"}
)
resp.raise_for_status()
print(f"Created (id={resp.json()['id']}): {resp.status_code}")
return resp.json()
def update_post(post_id, title, body):
resp = requests.put(f"{BASE}/posts/{post_id}",
json={"id": post_id, "title": title, "body": body, "userId": 1}
)
resp.raise_for_status()
return resp.json()
def delete_post(post_id):
resp = requests.delete(f"{BASE}/posts/{post_id}")
resp.raise_for_status()
print(f"Deleted post {post_id}: {resp.status_code}")
create_post("My Title", "My test content.", 1)
update_post(1, "Updated Title", "Updated body.")
delete_post(1)
Authentication: API Key and Bearer Token
import requests
# API Key in header
resp = requests.get(
"https://api.openweathermap.org/data/2.5/weather",
params={"q": "London", "units": "metric"},
headers={"X-API-Key": "YOUR_API_KEY"}
)
data = resp.json()
print(f"Temperature in London: {data['main']['temp']}°C")
# Bearer Token (OAuth2, JWT)
TOKEN = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
resp = requests.get(
"https://api.myservice.com/profile",
headers={"Authorization": f"Bearer {TOKEN}"}
)
print(resp.json())
Automatic Pagination
import requests
def fetch_all(url, params=None, limit=None):
results = []
page = 1
while True:
p = {**(params or {}), "page": page, "per_page": 100}
resp = requests.get(url, params=p, timeout=10)
resp.raise_for_status()
data = resp.json()
if not data: break
results.extend(data)
print(f" Page {page}: {len(data)} records")
if len(data) < 100: break
if limit and len(results) >= limit: break
page += 1
return results
all_posts = fetch_all("https://jsonplaceholder.typicode.com/posts")
print(f"Total: {len(all_posts)} posts")
Download Files
import requests
from pathlib import Path
def download_file(url, dest, show_progress=True):
resp = requests.get(url, stream=True, timeout=30)
resp.raise_for_status()
total = int(resp.headers.get("Content-Length", 0))
done = 0
with open(dest, "wb") as f:
for chunk in resp.iter_content(chunk_size=8192):
f.write(chunk)
done += len(chunk)
if show_progress and total:
pct = done * 100 // total
print(f"\r {pct:3d}% ({done//1024}KB/{total//1024}KB)", end="")
if show_progress: print()
print(f"Downloaded: {dest} ({Path(dest).stat().st_size//1024} KB)")
download_file("https://example.com/large_file.zip", "download.zip")
Additional Resource
For converting downloaded files between PDF, ZIP, JPG and other formats without any coding, use KaijuConverter — free and no registration required.
Related conversions
Frequent conversions across the catalogue: