Converting cURL Commands to Python Requests: A Comprehensive Guide
cURL is a ubiquitous command-line tool for making HTTP requests, widely used by developers for testing APIs, downloading data, and interacting with web services. While powerful, integrating cURL commands directly into applications can be cumbersome. Python’s requests library, on the other hand, provides an elegant and Pythonic way to send HTTP requests, making it the de facto standard for HTTP communication in Python.
This article will guide you through the process of converting common cURL commands into their requests library equivalents, covering various aspects from basic requests to handling authentication, proxies, and file uploads.
Why Convert cURL to Python Requests?
- Programmatic Control: Integrate HTTP requests seamlessly into your Python scripts for automation, data processing, and application development.
- Readability and Maintainability: Python
requestscode is generally more readable and easier to maintain than shell commands embedded in scripts. - Error Handling:
requestsprovides robust mechanisms for handling network errors, HTTP status codes, and other exceptions. - Feature Rich: Leverage
requestsfeatures like session management, automatic cookie handling, and advanced authentication methods.
Let’s dive into the conversions.
1. Basic GET and POST Requests
cURL GET Request:
bash
curl "https://api.example.com/data"
Python Requests GET Equivalent:
“`python
import requests
url = “https://api.example.com/data”
response = requests.get(url)
print(response.status_code)
print(response.json()) # Assuming JSON response
“`
cURL POST Request with Data (Form-Encoded):
bash
curl -X POST -d "param1=value1¶m2=value2" "https://api.example.com/submit"
Python Requests POST (Form-Encoded) Equivalent:
“`python
import requests
url = “https://api.example.com/submit”
data = {
“param1”: “value1”,
“param2”: “value2”
}
response = requests.post(url, data=data)
print(response.status_code)
print(response.json())
“`
cURL POST Request with JSON Data:
bash
curl -X POST -H "Content-Type: application/json" -d '{"key": "value"}' "https://api.example.com/json_submit"
Python Requests POST (JSON) Equivalent:
“`python
import requests
import json
url = “https://api.example.com/json_submit”
headers = {
“Content-Type”: “application/json”
}
payload = {
“key”: “value”
}
response = requests.post(url, headers=headers, json=payload)
print(response.status_code)
print(response.json())
``requests
*Note:automatically sets theContent-Type: application/jsonheader when using thejson` parameter.*
2. Handling Headers
cURL uses the -H option for custom headers.
cURL with Headers:
bash
curl -H "User-Agent: MyCustomAgent/1.0" -H "X-API-Key: your_api_key" "https://api.example.com/protected"
Python Requests Headers Equivalent:
“`python
import requests
url = “https://api.example.com/protected”
headers = {
“User-Agent”: “MyCustomAgent/1.0”,
“X-API-Key”: “your_api_key”
}
response = requests.get(url, headers=headers)
print(response.status_code)
“`
3. Authentication
a) Basic Authentication (-u)
cURL uses -u for basic authentication.
bash
curl -u "username:password" "https://api.example.com/auth"
Python Requests Basic Auth Equivalent:
“`python
import requests
url = “https://api.example.com/auth”
username = “username”
password = “password”
response = requests.get(url, auth=(username, password))
print(response.status_code)
“`
b) Bearer Token Authentication (via Headers)
Common for OAuth2 and JWT.
bash
curl -H "Authorization: Bearer your_bearer_token" "https://api.example.com/secure_data"
Python Requests Bearer Token Equivalent:
“`python
import requests
url = “https://api.example.com/secure_data”
token = “your_bearer_token”
headers = {
“Authorization”: f”Bearer {token}”
}
response = requests.get(url, headers=headers)
print(response.status_code)
“`
4. Handling Cookies
cURL handles cookies with -b (send cookies) and -c (save cookies).
cURL with Cookies:
bash
curl -b "sessionid=xyz; csrftoken=abc" "https://api.example.com/profile"
Python Requests Cookies Equivalent:
“`python
import requests
url = “https://api.example.com/profile”
cookies = {
“sessionid”: “xyz”,
“csrftoken”: “abc”
}
response = requests.get(url, cookies=cookies)
print(response.status_code)
“`
For handling cookies across multiple requests (like cURL’s -c for saving cookies and -b for sending them in subsequent requests), use a requests.Session object:
“`python
import requests
session = requests.Session()
First request, cookies are automatically stored in the session
response1 = session.get(“https://api.example.com/login”, auth=(“user”, “pass”))
print(f”Login Status: {response1.status_code}”)
Subsequent requests automatically send cookies stored in the session
response2 = session.get(“https://api.example.com/dashboard”)
print(f”Dashboard Status: {response2.status_code}”)
“`
5. Proxies
cURL uses -x or --proxy for proxy settings.
bash
curl -x "http://proxy.example.com:8080" "https://api.example.com/external"
Python Requests Proxies Equivalent:
“`python
import requests
url = “https://api.example.com/external”
proxies = {
“http”: “http://proxy.example.com:8080”,
“https”: “http://proxy.example.com:8080”, # Use ‘https’ key for HTTPS requests
}
response = requests.get(url, proxies=proxies)
print(response.status_code)
“`
For authenticated proxies:
python
proxies = {
"http": "http://user:[email protected]:8080",
"https": "http://user:[email protected]:8080",
}
6. SSL/TLS Verification (--insecure or -k)
cURL’s -k or --insecure option disables SSL certificate verification.
bash
curl -k "https://self-signed.example.com/data"
Python Requests SSL Verification Equivalent:
By default, requests verifies SSL certificates. To disable it (use with caution in production!):
“`python
import requests
url = “https://self-signed.example.com/data”
response = requests.get(url, verify=False) # Disable SSL verification
print(response.status_code)
“`
7. Timeouts
While cURL can specify connection timeouts (e.g., --connect-timeout), requests offers a more flexible timeout parameter for both connection and read timeouts.
“`python
import requests
url = “https://api.example.com/slow_endpoint”
try:
# Timeout after 5 seconds (connection and read)
response = requests.get(url, timeout=5)
print(response.status_code)
except requests.exceptions.Timeout:
print(“Request timed out.”)
except requests.exceptions.RequestException as e:
print(f”An error occurred: {e}”)
“`
8. Handling File Uploads (-F)
cURL uses the -F option for multipart/form-data uploads.
bash
curl -F "file=@/path/to/your/image.jpg" -F "description=My uploaded image" "https://api.example.com/upload"
Python Requests File Upload Equivalent:
“`python
import requests
url = “https://api.example.com/upload”
files = {
“file”: (“image.jpg”, open(“/path/to/your/image.jpg”, “rb”), “image/jpeg”),
}
data = {
“description”: “My uploaded image”
}
response = requests.post(url, files=files, data=data)
print(response.status_code)
print(response.json())
``files
*Note: The tuple foris(filename, file_object, content_type).requestswill infer theContent-Type` if not provided, but it’s good practice to specify it.*
9. Tips and Best Practices
- External Converters: For complex cURL commands, tools like
curlconverter.comcan be a quick way to get a starting Pythonrequestssnippet. - Error Handling: Always wrap your
requestscalls intry-exceptblocks to handle network issues, timeouts, and otherrequests.exceptions.RequestExceptionerrors. Useresponse.raise_for_status()to raise anHTTPErrorfor bad responses (4xx or 5xx). - Session Objects: For making multiple requests to the same host, especially when dealing with authentication and cookies, use a
requests.Sessionobject. It provides connection pooling and persistent cookies, leading to better performance and cleaner code.
“`python
with requests.Session() as session:
session.auth = (‘user’, ‘pass’)
session.headers.update({‘x-test’: ‘true’})# All requests made with 'session' will use these auth and headers session.get('https://httpbin.org/headers')* **Parameters**: For URL query parameters, use the `params` argument in `requests` instead of manually constructing the URL string. This handles URL encoding automatically.python
params = {“key1”: “value1”, “key2”: “value2”}
response = requests.get(“https://api.example.com/search”, params=params)URL will be https://api.example.com/search?key1=value1&key2=value2
``requests` code clean and well-commented. Break down complex requests into smaller, manageable parts.
* **Readability**: Keep your
Conclusion
Converting cURL commands to Python requests is a fundamental skill for anyone working with web APIs in a programmatic context. The requests library offers a powerful, flexible, and Pythonic interface for HTTP communication, making it an indispensable tool in your development arsenal. By following the examples and best practices outlined in this guide, you can confidently transition your command-line interactions into robust and maintainable Python applications.