user2848437
user2848437

Reputation: 61

return http error code for curl in python

status, output = commands.getstatusoutput("curl -k -v --cookie cookie_name 'URL' -o filename")

Above is my code , I am trying to return http response code of curl. So i tried the following option -w %{http_code}

status, output = commands.getstatusoutput("curl -k -v --cookie cookie_name -w %{http_code} 'URL' -o filename")

When i run it in python script and print status, nothing gets printed. Can someone please help me with the curl return code? I want to try scenario's like when username password is wrong to get a status, or when the network host is not reachable or content not downloaded properly.

Upvotes: 0

Views: 4766

Answers (2)

jfs
jfs

Reputation: 414395

commands.getstatusoutput("cmd") is equivalent to { cmd ; } 2>&1 i.e., stdout/stderr are merged. curl prints the http code to stdout. You could use subprocess.check_output to get only stdout:

import shlex
from subprocess import check_output

DEVNULL = open(os.devnull, 'wb', 0)

curl_cmd = "curl -k --cookie ... -w %{http_code} -o filename 'URL'"
http_code = int(check_output(shlex.split(curl_cmd), stderr=DEVNULL))

As others already said, you don't need to start a subprocess to make an http request in Python : you could use urllib2, pycurl, requests libraries instead e.g.:

import urllib2
from shutil import copyfileobj

url = 'http://httpbin.org/status/418'
# to load cookies from file, you could use cookielib module
request = urllib2.Request(url, headers={'Cookie': 'cookie_name=value'})
try: # both `curl -k` and urllib2 do not verify ssl certificates
    response = urllib2.urlopen(request)
except urllib2.HTTPError as e:
    http_code = e.code
else:
    http_code = response.code
print(http_code)
if http_code == 200: # save to file
    with open('filename', 'wb') as output_file:
        copyfileobj(response, output_file)
response.close()

Upvotes: 1

AliBZ
AliBZ

Reputation: 4099

As the other guys suggested, it is better to use HTTP to do a curl call. requests is the easiest way:

import requests

data = {
    ...
}
r = requests.post(url, data=data)
print r.content

r.content contains the response body and if you need the status code just use r.status_code.

Upvotes: 1

Related Questions