Python json.loads(req.stream.read().decode( "utf-8" )) 在on_post上失败



我有一个用Python 2.7编写的Web服务,它使用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

我正在研究pycharm IDE,它只是在执行时超时 simplejson.load(req.stream.read().decode("utf-8"))

我尝试过的其他事情都无法读取 json json.loads(req.stream.read().decode("utf-8"))

我正在尝试的卷曲请求:

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 的最新版本

在正常情况下,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 抛出一个断言错误,因为在我的中间件中调用req.stream.read()没有声明大小的值!通常不需要它,因为 gunicorn 会自动设置大小,但 InputWrapper 只断言需要设置它。

溶液

# previous code
data = simplejson.load(req.stream.read(req.content_length or 0))
# remaining code

加上最近发布的另一个答案,req.stream确实是直接来自应用程序服务器的原始流。猎鹰提供了与req.bounded_stream相同的解决方法;另请参阅:为什么 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!'}

相关内容

  • 没有找到相关文章

最新更新