Back to Updates
DevTool Team

From curl to Python requests: A Flag-by-Flag Conversion Guide with Live Examples

Got a curl command and need Python requests code? This guide walks the mapping flag by flag: -H to headers, -d to data, -u to Authorization, -G to query strings — with worked examples for JSON requests, cookie sessions, and scraper workflows, plus a one-click converter you can run the output in.

Why developers keep converting curl to Python

Right-click a request in browser DevTools, choose "Copy as cURL", and you get a complete command: URL, headers, body, cookies — everything. The next step is usually reproducing that request in Python: scrapers, API clients, automation checks. The mapping itself is mechanical, but with many flags it's easy to miss one — drop an -H and you get a 401; drop --data-raw and the method silently becomes GET.

Mechanical translation is exactly what tools are for: the curl command converter takes the pasted command, generates requests code instantly when you pick the Python target, and can send it straight into the online Python runner to execute.

The mapping, flag by flag

Start with a typical command:

curl 'https://api.example.com/v1/users' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer demo-token' \
  --data-raw '{"name":"Ada","role":"admin"}'

The converted Python:

import requests

url = "https://api.example.com/v1/users"
headers = {
    "Content-Type": "application/json",
    "Authorization": "Bearer demo-token",
}
data = '{"name":"Ada","role":"admin"}'

response = requests.post(url, headers=headers, data=data, allow_redirects=False)
print(response.status_code)
print(response.text)

Where each flag lands:

curl form requests landing spot Notes
URL (first argument) url quoting preserved
-H 'name: value' one entry in the headers dict later duplicates override earlier
-d / --data-raw data string multiple -d joined with &
-X POST requests.post inferred as POST when -d present, no -X
-u user:pass auth=(user, pass) or hand-write the Authorization Basic header
-b 'k=v' Cookie header in headers prefer Session for sessions
-G data moves into the query string method falls back to GET
-k verify=False test environments only
-L default (omit allow_redirects=False) curl defaults to not following; requests follows
-A 'UA/1.0' / -e 'url' User-Agent / Referer headers curl semantics are just header sets

One trap worth knowing: when curl has a body but no Content-Type, it sends application/x-www-form-urlencoded by default. A good converter adds that header for you (curlconverter.com and this site's tool both do); otherwise servers may parse the body as raw text and return 400.

JSON requests: choosing between data and json

Converting --data-raw '{"name":"Ada"}' yields the string form. To use the json parameter, parse it into a dict first:

import json

payload = {"name": "Ada", "role": "admin"}
response = requests.post(url, headers=headers, json=payload)

json=payload serializes automatically and sets Content-Type: application/json. Both forms behave identically on the wire — pick by team convention: the string form means smaller diffs while tweaking payloads; the dict form reads better in business code.

Cookies and login state: Session is the answer

curl's -b 'session=xyz' converts to a single Cookie header — fine for one request. But once you hit more endpoints on the same site, hand-managing cookies falls apart. requests' Session catches Set-Cookie automatically:

session = requests.Session()
session.headers.update({"User-Agent": "MyApp/1.0"})

login = session.post("https://api.example.com/login", data={"user": "ada", "pass": "***"})
profile = session.get("https://api.example.com/me")  # login state carried over

The typical scraper pipeline: copy the login request from DevTools → convert to Python → switch to Session → loop the pages. Every step's mapping is in the table above.

How to pick a converter

Three practical criteria:

  1. Flag coverage: -H/-d/--data-raw/--json/-u/-b/-G/-L/-k plus combined shorts (-sSL) and multi-line continuations are the high-frequency set; missing any one means manual patching.
  2. Error feedback: when a command fails to parse, a tool that points at the offending flag halves your debugging time; one that only says "parse error" is a tier below.
  3. What happens after conversion: can the generated code run immediately? The curl converter on this site sends its Python output straight into the online runner (requests built in), so you see the status code and body on the spot; Go and Java targets work the same way, while PHP and C++ are copy-only.

Frequently Asked Questions

How do I convert a curl command into Python requests code?

Map it in three steps: the URL becomes the first argument; each -H "name: value" goes into the headers dict; the -d/--data-raw content becomes the data string, with requests.post as the method (curl with -d and no -X is a POST). An online converter skips the manual work: paste the command, pick Python, and the code generates instantly — and can be sent straight into an online runner to verify.

Should I use data or json when converting a curl JSON request to Python?

Both send JSON. With data you must ensure the string is valid JSON and set the Content-Type: application/json header yourself; with json you pass a dict and requests serializes and sets the header automatically. Converting from curl -d or --json yields the string form first — confirm the structure, then switch to the json parameter.

What do curl's -b and -u become in Python?

-b "name=value" becomes a Cookie request header; for cookie-backed sessions, switch to requests.Session() to persist login state. -u user:pass maps to auth=("user", "pass"), which requests turns into an Authorization Basic header — no manual Base64 needed.

Why does the converted Python code fail with 'No module named requests'?

requests is a third-party library — run pip install requests first. Online runtimes (like this site's Python runner) ship with requests built in, so pasting the generated code there runs immediately: handy for verifying logic before moving it into a local project.