Table of contents

How do I Send PUT requests with JSON Data Using Requests?

Sending PUT requests with JSON data is a common requirement when working with REST APIs that support data updates. The Python Requests library provides several convenient methods to send JSON payloads in PUT requests, making it straightforward to update resources on web servers.

Basic PUT Request with JSON Data

The simplest way to send a PUT request with JSON data using Requests is to use the json parameter:

import requests

# JSON data to send
data = {
    "name": "John Doe",
    "email": "john.doe@example.com",
    "age": 30
}

# Send PUT request with JSON data
response = requests.put('https://api.example.com/users/123', json=data)

# Check the response
if response.status_code == 200:
    print("Update successful!")
    print(response.json())
else:
    print(f"Request failed with status code: {response.status_code}")

When you use the json parameter, Requests automatically: - Sets the Content-Type header to application/json - Serializes your Python dictionary or list to JSON format - Encodes the JSON data as UTF-8

Manual JSON Encoding and Headers

For more control over the request, you can manually encode JSON data and set headers:

import requests
import json

# Prepare JSON data
data = {
    "product_name": "Laptop",
    "price": 999.99,
    "category": "Electronics"
}

# Convert to JSON string
json_data = json.dumps(data)

# Set headers
headers = {
    'Content-Type': 'application/json',
    'Accept': 'application/json'
}

# Send PUT request
response = requests.put(
    'https://api.example.com/products/456',
    data=json_data,
    headers=headers
)

print(f"Status Code: {response.status_code}")
print(f"Response: {response.text}")

PUT Requests with Authentication

Many APIs require authentication for PUT operations. Here's how to include various authentication methods:

Bearer Token Authentication

import requests

# Your data and authentication token
data = {"status": "active", "permissions": ["read", "write"]}
token = "your_bearer_token_here"

headers = {
    'Authorization': f'Bearer {token}',
    'Content-Type': 'application/json'
}

response = requests.put(
    'https://api.example.com/users/789',
    json=data,
    headers=headers
)

if response.status_code == 200:
    print("User updated successfully")
else:
    print(f"Error: {response.status_code} - {response.text}")

Basic Authentication

import requests
from requests.auth import HTTPBasicAuth

data = {"title": "Updated Article", "content": "New content here"}

response = requests.put(
    'https://api.example.com/articles/101',
    json=data,
    auth=HTTPBasicAuth('username', 'password')
)

print(f"Response: {response.status_code}")

Advanced PUT Request Examples

Complex JSON Structure

import requests

# Complex nested JSON data
complex_data = {
    "user": {
        "personal_info": {
            "first_name": "Jane",
            "last_name": "Smith",
            "address": {
                "street": "123 Main St",
                "city": "New York",
                "zip_code": "10001"
            }
        },
        "preferences": {
            "notifications": True,
            "theme": "dark",
            "languages": ["en", "es"]
        }
    },
    "metadata": {
        "updated_by": "admin",
        "version": "2.1"
    }
}

response = requests.put(
    'https://api.example.com/users/profile/456',
    json=complex_data,
    timeout=30
)

if response.status_code in [200, 204]:
    print("Profile updated successfully")
else:
    print(f"Update failed: {response.text}")

PUT Request with Query Parameters

import requests

# Data to update
update_data = {
    "price": 1299.99,
    "stock_quantity": 15
}

# Query parameters
params = {
    "version": "v2",
    "format": "json",
    "notify": "true"
}

response = requests.put(
    'https://api.example.com/inventory/items/SKU123',
    json=update_data,
    params=params
)

print(f"Final URL: {response.url}")
print(f"Status: {response.status_code}")

Error Handling and Response Processing

Proper error handling is crucial when working with PUT requests:

import requests
from requests.exceptions import RequestException, Timeout, ConnectionError

def update_resource(url, data, headers=None, timeout=30):
    """
    Send a PUT request with comprehensive error handling
    """
    try:
        response = requests.put(
            url,
            json=data,
            headers=headers,
            timeout=timeout
        )

        # Raise exception for bad status codes
        response.raise_for_status()

        # Process successful response
        if response.status_code == 200:
            return {"success": True, "data": response.json()}
        elif response.status_code == 204:
            return {"success": True, "message": "Updated successfully (no content)"}
        else:
            return {"success": True, "status": response.status_code}

    except Timeout:
        return {"success": False, "error": "Request timed out"}
    except ConnectionError:
        return {"success": False, "error": "Connection error"}
    except requests.exceptions.HTTPError as e:
        return {"success": False, "error": f"HTTP error: {e}"}
    except RequestException as e:
        return {"success": False, "error": f"Request error: {e}"}

# Usage example
update_data = {"name": "Updated Product", "price": 299.99}
result = update_resource(
    'https://api.example.com/products/789',
    update_data,
    headers={'Authorization': 'Bearer your_token'}
)

if result["success"]:
    print("Update successful!")
    if "data" in result:
        print(f"Response data: {result['data']}")
else:
    print(f"Update failed: {result['error']}")

Session-Based PUT Requests

For multiple requests, using a session can improve performance and maintain state:

import requests

# Create a session
session = requests.Session()

# Set default headers for all requests in this session
session.headers.update({
    'Authorization': 'Bearer your_api_token',
    'Content-Type': 'application/json',
    'User-Agent': 'MyApp/1.0'
})

# Multiple PUT requests using the same session
products_to_update = [
    {"id": 1, "data": {"price": 99.99, "stock": 50}},
    {"id": 2, "data": {"price": 149.99, "stock": 25}},
    {"id": 3, "data": {"price": 199.99, "stock": 10}}
]

for product in products_to_update:
    response = session.put(
        f'https://api.example.com/products/{product["id"]}',
        json=product["data"]
    )

    if response.status_code == 200:
        print(f"Product {product['id']} updated successfully")
    else:
        print(f"Failed to update product {product['id']}: {response.status_code}")

# Close the session
session.close()

Content-Type Variations

While JSON is the most common format, you might need to send other content types:

Sending Form Data with PUT

import requests

# Form data instead of JSON
form_data = {
    'name': 'Updated Name',
    'description': 'Updated description'
}

response = requests.put(
    'https://api.example.com/items/123',
    data=form_data  # Use 'data' instead of 'json'
)

Custom Content-Type

import requests
import json

data = {"key": "value"}
custom_json = json.dumps(data)

headers = {
    'Content-Type': 'application/vnd.api+json',  # Custom content type
    'Accept': 'application/vnd.api+json'
}

response = requests.put(
    'https://api.example.com/resources/456',
    data=custom_json,
    headers=headers
)

Best Practices and Tips

1. Always Validate Response Status

import requests

def safe_put_request(url, data):
    response = requests.put(url, json=data)

    # Check for successful status codes
    if response.status_code in [200, 201, 204]:
        return response
    else:
        raise Exception(f"PUT request failed: {response.status_code} - {response.text}")

2. Use Timeouts

Always set timeouts to prevent hanging requests:

response = requests.put(
    'https://api.example.com/data',
    json=data,
    timeout=(5, 30)  # (connection timeout, read timeout)
)

3. Handle Large JSON Payloads

For large datasets, consider streaming:

import requests
import json

def stream_put_request(url, large_data):
    def json_generator():
        yield json.dumps(large_data).encode('utf-8')

    headers = {'Content-Type': 'application/json'}
    response = requests.put(
        url,
        data=json_generator(),
        headers=headers
    )
    return response

Integration with Web Scraping

When building web scraping applications, PUT requests are often used to update scraped data in your backend systems. For complex scenarios involving dynamic content updates, you might also need to handle AJAX requests using Puppeteer for browser-based scraping tasks.

Common HTTP Status Codes for PUT Requests

Understanding the response codes helps in proper error handling:

  • 200 OK: The resource was successfully updated
  • 201 Created: A new resource was created (if PUT is used for creation)
  • 204 No Content: The update was successful, but no content is returned
  • 400 Bad Request: The request data is invalid
  • 401 Unauthorized: Authentication is required
  • 403 Forbidden: The client doesn't have permission
  • 404 Not Found: The resource doesn't exist
  • 422 Unprocessable Entity: The request is valid but cannot be processed

When scraping websites that require authentication or session management, you might find it useful to understand how to handle browser sessions in Puppeteer for more complex authentication flows.

Conclusion

The Python Requests library makes sending PUT requests with JSON data straightforward and flexible. Whether you're updating user profiles, modifying product information, or synchronizing data between systems, the techniques covered in this guide will help you implement robust PUT request functionality in your applications.

Remember to always include proper error handling, use appropriate timeouts, and validate your JSON data before sending requests. For production applications, consider implementing retry logic and logging to make your code more resilient and maintainable.

Try WebScraping.AI for Your Web Scraping Needs

Looking for a powerful web scraping solution? WebScraping.AI provides an LLM-powered API that combines Chromium JavaScript rendering with rotating proxies for reliable data extraction.

Key Features:

  • AI-powered extraction: Ask questions about web pages or extract structured data fields
  • JavaScript rendering: Full Chromium browser support for dynamic content
  • Rotating proxies: Datacenter and residential proxies from multiple countries
  • Easy integration: Simple REST API with SDKs for Python, Ruby, PHP, and more
  • Reliable & scalable: Built for developers who need consistent results

Getting Started:

Get page content with AI analysis:

curl "https://api.webscraping.ai/ai/question?url=https://example.com&question=What is the main topic?&api_key=YOUR_API_KEY"

Extract structured data:

curl "https://api.webscraping.ai/ai/fields?url=https://example.com&fields[title]=Page title&fields[price]=Product price&api_key=YOUR_API_KEY"

Try in request builder

Related Questions

Get Started Now

WebScraping.AI provides rotating proxies, Chromium rendering and built-in HTML parser for web scraping
Icon