2016-10-09 3 views
0

Я пробовал Falcon для небольшого проекта api. К сожалению, я застрял в json parsing и код из примеров документации не работает.Falcon parsing json error

Я пробовал так много вещей, которые я нашел на Stack и Google, но никаких изменений. Я попытался следующие коды, которые приводят к ошибкам ниже

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'""" 

Я на пути подачи, но если кто-нибудь может сказать мне, почему это происходит и как разобрать JSON в Соколе я бы быть чрезвычайно благодарным.

Благодаря

Окружающая среда: OSX Sierra Python 3.5.2 Сокол и другие это последняя версия от Пипа

ответ

1

ваш код должен работать, если другие части кода на месте. быстрый тест (имя файла 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) 

бег с: gunicorn app
$ curl -XPOST 'localhost:8000' -d '{"Hello":"wold"}'

+0

Привет и спасибо за ваш ответ. Пример - это в значительной степени то, что у меня было, но в результате была сделана копия, в результате которой «TypeError: объект JSON должен быть str, а не« байтами ». Протестирован на Ubuntu в виртуальной машине, и он отлично работал. Это странно. Пытался переустановить, но не помог. Идеи? :-) – Audunfr

+0

@Audunfr, если вы правильно ответите на этот вопрос, примите его. – anekix

1

Вы должны вызвать encode() на байт, возвращаемых read() с чем-то вроде req.stream.read().encode('utf-8').

Таким образом, байты преобразуются в str, как ожидается, json.loads().

Другой способ не беспокоиться обо всем этом скучном и подверженном ошибкам кодировании/декодировании и байтах/str материалах (который BTW отличается в Py2 и Py3), заключается в использовании simplejson в качестве замены для json. Он совместим с API, поэтому единственным изменением является замена import jsonimport simplejson as json в вашем коде.

Кроме того, он упрощает код, так как считывание тела может быть выполнено с помощью json.load(req.bounded_stream), что намного короче и читаемо, чем json.loads(req.bounded_stream.read().encode('utf-8')).

Теперь я сделаю так, и больше не использую стандартный модуль json.