Skip to content
TabBench

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.

Open the cURL to Python ConverterFree, no sign-up, and your file never leaves your browser.

Step by step

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. 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?

Pass files={'file': open('photo.jpg', 'rb')} to requests.post, optionally as a tuple of file name, file object and content type. Other form fields go in data=. The converter builds this from curl -F.

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

data= sends form-encoded fields (or raw text or bytes). json= serialises a Python object to JSON and sets Content-Type: application/json. Use json= for JSON APIs.

Should I use requests or httpx?

requests is simple and ubiquitous. Choose httpx if you need async code, HTTP/2 or a stricter default for redirects and timeouts. Their APIs are very similar, so switching later is easy.