python json.loads(req.stream.read().decode("utf-8")) завершается неудачно на on_post

У меня есть веб-сервис, написанный на Python 2.7, который использует платформу Falcon. Один конкретный метод принимает пост значений JSON. Мой код:

 def on_post(self, req, resp):
    response = dict()
    try:
        data = simplejson.load(req.stream.read().decode("utf-8"))
        logger.info(data)
        mapUrl = data['url']
        #mapUrl = req.get_params("url", None)
        response['url'] = add_google_key(mapUrl)
        resp.status = falcon.HTTP_200
        resp.body = simplejson.dumps(response)
    except Exception, ex:
        response['error'] = "Error occured"
        resp.status = falcon.HTTP_400
        resp.body = simplejson.dumps(response)
        return resp

Я перепробовал так много всего, что нашел в Stack и Google, но без изменений. Я работаю над Pycharm IDE, и это просто время ожидания при выполнении simplejson.load(req.stream.read().decode("utf-8"))

Другие вещи, которые я пытался все не читать JSONjson.loads(req.stream.read().decode("utf-8"))

Запрос curl я пытаюсь

POST /add HTTP/1.1
Host: 127.0.0.1:8000
Content-Type: application/json
Cache-Control: no-cache

{
"url": "www.google.com"
}

Среда: OSX Sierra Python 2.7 Falcon 0.3.0 и другие являются последней версией из Pip

2 ответа

Добавляя к другому недавно опубликованному ответу,req.streamэто, действительно, необработанный поток непосредственно с сервера приложений. Falcon предлагает тот же обходной путь, что и; см. также: Почему req.stream.read() зависает для определенных запросов?

Чтение данных изreq.bounded_stream:

      def on_post(self, req, resp):
    data = simplejson.loads(req.bounded_stream.read().decode())
    logger.info(data)
    # ...

Также безопасно следующее:

      def on_post(self, req, resp):
    data = json.load(req.bounded_stream)
    logger.info(data)
    # ...

Однако для стандартных типов интернет-медиа, таких как JSON, вы также можете проверить встроенную обработку мультимедиа Falcon, которая обеспечивает ту же функциональность с еще меньшим количеством шаблонов:

      def on_post(self, req, resp):
    data = req.get_media()
    logger.info(data)
    # ...

    # You can also set response JSON by simply assigning to resp.media
    resp.media = {'message': 'Hello from Stack Overflow!'}

В нормальных условиях req.stream является экземпляром<class gunicorn.http.body.Body>. Однако при тестировании это<class wsgiref.validate.InputWrapper>. У обоих есть методы read(), но они различаются как таковые:

gunicorn.http.body.Body:

      def read(self, size=None):
size = self.getsize(size)
if size == 0:
    return b""
# ...snip...

wsgiref.validate.InputWrapper:

      def read(self, *args):
assert_(len(args) == 1)
v = self.input.read(*args)
assert_(type(v) is bytes)
return v

InputWrapper выдает AssertionError, потому что вызовreq.stream.read()в моем промежуточном программном обеспечении не объявляется значение размера! Обычно в этом нет необходимости, потому что gunicorn устанавливает размер автоматически, но InputWrapper только утверждает, что его нужно установить.

Решение

      # previous code
data = simplejson.load(req.stream.read(req.content_length or 0))
# remaining code
Другие вопросы по тегам