Reputation: 1811
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 :)
Upvotes: 3
Views: 10490
Reputation: 21
To be able to catch a JSON response from http.server using requests library, another words to use response.json()
you should make the following on the server side:
from http.server import BaseHTTPRequestHandler
import json
class GetHandler(BaseHTTPRequestHandler):
def do_GET(self):
json_data = {'token': 'qfrwefewrtweygds--fefef==wef'}
json_to_pass = json.dumps(json_data)
self.send_response(code=200, message='here is your token')
self.send_header(keyword='Content-type', value='application/json')
self.end_headers()
self.wfile.write(json_to_pass.encode('utf-8'))
This thing worked for me.
Upvotes: 2
Reputation: 25779
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))
Upvotes: 5
Reputation: 19154
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)
Upvotes: 2