How to convert a curl command to Python requests
By TabBenchHow we check our guides
A curl command in the documentation is easy to run but hard to build on. To call the same API from a script, a notebook or a service, you need Python code, and each curl flag maps to a different part of the requests library: headers become a dictionary, a JSON body becomes json=, a file upload becomes files=, and a timeout has to be added explicitly.
This guide explains each translation, the defaults where Python and curl differ, and how to choose between requests, httpx and the standard-library urllib.
Step by step
Paste the command and pick a library
Copy the curl command (from API docs, or from DevTools with Copy as cURL) and paste it into the converter. requests is the everyday choice and is installed with pip install requests. httpx has the same shape with async support and HTTP/2. urllib ships with Python and is the right choice only when nothing can be installed.
Translate headers and bodies
-H entries become a headers dictionary. A JSON body is passed as json=payload, where payload is a Python dict; requests serialises it and sets the Content-Type. A form body from -d or --data-urlencode becomes data={...}. Multipart uploads from -F become files={...} with the file name and content type, plus data={...} for ordinary fields.
Carry over authentication
-u user:password becomes auth=('user', 'password'), which requests turns into a Basic Authorization header. Bearer tokens stay as a header. Keep tokens in environment variables with os.environ rather than in source files.
Add what curl did implicitly
requests has no default timeout, so a stalled server can block your script forever: always pass timeout=. curl does not follow redirects without -L, whereas requests follows them for GET requests, so use allow_redirects=False to match. -k becomes verify=False, which should stay out of production. Call response.raise_for_status() so that 4xx and 5xx responses raise an exception instead of passing silently.
Run it and read the response
response.status_code holds the status, response.json() parses a JSON body and response.text returns the body as a string. For many calls to the same host, create a requests.Session so connections are reused, which is much faster than a new connection for each call.
Things worth knowing
- Use json= for JSON and data= for forms. Passing a dict to data= sends form encoding, not JSON.
- httpx times out after five seconds by default and does not follow redirects unless follow_redirects=True.
- urllib raises HTTPError for 4xx and 5xx responses, unlike requests, and has no multipart helper.
- Be careful scraping: only call endpoints you are allowed to use, and respect rate limits and robots rules.
Frequently asked questions
How do I upload a file from Python?
What is the difference between data= and json= in requests?
Should I use requests or httpx?
Related tools
cURL to Fetch Converter
Convert a curl command to JavaScript fetch code.
cURL Command Generator
Build a correct curl command from a form, for any shell.
cURL to Axios Converter
Convert a curl command to Axios code for JavaScript.