我有一个用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!'}