1

I'm trying to use an API with curl, returning a JSON:

response=$(curl -i --user api:$APIKey --data-binary @$target https://api.tinypng.com/shrink)

Next, I try to parse (briefly) the response with a function:

parseJson(){
    result="$1"
    result=($(echo $result | python -mjson.tool))
    result=${result%\"*}
    result=${result##*\"}
    return $result
}

and I'm calling it like this: message=$(parseJson "$response" message). FYI, the response is on multiple lines.

But weird thing happened: python gave me No JSON object could be decoded, but if I echoed $result there is a good JSON string. Weirder, if I echoed it before calling python, it looks like python is executed first anyway.

Is there some asynchronous trick ? Why can't I pass my variable string to python ?

Any help or better method will be greatly appreciated!

2
  • are you sure that the string you receive is an actual json string? Did you check it for instance on jsonformatter.curiousconcept.com ? Commented Dec 3, 2013 at 15:59
  • I tested it in a terminal, worked great. Even tested it without the bash function, worked too. That's why I wondered if passing it as an argument could affect it somehow Commented Dec 3, 2013 at 16:10

2 Answers 2

2

No JSON Object could be decoded and the response is on multiple lines are the keys here I think. That error is usually returned from mjson.tools on an empty string, whereas malformed JSON generally returns something more verbose.

The JSON parser will not look past the first newline (outside of a quote string value). It is probably receiving something like \r\n{"key":"value"} and failing. If the response is on multiple lines for some reason, then you should parse out the response body (JSON) without leading or trailing \r\n's

Sign up to request clarification or add additional context in comments.

1 Comment

You were right, my echoes didn't show me there was lines before my JSON (HTTP header mostly). When I strip those whith tail it works perfectly!
1

You can try HttpConnection instead of calling curl and do everything directly in python:

conn = httplib.HTTPConnection('www.a_url.com')
conn.request("GET", /index.html')
response = conn.getresponse()
status = response.status
if status != 200:
    print 'ERROR'
    sys.exit(1)
reason = response.reason
answer = response.read()

in order to get the json just do:

received_json = None
try:
    json.loads(answer)
except:
    print 'ERROR'
    sys.exit(2)

2 Comments

I'm not very familiar with Python, so how am I supposed to set my curl paramaters (--user & --data-binary) to my HTTPConnection? Thanks
That might be a different question. But have a look for example at stackoverflow.com/q/34079/1141095 though it's not HttpConnection, the same should work in my example

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.