DevToolsmith

cURL to Python Converter

Convert curl commands to Python code using the requests library. Query strings become params, cookies become a cookies dict, JSON bodies become Python dicts, and -F uploads become files=. Paste a command from your terminal, API docs or your browser’s Copy as cURL.

Runs 100% in your browser — nothing is uploaded

curl command
Tip: drop a file here236 chars · 236 bytes · 4 lines
Python · requests
451 chars · 451 bytes · 30 lines

Install: pip install requests

Parsed request

POST https://api.example.com/v1/orders?notify=true

  • Authorization: Bearer YOUR_API_TOKEN
  • Content-Type: application/json
  • Body: JSON

Example

curl
curl 'https://api.example.com/search?q=shoes&page=2' \
  -H 'Accept: application/json' \
  -b 'session=abc123' \
  -u admin:secret \
  --max-time 10
Python (requests)
import requests

params = {
    'q': 'shoes',
    'page': '2',
}

cookies = {
    'session': 'abc123',
}

headers = {
    'Accept': 'application/json',
}

response = requests.get(
    'https://api.example.com/search',
    params=params,
    cookies=cookies,
    headers=headers,
    auth=('admin', 'secret'),
    timeout=10,
)
print(response.status_code)
print(response.json())

curl options in requests

curlrequests
-X PUTrequests.put(…), or requests.request('PURGE', …) for custom methods
-H 'Name: value'headers={'Name': 'value'}
?a=1 in the URL, or -G -d a=1params={'a': '1'}
-d 'a=1&b=2'data={'a': '1', 'b': '2'}
--json or JSON with a JSON Content-Typejson={…}
-F 'f=@file.txt'files={'f': ('file.txt', open('file.txt', 'rb'))}
-u user:passauth=('user', 'pass')
--digest -u user:passauth=HTTPDigestAuth('user', 'pass')
-b 'a=1; b=2'cookies={'a': '1', 'b': '2'}
-kverify=False
-m 10timeout=10
-x http://proxy:3128proxies={'http': …, 'https': …}
-LDefault (requests follows redirects, except for HEAD)

File uploads

curl
curl -F 'title=Holiday' -F 'photo=@beach.jpg;type=image/jpeg' https://api.example.com/photos
Python (requests)
import requests

files = [
    ('title', (None, 'Holiday')),
    ('photo', ('beach.jpg', open('beach.jpg', 'rb'), 'image/jpeg')),
]

response = requests.post(
    'https://api.example.com/photos',
    files=files,
)
print(response.status_code)
print(response.text)

Open files in binary mode ('rb'), and close them when done, for example with a with block. Making many requests to the same host? Create a requests.Session() and call session.post(…); it reuses connections and keeps cookies between calls. Parsing the JSON response into typed objects? Generate models with JSON to Pydantic.

Frequently asked questions

What is the difference between json= and data= in requests?

json= takes a Python object, serialises it to JSON and sets Content-Type: application/json for you. data= sends a dict as form fields (application/x-www-form-urlencoded) or a string or bytes as is. The converter uses json= when the curl body is valid JSON sent as JSON, and data= otherwise. json= re-serializes the body, so the request means the same thing but the bytes can differ (spacing after commas and colons, non-ASCII characters escaped); the converter points out when that happens. If the server needs curl’s exact bytes, for example to check a signature, send the original string with data= instead.

How do I convert curl -k to Python?

Pass verify=False. requests will then print an InsecureRequestWarning on every call. Use it only for testing; for an internal CA, point verify at its certificate bundle instead: verify="/path/to/ca.pem".

Why does the code have a timeout?

Only if the curl command had -m or --connect-timeout. Note that requests has no timeout by default, so a call can hang forever. Adding timeout=(3.05, 30) (connect, read) to every request is good practice even when curl didn’t set one.

How are file uploads (-F file=@path) converted?

They become the files= argument, with a (filename, file object, content type) tuple for each file. Plain -F fields are written as (None, value), which keeps them in the same multipart body, exactly like curl does.

Can I use httpx instead of requests?

Yes. For simple requests the code is the same after replacing import requests with import httpx: httpx.get, httpx.post, params=, headers=, json=, data=, files=, auth= and timeout= all exist. The main differences: httpx doesn’t follow redirects unless you pass follow_redirects=True, and with an httpx.Client, options like verify= are set when creating the client rather than on each request.