Of course! In Python, you can perform HTTP DELETE requests using the urllib library. The most common and modern way to do this is with the request module, which was introduced in Python 3.2 as a more user-friendly replacement for the older urllib2.

Here’s a complete guide, from the basic method to the recommended best practice.
Using urllib.request (Standard Library)
This is the built-in, no-install-required method. It's perfectly capable but can be a bit more verbose.
The Basic Method: urllib.request.urlopen()
This approach is simple but offers less control over the request (e.g., you can't easily add custom headers).
import urllib.request
import json
# The URL of the resource you want to delete
url = "https://jsonplaceholder.typicode.com/posts/1"
try:
# In Python 3, you can pass a data dictionary directly to urlopen.
# For a DELETE request, the data is often included in the URL or body.
# The 'method' argument is the key here.
# We'll send an empty JSON object in the body, as some APIs expect it.
data = json.dumps({}).encode('utf-8') # data must be bytes
req = urllib.request.Request(url, data=data, method='DELETE')
# You can add headers if needed
req.add_header('Content-Type', 'application/json')
req.add_header('Accept', 'application/json')
print(f"Sending DELETE request to: {url}")
with urllib.request.urlopen(req) as response:
# The response is a file-like object. Read the data.
response_data = response.read().decode('utf-8')
response_status = response.getcode()
print(f"\nResponse Status Code: {response_status}")
print("Response Body:")
print(response_data)
except urllib.error.HTTPError as e:
print(f"\nError: {e.code} {e.reason}")
# You can read the error response body
error_body = e.read().decode('utf-8')
print("Error Response Body:")
print(error_body)
except urllib.error.URLError as e:
print(f"\nFailed to reach the server. Reason: {e.reason}")
except Exception as e:
print(f"\nAn unexpected error occurred: {e}")
Explanation:

urllib.request.Request(url, data=data, method='DELETE'): This creates a request object. We explicitly set themethodto'DELETE'. Thedataargument is required when you specify a method other than GET or POST, even if the data is empty.data = json.dumps({}).encode('utf-8'): Thedataparameter must be in bytes. We create an empty JSON object , convert it to a JSON string, and then encode it to bytes.req.add_header(...): This is how you add custom headers, likeContent-Type, which is crucial for APIs that expect JSON.with urllib.request.urlopen(req) as response:: This sends the request and opens the response. Using awithstatement ensures the response is closed properly.response.read().decode('utf-8'): Reads the raw bytes from the response and decodes them into a UTF-8 string.response.getcode(): Gets the HTTP status code (e.g., 200 for success, 404 for not found).except urllib.error.HTTPError: This block catches HTTP errors like 404 (Not Found) or 401 (Unauthorized), which are common when deleting resources.
The Recommended Best Practice: requests Library
While urllib is built-in, the requests library is the de facto standard for making HTTP requests in Python. It's significantly more user-friendly, readable, and powerful.
First, you'll need to install it:
pip install requests
Now, let's perform the same DELETE request using requests.
import requests
import json
# The URL of the resource you want to delete
url = "https://jsonplaceholder.typicode.com/posts/1"
try:
# The `requests.delete()` function makes it incredibly simple.
# You can pass data as a dictionary for the JSON body.
# The `headers` can be a simple dictionary.
response = requests.delete(
url,
json={}, # Automatically sets Content-Type to application/json and encodes the data
headers={'Accept': 'application/json'}
)
# The `response` object has convenient attributes
print(f"Sending DELETE request to: {url}")
print(f"\nResponse Status Code: {response.status_code}")
# `response.json()` will parse the JSON response into a Python dict
if response.status_code == 200:
print("Response Body (parsed as JSON):")
print(response.json())
else:
# If the response is not JSON, you can still access the text
print("Response Body (text):")
print(response.text)
except requests.exceptions.HTTPError as e:
# This will raise an HTTPError for bad responses (4xx or 5xx)
print(f"\nError: {e.response.status_code} {e.response.reason}")
print("Error Response Body:")
print(e.response.text)
except requests.exceptions.RequestException as e:
# This is the base class for all requests-related exceptions
print(f"\nAn error occurred with the request: {e}")
Why requests is often preferred:

- Simplicity:
requests.delete()is a single, clear function call. - Automatic Encoding: Passing a
jsondictionary automatically handles the encoding and sets the correctContent-Typeheader. - Intuitive Response Object:
response.status_code,response.json(), andresponse.textare very easy to use. - Better Exception Handling: The exception hierarchy is more specific and easier to work with.
- Session Management:
requests.Sessionmakes it easy to persist parameters and cookies across multiple requests.
Summary: urllib.request vs. requests
| Feature | urllib.request (Standard Library) |
requests (Third-Party Library) |
|---|---|---|
| Installation | Built-in (No installation needed) | pip install requests |
| Simplicity | Verbose. Requires manual encoding and header management. | Very simple and intuitive. |
| JSON Handling | Manual: json.dumps().encode(). |
Automatic: json={} parameter. |
| Response Object | A generic file-like object. | A rich Response object with convenient attributes (status_code, json(), etc.). |
| Recommendation | Use when you cannot install external libraries or are in a restricted environment. | Highly recommended for almost all Python projects involving HTTP requests. |
