Example
curl 'https://api.example.com/search?q=shoes&page=2' \
-H 'Accept: application/json' \
-b 'session=abc123' \
-u admin:secret \
--max-time 10
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
| curl | requests |
|---|---|
-X PUT | requests.put(…), or requests.request('PURGE', …) for custom methods |
-H 'Name: value' | headers={'Name': 'value'} |
?a=1 in the URL, or -G -d a=1 | params={'a': '1'} |
-d 'a=1&b=2' | data={'a': '1', 'b': '2'} |
--json or JSON with a JSON Content-Type | json={…} |
-F 'f=@file.txt' | files={'f': ('file.txt', open('file.txt', 'rb'))} |
-u user:pass | auth=('user', 'pass') |
--digest -u user:pass | auth=HTTPDigestAuth('user', 'pass') |
-b 'a=1; b=2' | cookies={'a': '1', 'b': '2'} |
-k | verify=False |
-m 10 | timeout=10 |
-x http://proxy:3128 | proxies={'http': …, 'https': …} |
-L | Default (requests follows redirects, except for HEAD) |
File uploads
curl -F 'title=Holiday' -F 'photo=@beach.jpg;type=image/jpeg' https://api.example.com/photos
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.