advanced
Step 17 of 20
Working with APIs
Python Programming
Working with APIs
APIs (Application Programming Interfaces) are the backbone of modern software, enabling different applications to communicate with each other. REST APIs, accessed over HTTP, are the most common type you will encounter. Whether you are fetching weather data, posting to social media, processing payments, or integrating third-party services, you need to know how to make HTTP requests and handle responses. Python's requests library makes this task straightforward and enjoyable, providing a clean interface for all types of HTTP operations.
Making GET Requests
import requests
# Simple GET request
response = requests.get("https://jsonplaceholder.typicode.com/posts/1")
# Check status code
print(response.status_code) # 200
print(response.ok) # True (status code < 400)
# Parse JSON response
data = response.json()
print(data["title"])
print(data["body"])
# Response headers
print(response.headers["Content-Type"])
# GET with query parameters
params = {"userId": 1, "_limit": 5}
response = requests.get(
"https://jsonplaceholder.typicode.com/posts",
params=params
)
posts = response.json()
for post in posts:
print(f" {post['id']}: {post['title'][:50]}")
POST, PUT, PATCH, DELETE
# POST — create a new resource
new_post = {
"title": "My New Post",
"body": "This is the content of my post.",
"userId": 1
}
response = requests.post(
"https://jsonplaceholder.typicode.com/posts",
json=new_post # Automatically sets Content-Type and serializes
)
print(response.status_code) # 201 (Created)
created = response.json()
print(f"Created post with ID: {created['id']}")
# PUT — replace entire resource
updated_post = {
"id": 1,
"title": "Updated Title",
"body": "Updated body content.",
"userId": 1
}
response = requests.put(
"https://jsonplaceholder.typicode.com/posts/1",
json=updated_post
)
# PATCH — partial update
response = requests.patch(
"https://jsonplaceholder.typicode.com/posts/1",
json={"title": "Just Update the Title"}
)
# DELETE
response = requests.delete(
"https://jsonplaceholder.typicode.com/posts/1"
)
print(response.status_code) # 200
Headers and Authentication
# Custom headers
headers = {
"Authorization": "Bearer your_api_token_here",
"Accept": "application/json",
"User-Agent": "MyApp/1.0"
}
response = requests.get(
"https://api.example.com/data",
headers=headers
)
# Basic authentication
response = requests.get(
"https://api.example.com/protected",
auth=("username", "password")
)
# Session — persist settings across requests
session = requests.Session()
session.headers.update({
"Authorization": "Bearer token123",
"Accept": "application/json"
})
# All requests in this session include the headers
r1 = session.get("https://api.example.com/users")
r2 = session.get("https://api.example.com/posts")
session.close()
Error Handling and Timeouts
import requests
from requests.exceptions import (
ConnectionError, Timeout, HTTPError, RequestException
)
def fetch_data(url, max_retries=3):
for attempt in range(1, max_retries + 1):
try:
response = requests.get(url, timeout=10)
response.raise_for_status() # Raises HTTPError for 4xx/5xx
return response.json()
except Timeout:
print(f"Attempt {attempt}: Request timed out")
except ConnectionError:
print(f"Attempt {attempt}: Connection failed")
except HTTPError as e:
print(f"HTTP error: {e.response.status_code}")
if e.response.status_code == 404:
return None # Resource not found, don't retry
if e.response.status_code >= 500:
print("Server error, retrying...")
continue
return None
except RequestException as e:
print(f"Request failed: {e}")
return None
print("All retries exhausted")
return None
data = fetch_data("https://jsonplaceholder.typicode.com/posts/1")
if data:
print(data["title"])
Pro tip: Always set a timeout on your requests to prevent your program from hanging indefinitely if the server is unresponsive. A timeout of 10-30 seconds is reasonable for most APIs. Also, use response.raise_for_status() to automatically raise an exception for HTTP error codes (4xx and 5xx).
Key Takeaways
- Use the
requestslibrary for HTTP operations:get(),post(),put(),patch(), anddelete(). - Pass
json=datafor JSON payloads andparams=dictfor query parameters. - Always handle errors with try/except and set timeouts to prevent hanging requests.
- Use
response.raise_for_status()to automatically detect HTTP errors (4xx/5xx status codes). - Use
requests.Session()to persist headers and authentication across multiple requests efficiently.