Readable Python from any curl command
The requests library is the most popular way to call HTTP APIs from Python, and its keyword arguments map neatly onto curl's options. This curl to Python converter produces idiomatic code: headers, query parameters, cookies and JSON bodies become Python dictionaries instead of long encoded strings, so the request is easy to read and modify.
Example
curl -X POST 'https://api.example.com/v1/orders?notify=true' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer YOUR_API_TOKEN' \
-d '{"sku":"LAMP-01","qty":2}' \
--max-time 30import requests
headers = {
'Authorization': 'Bearer YOUR_API_TOKEN',
}
params = {
'notify': 'true',
}
json_data = {
'sku': 'LAMP-01',
'qty': 2,
}
response = requests.post('https://api.example.com/v1/orders',
headers=headers,
params=params,
json=json_data,
allow_redirects=False,
timeout=30,
)
print(response.status_code)
print(response.text)Notice that the Content-Type: application/json header disappears: passing json= makes requests serialize the body and set that header automatically.
How the conversion works
- Query string – parameters in the URL are moved into a
paramsdict. - JSON bodies – parsed and written as Python literals (
True,False,None) forjson=. - Form data – URL-encoded bodies become a
datadict;-Ffields becomedataandfileswithopen(path, 'rb'). - Cookies – a
Cookieheader or-bvalue becomes acookiesdict. - Auth –
-u user:passbecomesauth=('user', 'pass'). - Redirects – curl does not follow redirects unless you pass
-L, while requests does. The converter addsallow_redirects=Falseso behavior matches; remove it or add-Lto follow redirects. - TLS and proxies –
-kbecomesverify=False(for testing only) and-xbecomes aproxiesdict. - Timeouts –
--connect-timeoutand-mbecometimeout=(connect, total).
Supported curl options
| curl option | Meaning |
|---|---|
-X, --request | HTTP method (GET, POST, PUT, PATCH, DELETE…) |
-H, --header | Request headers |
-d, --data, --data-raw, --data-binary, --data-urlencode | Request body; implies POST |
--json | JSON body with Content-Type and Accept headers |
-F, --form | Multipart form fields and file uploads |
-u, --user and --oauth2-bearer | Basic and bearer authentication |
-b, --cookie, -A, -e | Cookies, user agent and referer |
-G, --get | Send -d data as query string |
-L, -k, -m, -x, -I, -T | Follow redirects, skip TLS checks, timeout, proxy, HEAD request, upload file |
Line continuations (\), single and double quotes are parsed like a Unix shell. Options that only affect curl's own output, such as -s, -v or -o, are ignored silently; any other unsupported option is listed as a comment at the top of the generated code, so nothing is dropped without notice.
Next steps
- Run the script with Python 3 in a virtual environment so the requests package does not conflict with system packages.
- Always keep a
timeout; without one, requests can wait indefinitely. - Call
response.raise_for_status()to turn HTTP errors into exceptions, andresponse.json()to parse JSON responses. - Load tokens from environment variables (
os.environ['API_TOKEN']) instead of committing them. - For many requests to the same host, use a
requests.Session()to reuse connections.
Need a different language? Use cURL to PHP or cURL to JavaScript. To inspect the response format first, send the request with the API tester. Conversion happens locally in your browser.