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