代码之家  ›  专栏  ›  技术社区  ›  James Adams

Flask:尽管返回了200响应代码,但仍存在未知错误

  •  0
  • James Adams  · 技术社区  · 5 年前

    我创建了一个简单的Flask RESTful API,其中有一个用于服务GET请求的函数,需要几个URL参数:

    import logging
    
    from flask import Flask
    from flask_restful import Api, Resource
    from webargs import fields
    from webargs.flaskparser import abort, parser, use_args
    
    # initialize the Flask application and API
    app = Flask(__name__)
    api = Api(app)
    
    
    # ------------------------------------------------------------------------------
    # set up a basic, global logger object which will write to the console
    logging.basicConfig(level=logging.INFO,
                        format="%(asctime)s %(levelname)s  %(message)s",
                        datefmt="%Y-%m-%d  %H:%M:%S")
    _logger = logging.getLogger(__name__)
    
    
    # ------------------------------------------------------------------------------
    class Abc(Resource):
    
        abc_args = {"rtsp": fields.Url(required=True),
                    "start": fields.Integer(required=True),
                    "duration": fields.Integer(required=True),
                    "bucket": fields.String(required=True),
                    "prefix": fields.String(missing="")}
    
        @use_args(abc_args)
        def get(self, args) -> (str, int):
    
            _logger.info("Recording video clip with the following parameters:\n"
                         f"\tRTSP URL: {args['rtsp']}"
                         f"\tStart seconds: {args['start']}"
                         f"\tDuration seconds: {args['duration']}"
                         f"\tS3 bucket: {args['bucket']}"
                         f"\tS3 key prefix: {args['prefix']}")
    
            return "OK", 200
    
    
    # ------------------------------------------------------------------------------
    # This error handler is necessary for usage with Flask-RESTful
    @parser.error_handler
    def handle_request_parsing_error(err, req, schema, error_status_code, error_headers):
        """
        webargs error handler that uses Flask-RESTful's abort function to return
        a JSON error response to the client.
        """
        abort(error_status_code, errors=err.messages)
    
    
    # ------------------------------------------------------------------------------
    if __name__ == '__main__':
        api.add_resource(Abc, "/abc", endpoint="abc")
        app.run(debug=True)
    

    当我向端点发送带有或不带参数的GET请求时,我没有得到预期的行为——如果GET请求中包含好的参数,那么我希望在控制台中看到一条日志消息,如果不存在任何必需的参数,那么我希望得到某种错误。相反,我在控制台中得到了200个响应代码,在主浏览器窗口中只得到了短语“未知错误”。

    http://127.0.0.1:5000/abc 然后我在控制台中看到:

    2019-05-28  17:42:14 INFO  127.0.0.1 - - [28/May/2019 17:42:14] "GET /abc HTTP/1.1" 200 -
    

    我的假设是,上面应该抛出某种错误,表明缺少URL参数。

    如果我在Chrome浏览器的地址栏中输入以下带有预期参数的URL: http://127.0.0.1:5000/abc?rtsp=rtsp://user:passwd@171.25.14.15:554&start=1559076593&duration=10&bucket=testbucket&prefix=test.

    2019-05-28  17:45:31 INFO  127.0.0.1 - - [28/May/2019 17:45:31] "GET /abc?rtsp=rtsp://user:passwd@171.25.14.15:554&start=1559076593&duration=10&bucket=testbucket&prefix=test. HTTP/1.1" 200 -
    

    我的假设是,上述情况应该会导致记录器将信息消息打印到控制台,如中所定义 Abc.get

    如果我使用 curl 在命令行中,我得到以下结果:

    $ curl "http://127.0.0.1:5000/abc?rtsp=rtsp://user:passwd@171.25.14.15:554&start=1559076593&duration=10&bucket=testbucket&prefix=test."
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
    <title>None Unknown Error</title>
    <h1>Unknown Error</h1>
    <p></p>
    

    我在Ubuntu 18.04上的Anaconda环境(Python 3.7)中使用Flask 1.0.3、Flask Restful 0.3.6和Webargs 5.3.1。

    0 回复  |  直到 5 年前
        1
  •  0
  •   James Adams    5 年前

    flask_restful . 见下文:

    import logging
    
    from flask import Flask, request
    
    # initialize the Flask application
    app = Flask(__name__)
    
    
    # ------------------------------------------------------------------------------
    # set up a basic, global logger object which will write to the console
    logging.basicConfig(level=logging.INFO,
                        format="%(asctime)s %(levelname)s  %(message)s",
                        datefmt="%Y-%m-%d  %H:%M:%S")
    _logger = logging.getLogger(__name__)
    
    
    # ------------------------------------------------------------------------------
    @app.route('/clip', methods=['GET'])
    def record_and_store_clip():
    
        message = "Recording video clip with the following parameters:\n" + \
                  f"\tRTSP URL: {request.args.get('rtsp')}\n" + \
                  f"\tStart seconds: {request.args.get('start')}\n" + \
                  f"\tDuration seconds: {request.args.get('duration')}\n" + \
                  f"\tS3 bucket: {request.args.get('bucket')}\n" + \
                  f"\tS3 key prefix: {request.args.get('prefix')}\n"
    
        _logger.info(message)
    
        return message
    
    
    # ------------------------------------------------------------------------------
    if __name__ == '__main__':
        app.run(debug=True)