Python
cURL
Programming
Scripting
Automation

How to use Python to execute a cURL command?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

If you already have a working curl command and want to call it from Python, the direct solution is to run the command with subprocess. In many cases, though, the better solution is to skip curl entirely and make the HTTP request with a Python library such as requests.

The right choice depends on why curl is involved. Use subprocess when you truly need the curl executable or want to reuse an existing shell command. Use requests when your goal is simply to send HTTP traffic from Python code.

Execute curl Safely with subprocess

The safest standard-library approach is subprocess.run with a list of arguments. Passing a list avoids shell-quoting problems and reduces injection risk.

python
1import subprocess
2
3result = subprocess.run(
4    [
5        "curl",
6        "-sS",
7        "-H", "Accept: application/json",
8        "https://api.github.com"
9    ],
10    capture_output=True,
11    text=True,
12    check=True
13)
14
15print(result.stdout)

Key options:

  • 'capture_output=True collects standard output and standard error'
  • 'text=True returns decoded strings instead of bytes'
  • 'check=True raises an exception if the command exits with a non-zero status'

If curl is not installed or not on your PATH, Python raises FileNotFoundError.

Pass Headers, Data, and Authentication

The same pattern works for POST requests:

python
1import subprocess
2
3payload = '{"name":"Ada","role":"admin"}'
4
5result = subprocess.run(
6    [
7        "curl",
8        "-sS",
9        "-X", "POST",
10        "-H", "Content-Type: application/json",
11        "-H", "Authorization: Bearer MY_TOKEN",
12        "-d", payload,
13        "https://example.com/api/users"
14    ],
15    capture_output=True,
16    text=True,
17    check=True
18)
19
20print(result.stdout)

Notice that the JSON body is passed as one argument. That is another reason to prefer argument lists over manually building one long shell string.

Avoid os.system

You may see examples using os.system, but it gives you poor error handling and makes quoting harder:

python
1import os
2
3exit_code = os.system("curl -sS https://api.github.com")
4print(exit_code)

This works for simple cases, but you do not get structured access to output, and failures are harder to diagnose. For new code, subprocess.run is the right default.

Prefer Native HTTP in Python When Possible

If the goal is just to call an API, the requests library is usually cleaner:

python
1import requests
2
3response = requests.get(
4    "https://api.github.com",
5    headers={"Accept": "application/json"},
6    timeout=10
7)
8
9response.raise_for_status()
10print(response.json())

This removes the external dependency on curl, gives you native access to status codes and JSON parsing, and keeps your code cross-platform.

A good rule is:

  • use subprocess if you already depend on a specific curl invocation
  • use requests if you are writing normal Python application code

Capture Errors Clearly

When you call curl through subprocess, capture both standard output and standard error so failures are visible:

python
1import subprocess
2
3try:
4    result = subprocess.run(
5        ["curl", "-sS", "https://bad.example.invalid"],
6        capture_output=True,
7        text=True,
8        check=True
9    )
10except subprocess.CalledProcessError as error:
11    print("Command failed")
12    print("Exit code:", error.returncode)
13    print("stderr:", error.stderr)

That gives you enough information to distinguish DNS failures, TLS errors, or HTTP-related command options problems.

Common Pitfalls

  • Building one shell string from untrusted input instead of passing an argument list to subprocess.run.
  • Using os.system and then struggling to capture output or diagnose failures.
  • Assuming curl exists on every machine where the Python script runs.
  • Using curl from Python when a native HTTP library would be simpler and easier to maintain.

Summary

  • Use subprocess.run with a list of arguments when you need to execute curl from Python.
  • Capture output and enable check=True so failures are visible and actionable.
  • Avoid os.system for anything beyond trivial experiments.
  • Prefer requests when you only need to send HTTP requests and do not specifically need the curl executable.
  • Choose the approach that matches the actual dependency in your project instead of wrapping shell commands by habit.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.