Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Returning JSON using a GET request from server

I have a simple server from here, and when the GET function is called, I would like it to return a JSON file, as show in the relevant code snippet below:

from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
import json

class S(BaseHTTPRequestHandler):
    def _set_headers(self):
        self.send_response(200)
        self.send_header('Content-type', 'application/json')
        self.end_headers()

    def do_GET(self):
        self._set_headers()
        with open('test.json') as data_file:    
            data = json.load(data_file)
        self.wfile.write(data)

My json file:

{"foo": "bar", "boo": "far"}

The application requesting the file (client.py):

import requests
import json

r = requests.get('http://localhost:8080')
print r.json()

However, when trying to run client.py I get the following error:

ValueError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)

Am I correctly loading the test.json file in the do_GET function?

Thanks for your help :)

like image 649
monadoboi Avatar asked Dec 12 '25 05:12

monadoboi


2 Answers

Let's make it a bit better for an answer :)

The whole problem is that you're parsing test.json on in your server and then print string representation of it to your client. Consider a simple JSON like:

{"foo": "bar", "baz": "far"}

When you load and parse it as JSON, and then print it, you'll get a string representation of a Python dict it was parsed into, which, while very similar, is no longer JSON:

import json

data = '{"foo": "bar", "baz": "far"}'  # we'll use a string instead of a file for testing
parsed = json.loads(data)
print(parsed)  # equivalent to printing `str(parsed)`

Which will yield (on Python 2.x, on Python 3.x there are no unicode markings but the rest is the same):

{u'foo': u'bar', u'baz': u'far'}

And that's how your data gets sent from the server - as a string representation of a Python dict. Notice, for example, those u prefixes denoting a unicode string? Those are the culprits (in this instance).

Now, if you were to load it back and try to parse it as JSON:

import json 

data = "{u'foo': u'bar', u'baz': u'far'}"
parsed = json.loads(data)

You would get your ValueError: Expecting property name: line 1 column 2 (char 1) error.

To avoid that, don't parse your JSON if you want to send it over to your client, so a simple:

with open('test.json') as data_file:
    self.wfile.write(data_file.read())

should suffice. In case you need to do some pre-processing to your JSON, then you need to serialize it back to JSON before sending, e.g.:

with open('test.json') as data_file:    
    data = json.load(data_file)
    data["boo"] = "baz"
    self.wfile.write(json.dumps(data))
like image 84
zwer Avatar answered Dec 14 '25 19:12

zwer


json.load is not needed replace it with data_file.read()

def do_GET(self):
    self._set_headers()
    with open('test.json') as data_file:    
        data = data_file.read()
    self.wfile.write(data)
like image 24
ewwink Avatar answered Dec 14 '25 19:12

ewwink



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!