Reputation: 37
I'm trying out Falcon for a small api project. Unfortunate i'm stuck on the json parsing stuff and code from the documentation examples does not work.
I have tried so many things i've found on Stack and Google but no changes. I've tried the following codes that results in the errors below
import json
import falcon
class JSON_Middleware(object):
def process_request(self, req, resp):
raw_json = json.loads(req.stream.read().decode('UTF-8'))
"""Exception: AttributeError: 'str' object has no attribute 'read'"""
raw_json = json.loads(req.stream.read(), 'UTF-8')
"""Exception: TypeError: the JSON object must be str, not 'bytes'"""
raw_json = json.loads(req.stream, 'UTF-8')
"""TypeError: the JSON object must be str, not 'Body'"""
I'm on the way of giving up, but if somebody can tell me why this is happening and how to parse JSON in Falcon i would be extremely thankful.
Thanks
Environment: OSX Sierra Python 3.5.2 Falcon and other is the latest version from Pip
Upvotes: 1
Views: 2214
Reputation: 219
You have to invoke encode()
on the bytes returned by read()
with something like req.stream.read().encode('utf-8')
.
This way the bytes are converted to a str as expected by json.loads()
.
The other way not to bother with all this boring and error prone encode/decode and bytes/str stuff (which BTW differs in Py2 and Py3), is to use simplejson as a replacement for json. It is API compatible, so the only change is to replace import json
with import simplejson as json
in your code.
In addition, it simplifies the code since reading the body can be done with json.load(req.bounded_stream)
, which is much shorter and more readable than json.loads(req.bounded_stream.read().encode('utf-8'))
.
I now do it this way, and don't use the standard json module any more.
Upvotes: 1
Reputation: 2563
your code should work if other pieces of code are in place . a quick test(filename app.py):
import falcon
import json
class JSON_Middleware(object):
def process_request(self, req, resp):
raw_json = json.loads(req.stream.read())
print raw_json
class Test:
def on_post(self,req,resp):
pass
app = application = falcon.API(middleware=JSON_Middleware())
t = Test()
app.add_route('/test',t)
run with: gunicorn app
$ curl -XPOST 'localhost:8000' -d '{"Hello":"wold"}'
Upvotes: 2