Of course! Using the requests library to work with JSON is one of its most common and powerful features. The library makes it incredibly simple to send HTTP requests and then easily parse the JSON response.

Here's a complete guide, from the basics to more advanced use cases.
The Core Concept: response.json()
When you make a request to a modern web API, the server often sends the data back in JSON format. The requests library automatically decodes this response for you.
The key method is response.json(). This method does two things:
- It checks if the
Content-Typeheader of the response isapplication/json. - If it is, it parses the raw response body (a string) into a Python data structure (a dictionary or a list).
A Simple GET Request (Reading Data)
This is the most common scenario: you want to get data from an API endpoint.

Step 1: Install the requests library
If you don't have it installed, open your terminal or command prompt and run:
pip install requests
Step 2: Make a GET request and parse the JSON
Let's use the JSONPlaceholder test API, which is perfect for examples.
import requests
import json # Useful for pretty-printing
# The URL of the API endpoint
url = "https://jsonplaceholder.typicode.com/posts/1"
try:
# Make a GET request to the URL
response = requests.get(url)
# Raise an exception if the request was unsuccessful (e.g., 404 Not Found, 500 Server Error)
response.raise_for_status()
# --- The Magic Happens Here ---
# .json() parses the JSON response into a Python dictionary
data = response.json()
# Now 'data' is a Python dictionary, so you can access its keys
print(f"Successfully fetched data for Post ID: {data['id']}")
print(f"Title: {data['title']}")
print(f"Body: {data['body']}")
print("-" * 20)
# Pretty-print the entire dictionary to see its structure
# The 'indent=4' argument makes the output readable
print("Full JSON data (pretty-printed):")
print(json.dumps(data, indent=4))
except requests.exceptions.HTTPError as errh:
print(f"Http Error: {errh}")
except requests.exceptions.ConnectionError as errc:
print(f"Error Connecting: {errc}")
except requests.exceptions.Timeout as errt:
print(f"Timeout Error: {errt}")
except requests.exceptions.RequestException as err:
print(f"Oops: Something Else: {err}")
Output:
Successfully fetched data for Post ID: 1 sunt aut facere repellat provident occaecati excepturi optio reprehenderit
Body: quia et suscipit
suscipit recusandae consequuntur expedita et cum
reprehenderit molestiae ut ut quas totam
nostrum rerum est autem sunt rem eveniet architecto
--------------------
Full JSON data (pretty-printed):
{
"userId": 1,
"id": 1,: "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
"body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
}
A POST Request (Sending Data)
Often, you'll need to send data to an API, like creating a new resource. This is done with a POST request. You send your data in the request body as JSON.

The requests library has a json parameter that automatically handles the conversion of your Python dictionary to a JSON string and sets the correct Content-Type header for you.
import requests
import json
url = "https://jsonplaceholder.typicode.com/posts"
# The data you want to send, as a Python dictionary
new_post_data = {: 'My Awesome New Post',
'body': 'This is the content of my new post.',
'userId': 10
}
try:
# Make a POST request
# The 'json' parameter is the key here!
response = requests.post(url, json=new_post_data)
# Raise an exception for bad status codes
response.raise_for_status()
# Parse the JSON response from the server
# This usually contains the data that was created, often with a new ID
created_data = response.json()
print("Successfully created a new post!")
print(f"Server assigned it ID: {created_data['id']}")
print("Full server response:")
print(json.dumps(created_data, indent=4))
except requests.exceptions.RequestException as e:
print(f"An error occurred: {e}")
Output:
Successfully created a new post!
Server assigned it ID: 101
Full server response:
{: "My Awesome New Post",
"body": "This is the content of my new post.",
"userId": 10,
"id": 101
}
Other Common HTTP Methods
The same principles apply to other HTTP methods like PUT (to update data) and DELETE (to remove data).
PUT (Update)
import requests
import json
url = "https://jsonplaceholder.typicode.com/posts/1"
# The updated data
updated_data = {
'id': 1,: 'An Updated Title',
'body': 'This post has been updated.',
'userId': 1
}
try:
response = requests.put(url, json=updated_data)
response.raise_for_status()
updated_resource = response.json()
print("Successfully updated the post!")
print(json.dumps(updated_resource, indent=4))
except requests.exceptions.RequestException as e:
print(f"An error occurred: {e}")
DELETE
import requests
url = "https://jsonplaceholder.typicode.com/posts/1"
try:
response = requests.delete(url)
response.raise_for_status()
print(f"Successfully deleted post with status code: {response.status_code}")
# A DELETE request often returns an empty body with a 200 or 204 status code.
# response.json() would fail here, so be careful.
print(f"Response content: {response.text}")
except requests.exceptions.RequestException as e:
print(f"An error occurred: {e}")
Handling Errors and Edge Cases
a) The Response Isn't JSON
What if the server returns an HTML error page (like a 404) instead of JSON? Calling response.json() will raise a requests.exceptions.JSONDecodeError.
The try...except block from the first example is a robust way to handle this. A more specific check is to look at the Content-Type header.
response = requests.get("https://example.com/non-existent-endpoint")
# Check if the content type is actually JSON before parsing
if response.headers['Content-Type'] == 'application/json':
data = response.json()
print(data)
else:
print(f"Error: Expected JSON, but got Content-Type: {response.headers['Content-Type']}")
print(f"Response text: {response.text}")
b) Non-2xx Status Codes
By default, requests does not raise an exception for HTTP error codes (4xx or 5xx). You must call response.raise_for_status() to do this manually. This is a best practice.
response = requests.get("https://jsonplaceholder.typicode.com/posts/999")
# This post doesn't exist, so it will return a 404 Not Found
print(f"Status Code: {response.status_code}") # Will print 404
# This line will raise an HTTPError because the status is 404
try:
response.raise_for_status()
except requests.exceptions.HTTPError as e:
print(f"Caught an HTTPError: {e}")
Summary: Key Takeaways
| Task | Code Snippet | Description |
|---|---|---|
Install requests |
pip install requests |
Install the library in your environment. |
| GET Request & Parse JSON | response = requests.get(url)data = response.json() |
Fetch data from a URL and parse the JSON response into a Python dictionary. |
| POST Request with JSON Body | response = requests.post(url, json=my_dict) |
Send data to a server. The json parameter automatically converts the dict to JSON and sets the header. |
| Check for Errors | response.raise_for_status() |
Raise an exception if the request returned an unsuccessful status code (4xx or 5xx). |
| Pretty-Print JSON | import jsonprint(json.dumps(data, indent=4)) |
For debugging, print a Python dictionary/list as |
