Python Falcon - 获取POST数据

问题描述 投票:6回答:5

我尝试在我的项目中使用falcon包。问题是我没有找到从HTTP post请求获取正文数据的方法。

我使用了示例中的代码,但req.stream.read()没有按预期返回JSON。

代码是:

raw_json = req.stream.read()
result.json(raw_json, encoding='utf-8')
resp.body = json.dumps(result_json, encoding='utf-8')

如何获取POST数据?

谢谢你的帮助

python python-3.x http-post falconframework falcon
5个回答
6
投票

很少挖掘问题导致以下linked issue on github。它声明falcon框架至少在其0.3版本中并且与Python 2一起工作时,如果它们被适当地转义,则不会将数据“POSTed”解析为字符串。我们可以使用有关您尝试通过POST请求发送的数据以及发送的格式的更多信息,例如,它是作为简单文本发送,还是使用Header Information Content-Type:application / json,或者如果是通过HTML表单。

虽然问题的确切问题不明确,我仍然可以建议尝试使用bounded_stream而不是stream,如:

raw_json = req.bounded_stream.read()
result.json(raw_json, encoding='utf-8')
resp.body = json.dumps(result_json, encoding='utf-8')

官方文档建议使用bounded_stream,其中不确定条件如Content-Length undefined或0,或者如果标题信息完全丢失。

bound_stream在官方falcon documentation中描述如下。

类似于文件的流包装器,用于规范不同WSGI服务器使用的本机输入对象之间的某些差异。特别是,bounded_stream知道正文的预期Content-Length,并且永远不会阻止越界读取,假设客户端在将数据传输到服务器时没有停顿。

Falcon接收HTTP请求数据作为缓冲区对象,由WSGI包装器传递,它从客户端接收数据,并且由于性能原因,它可能无法在数据之上运行正确的解析以转换为更有用的数据结构。


3
投票

你正在寻找的领域有点混乱,但它是req.media

返回请求流的反序列化形式。调用时,它将尝试使用Content-Type标头以及通过falcon.RequestOptions配置的媒体类型处理程序反序列化请求流。

如果请求是JSON,req.media已经包含python dict。


1
投票

我在falcon框架中添加了request.py中的更改来解析application / x-www-form-urlencoded和multipart / from-data。我已经提出拉动请求 - https://github.com/falconry/falcon/pull/1236但它还没有合并到主人。检查一下 - https://github.com/branelmoro/falcon

我添加了新代码来解析POST,PUT和DELETE application / x-www-form-urlencoded和multipart / form-data。文本字段将在req.form_data字典中可用,上载文件缓冲区流将在req.files字典中可用。

我希望这有助于分别访问POST和GET参数,我们也可以上传文件。改变的好处是它不会将整个上传的文件加载到内存中。

下面是示例代码,用于说明如何使用POST,PUT和DELETE application / x-www-form-urlencoded和multipart / form-data:

import falcon

class Resource(object):

    def on_post(self, req, resp):

        # req.form_data will return dictionary of text field names and their values
        print(req.form_data)

        # req.form_data will return dictionary of file field names and
        # their buffer class FileStream objects as values
        print(req.files)

        # support we are uploading a image.jpg in `pancard` file field then
        # req.files["pancard"] will be FileStream buffer object

        # We can use set_max_upload_size method to set maximum allowed
        # file size let say 1Mb = 1*1024*1024 bytes for this file

        req.files["pancard"].set_max_upload_size(1*1024*1024)

        # We can use uploadto method to upload file on required path (Note: absolute filepath is required)
        # This method returns boolean - `True` on successful upload
        # and if upload is unsuccessful then it returns `False` and sets error on failure.
        path = "/tmp/" + req.files["pancard"].name

        response = req.files["pancard"].uploadto("/tmp/" + path)

        print(response)

        # Once file is uploaded sucessfully, we can check it's size
        print(req.files["pancard"].size)

        # If file is not uploaded sucessfully, we can check it's error
        print(req.files["pancard"].error)

        resp.body = "Done file upload"

        resp.status = falcon.HTTP_200

# falcon.API instances are callable WSGI apps
app = falcon.API()

things = Resource()

# things will handle post requests to the '/post_path' URL path
app.add_route('/post_path', things)

如果您有任何疑问,请告诉我。


1
投票

非常感谢Ryan(和Prateek Jain)的回答。

解决方案就是放app.req_options.auto_parse_form_urlencoded=True。例如:

import falcon

class ThingsResource(object):
    def on_post(self, req, resp):
        value = req.get_param("value", required=True)
        #do something with value

app = falcon.API()
app.req_options.auto_parse_form_urlencoded=True

things = ThingsResource()

app.add_route('/things', things)

1
投票

在猎鹰2中,如果你使用json类型,请使用req.media

例如:

import falcon
from json import dumps

class Resource(object):
    def on_post(self, req, resp, **kwargs):
        result = req.media
        # do your job
        resp.body = dumps(result)


api = falcon.API()

api.add_route('/test', Resource())

0
投票

到目前为止...对我来说bounded_stream.read()和stream.read()都将发布的数据作为str类型。到目前为止,我只找到了解决问题的方法:

def on_post(self, req, resp):
    posted_data = json.loads(req.stream.read())
    print(str(type(posted_data)))
    print(posted_data)

收到发布的数据后,将字符串加载到json dict是我能想到的唯一解决方案

© www.soinside.com 2019 - 2024. All rights reserved.