Curl is generating status 400 in subprocess

Viewed 222

I run a curl command on windows command line prompt. It produces a json output. The command looks like this:

curl --data "action=details&user=user&project=project1&problemid=2021" https://website:9020/

I issue the same command in python as following:

import subprocess
output = subprocess.run(
                [
                    "curl",
                    "--data",
                    "\"action=details&user=user&project=project1&problemid=2021\""
                    "https://website:9020/",
                ],
                stdout=subprocess.PIPE,
                stderr=subprocess.STDOUT,
                shell=True,
            )
print(output.stdout.decode("utf-8"))

The output is the following:

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   199  100    64  100   123     64    123  0:00:01 --:--:--  0:00:01  1254
{"status":400,"message":"Action parameter is missing"}

But the command line produces a json output. Yet the same command issued through subprocess.run produces this error. I also tried it with subprocess.Popen and subprocess.check_output. Same issue persists. What am I doing wrong here that is causing this error?

2 Answers

In some cases (e.g. if they require running command line as administrator), subprocess might not be the right choice to execute the command line commands.

You can use os.system() to see the output or os.popen() to read and store the output.

import os
import json

# to see the output 
print(os.system("curl --data \"action=details&user=user&project=project1&problemid=2021\" https://website:9020/")

output = os.popen("curl --data \"action=details&user=user&project=project1&problemid=2021\" https://website:9020/").read()

outputjson = json.loads(output)

then you can access the json information.

Did you try running your code without the quotation marks around the action parameter? Because the API is complaining about missing action parameter. I think it's just not recognising it due to the escaped quotation marks.

import subprocess
output = subprocess.run(
    [
        "curl",
        "--data",
        "action=details&user=user&project=project1&problemid=2021"
        "https://website:9020/",
    ],
    stdout=subprocess.PIPE,
    stderr=subprocess.STDOUT,
    shell=True,
)
print(output.stdout.decode("utf-8"))

EDIT: I'm not sure if this is the case, but it could be that subprocess implicitly surrounds all its parameters with quotation marks in order to avoid code injection and globbing.

I was just googling again and found this answer, which states it quite well: why would you use curl, if you could use requests?

No guarantee, but I think something like this should work:

import requests
url = "https://website:9020/"
payload = {
    "action": "details",
    "user": "user",
    "project": "project1",
    "problemid": "2021"
}
res = requests.get(url, params=payload)
Related