无法使用Flask从弹性bean读取JSON消息

2024-05-29 05:24:39 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个Python“worker”,它使用弹性Beanstalk从SQS读取消息。这是很好的工作,虽然缩放是笨重的,因为它是基于cpu。因此,我试图将其转换为使用AWS新的“Worker-Tier-Environment”。在

在深部有烧瓶,但我有烧瓶在电子商务工作层运行。目前,它被设置为只记录它接收到的消息信息-这是为了确保在我移动其他所有内容之前我可以读取这些信息。不幸的是我看不到任何信息的迹象?在

这是我的烧瓶测试代码:

import logging
import logging.handlers

from flask import Flask, request

logfile = "/opt/python/log/scan.log"
mylog = logging.getLogger('helloworld')
# (for brevity, log format/config code removed)

application = Flask(__name__)
app = application
app.Debug=True

@app.route('/', methods=['POST'])
def hello():
    global mylog
    err = "Unrecognized method"
    mylog.warning("Hello called")

    request_detail = """
# Before Request #
request.endpoint: {request.endpoint}
request.method: {request.method}
request.view_args: {request.view_args}
request.args: {request.args}
request.form: {request.form}
request.user_agent: {request.user_agent}
request.files: {request.files}
request.is_xhr: {request.is_xhr}
## request.headers ##
{request.headers}
    """.format(request=request).strip()
    mylog.warning(request_detail)

    mylog.warning("Moreinfo:")

    mylog.warning("Args:")
    for k in request.args.keys():
        mylog.warning(k + ": "+request.args[k])
    mylog.warning("Form:")
    for k in request.form.keys():
        mylog.warning(k + ": "+request.form[k])
    mylog.warning("Files:"+len(request.files))
    for k in request.files.keys():
        mylog.warning(k + ": "+request.files[k])

    try:
        myJSON = request.get_json(force=True)
        if myJSON is None:
            mylog.warning("JSON could not be forced")
        else:
            mylog.warning("MyJSON size: " + len(myJSON))
            mylog.warning( "MyJSON: {myJSON}".format(myJSON=myJSON))
        if request.json is None:
            mylog.warning("NO JSON")
    except Exception as e:
        mylog.warning("Exception: " + e)

    # the code below is executed if the request method
    # was GET or the credentials were invalid
    mylog.warning("failure 404")
    return 'Failure: '+err , 404, {'Content-Type': 'text/plain'}


if __name__ == '__main__':
    app.run(host='0.0.0.0', debug=True)

是的,那个大的长格式语句是从一本书中借来的:-)

以下是消息的典型日志输出:

^{pr2}$

注意,不可变的multidict结构似乎没有任何键。 而且,没有任何JSON方法/属性返回任何内容。在

Content-Length字段在日志条目之间确实有所不同,因此看起来信息确实存在。但我该怎么读呢?在

我的JSON消息使用BOTO写入SQS,例如:

  my_queue = conn.get_queue('my_queue_name')
  m = Message()
  m.set_body( json.dumps( my_structure ) )
  my_queue.write(m)

我还尝试使用sqsweb接口手工输入一个原始JSON消息。这也不起作用-我猜测我们可能有字符编码问题/


Tags: form信息jsonapp消息forifis
1条回答
网友
1楼 · 发布于 2024-05-29 05:24:39

不清楚为什么要切断消息日志记录;可能是您出现了缩进错误,并且部分日志代码未被视为视图方法的一部分。在

但是,如果我理解正确,botosqs消息不仅被编码为JSON,JSON消息本身也是base64 encoded,这意味着flask.get_json()方法不会为您解码它。在

相反,请使用^{} method访问原始POST数据并自行解码;请先验证request.content_length值是否在可接受的大小内,以防止攻击者向您发送过大的消息:

from flask import json
import base64

if request.mime_type == 'application/json' and request.content_length <= 1024**2:
    # message is JSON and smaller than 1 megabyte
    try:
        decoded = base64.b64decode(request.get_data())
        data = json.loads(decoded)
    except (ValueError, TypeError):
        mylog.exception('Failed to decode JSON')
    else:
        # do something with the decoded data

相关问题 更多 >

    热门问题