用 Bottle 处理 application/json 数据

发布于 2024-11-03 01:05:01 字数 737 浏览 0 评论 0 原文

我正在尝试使用基于 Restful JSON 的协议向 python3 应用程序编写一个简单的服务器前端。到目前为止, bottle 似乎是最适合该任务的框架(它支持 python3,以一种很好的方式处理方法分派,并且很容易返回 JSON。)问题是解析输入请求中的 JSON。

该文档仅提到 request.fields 和 request.files ,我认为两者都指的是 multipart/form-data 数据。没有提到直接访问请求数据。

查看源代码,我可以看到一个 BytesIO 类型的 request.body 对象。 json.load 拒绝直接对其进行操作,在 json 库中因 can't use a string pattern on a bytes-like object 而死掉。正确的方法可能是首先根据 Content-Type HTTP 标头中指定的字符集将字节解码为 un​​icode 字符。我不知道该怎么做;我可以看到一个 StringIO 类,并假设它可能保存一个字符缓冲区而不是字节,但看不到将 BytesIO 解码为 StringIO 的方法,如果这甚至可能的话。

当然,也可以将 BytesIO 对象读入字节串,然后将其解码为字符串,然后将其传递给 JSON 解码器,但如果我理解正确的话,这会破坏整个事物的良好缓冲行为。

或者有什么更好的方法吗?

I'm trying to write a simple server frontend to a python3 application, using a restful JSON-based protocol. So far, bottle seems the best suited framework for the task (it supports python3, handles method dispatching in a nice way, and easily returns JSON.) The problem is parsing the JSON in the input request.

The documentation only mention request.fields and request.files, both I assume refer to multipart/form-data data. No mention of accessing the request data directly.

Peeking at the source code, I can see a request.body object of type BytesIO. json.load refuses to act on it directly, dying in the json lib with can't use a string pattern on a bytes-like object. The proper way to do it may be to first decode the bytes to unicode characters, according to whichever charset was specified in the Content-Type HTTP header. I don't know how to do that; I can see a StringIO class and assume it may hold a buffer of characters instead of bytes, but see no way of decoding a BytesIO to a StringIO, if this is even possible at all.

Of course, it may also be possible to read the BytesIO object into a bytestring, then decode it into a string before passing it to the JSON decoder, but if I understand correctly, that breaks the nice buffering behavior of the whole thing.

Or is there any better way to do it ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

勿挽旧人 2024-11-10 01:05:01

似乎标准中的 io.TextIOWrapper图书馆就可以解决这个问题!

def parse(request):
    encoding = ... #get encoding from headers
    return json.load(TextIOWrapper(request.body, encoding=encoding))

It seems that io.TextIOWrapper from the standard library does the trick !

def parse(request):
    encoding = ... #get encoding from headers
    return json.load(TextIOWrapper(request.body, encoding=encoding))
吃→可爱长大的 2024-11-10 01:05:01

正如评论中提到的(以及类似的答案),request.json 方法从 Bottle 0.1.0 开始可用。

所以就像:

@route('/endpoint', method='POST')
def parse():
    body = request.json
    name = body.get('name')
    age = body.get('age')

As mentioned in a comment (and in a similar SO answer), the request.json method was made available from bottle 0.1.0.

So like:

@route('/endpoint', method='POST')
def parse():
    body = request.json
    name = body.get('name')
    age = body.get('age')
手心的温暖 2024-11-10 01:05:01

以下是我使用 Python3 和 Bottle 在 RESTful 服务上读取 json 的操作:

import bson.json_util as bson_json

@app.post('/location/API')
def post_json_example():
    """
    param: _id, value
    return: I usually return something like {"status": "successful", "message": "discription"}
    """

    query_string = bottle.request.query.json
    query_dict = bson_json.loads(query_string)
    _id = query_dict['_id']
    value = query_dict['value']

然后从 python3 解释器进行测试

Here's what I do to read in json on a RESTful service with Python3 and Bottle:

import bson.json_util as bson_json

@app.post('/location/API')
def post_json_example():
    """
    param: _id, value
    return: I usually return something like {"status": "successful", "message": "discription"}
    """

    query_string = bottle.request.query.json
    query_dict = bson_json.loads(query_string)
    _id = query_dict['_id']
    value = query_dict['value']

Then to Test

晨光如昨 2024-11-10 01:05:01

我写了一个助手来使用 b0fh 的好主意。
经过 2 周的 response.json 分析后,我连接到 StackOver Flow 并了解到我们需要解决

以下问题:

def json_app_rqt():
    # about request
    request.accept = 'application/json, text/plain; charset=utf-8'

def json_app_resp():
    # about response
    response.headers['Access-Control-Allow-Origin'] = _allow_origin
    response.headers['Access-Control-Allow-Methods'] = _allow_methods
    # response.headers['Access-Control-Allow-Headers'] = _allow_headers
    response.headers['Content-Type'] = 'application/json; charset=utf-8'

def json_app():
    json_app_rqt()
    json_app_resp()

def get_json_request(rqt):
    with TextIOWrapper(rqt.body, encoding = "UTF-8") as json_wrap:
        json_text = ''.join(json_wrap.readlines())
        json_data = json.loads(json_text)
        return json_data

对于使用,我们可以做:

if __name__ == "__main__":

    json_app()

    @post("/train_control/:control")
    def do_train_control(control):
        json_app_resp()

        data = get_json_request(request)
        print(json.dumps(data))

        return data

感谢所有人

I wrote an helper to use the good idea of b0fh.
After 2 weeks on response.json analyzing, I connect to StackOver Flow and understand that we need a work around

Here is:

def json_app_rqt():
    # about request
    request.accept = 'application/json, text/plain; charset=utf-8'

def json_app_resp():
    # about response
    response.headers['Access-Control-Allow-Origin'] = _allow_origin
    response.headers['Access-Control-Allow-Methods'] = _allow_methods
    # response.headers['Access-Control-Allow-Headers'] = _allow_headers
    response.headers['Content-Type'] = 'application/json; charset=utf-8'

def json_app():
    json_app_rqt()
    json_app_resp()

def get_json_request(rqt):
    with TextIOWrapper(rqt.body, encoding = "UTF-8") as json_wrap:
        json_text = ''.join(json_wrap.readlines())
        json_data = json.loads(json_text)
        return json_data

For the using, we cand do:

if __name__ == "__main__":

    json_app()

    @post("/train_control/:control")
    def do_train_control(control):
        json_app_resp()

        data = get_json_request(request)
        print(json.dumps(data))

        return data

Thanks to all

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文