【问题标题】:Flask route /predict returns name error on return objectFlask route /predict 在返回对象上返回名称错误
【发布时间】:2019-03-27 17:02:28
【问题描述】:

目前我的 Flask 应用程序可以在我的本地机器上运行,并且可以很好地将主页加载到 heroku。但是,当我调用我的路由 /predict 时,它会返回一个(NameError: name 'diagnosis' is not defined。)

在 /predict 路线中,我尝试了两次返回诊断结果,这不是我通常会尝试的。

我知道 h12 是一个超时错误,但我相信这是因为路由在 30 秒的时间限制内从未响应。

应用链接 https://lesionlegion1.herokuapp.com/

@app.route('/predict', methods=['GET', 'POST'])
def upload():
    # data = {"success": False}
    if request.method == 'POST':
        print(request)

        if request.files.get('file'):
            # read the file
            file = request.files['file']

            # read the filename
            # filename = file.filename

            # create a path to the uploads folder
            # filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename)

            basepath = os.path.dirname(__file__)
            filepath = os.path.join(
                basepath, 'uploads', secure_filename(file.filename))

            # Save the file to the uploads folder
            file.save(filepath)

           # Load the saved image using Keras and resize it to the Xception
            # format of 299x299 pixels
            image_size = (75, 100)
            im = keras.preprocessing.image.load_img(filepath,
                                                    target_size=image_size,
                                                    grayscale=False)

            # preprocess the image and prepare it for classification
            image = prepare_image(im)

            global graph
            with graph.as_default():

                labels = ['Melanocytic nevi', 'Melanoma', 'Benign keratosis-like lesions', 'Basal cell carcinoma',
                          'Actinic keratoses', 'Vascular lesions', 'Dermatofibroma']

                labels = tuple(labels)

                global preds
                preds = model.predict(image)

                # convert preds array to list
                preds = preds.tolist()

                # convert list of lists to one list for rounding to work
                flat_preds = [item for sublist in preds for item in sublist]

                updated_preds = list(
                    map(lambda x: (round(x*100, 3)), flat_preds))

                dictionary = dict(zip(labels, updated_preds))

                # create a function which returns the value of a dictionary

                def keyfunction(k):
                    return dictionary[k]

            global diagnosis
            diagnosis = []

            # sort by dictionary by the values and print top 3 {key, value} pairs
            for key in sorted(dictionary, key=keyfunction, reverse=True)[:3]:

                if dictionary[key] > 0:
                    diagnosis.append([key, str(dictionary[key]) + "%"])

            return jsonify(diagnosis)
    return jsonify(diagnosis)


if __name__ == "__main__":
    app.run(port=5002, debug=True, threaded=False)

heroku 日志

2019-03-27T16:47:43.394981+00:00 heroku[router]: at=info method=GET path="/predi
ct" host=lesionlegion1.herokuapp.com request_id=6a8b52fa-33c4-4c23-881f-25a626bc
73ae fwd="96.35.158.2" dyno=web.1 connect=1ms service=5ms status=500 bytes=455 p
rotocol=https
2019-03-27T16:47:43.392702+00:00 app[web.1]: [2019-03-27 16:47:43,390] ERROR in
app: Exception on /predict [GET]
2019-03-27T16:47:43.392716+00:00 app[web.1]: Traceback (most recent call last):
2019-03-27T16:47:43.392719+00:00 app[web.1]: File "/app/.heroku/python/lib/pytho
n3.6/site-packages/flask/app.py", line 2292, in wsgi_app
2019-03-27T16:47:43.392721+00:00 app[web.1]: response = self.full_dispatch_reque
st()
2019-03-27T16:47:43.392723+00:00 app[web.1]: File "/app/.heroku/python/lib/pytho
n3.6/site-packages/flask/app.py", line 1815, in full_dispatch_request
2019-03-27T16:47:43.392725+00:00 app[web.1]: rv = self.handle_user_exception(e)
2019-03-27T16:47:43.392726+00:00 app[web.1]: File "/app/.heroku/python/lib/pytho
n3.6/site-packages/flask/app.py", line 1718, in handle_user_exception
2019-03-27T16:47:43.392728+00:00 app[web.1]: reraise(exc_type, exc_value, tb)
2019-03-27T16:47:43.392729+00:00 app[web.1]: File "/app/.heroku/python/lib/pytho
n3.6/site-packages/flask/_compat.py", line 35, in reraise
2019-03-27T16:47:43.392732+00:00 app[web.1]: raise value
2019-03-27T16:47:43.392734+00:00 app[web.1]: File "/app/.heroku/python/lib/pytho
n3.6/site-packages/flask/app.py", line 1813, in full_dispatch_request
2019-03-27T16:47:43.392735+00:00 app[web.1]: rv = self.dispatch_request()
2019-03-27T16:47:43.392736+00:00 app[web.1]: File "/app/.heroku/python/lib/pytho
n3.6/site-packages/flask/app.py", line 1799, in dispatch_request
2019-03-27T16:47:43.392738+00:00 app[web.1]: return self.view_functions[rule.end
point](**req.view_args)
2019-03-27T16:47:43.392739+00:00 app[web.1]: File "/app/app.py", line 133, in up
load
2019-03-27T16:47:43.392741+00:00 app[web.1]: return jsonify(diagnosis)
2019-03-27T16:47:43.392746+00:00 app[web.1]: NameError: name 'diagnosis' is not
defined
2019-03-27T16:47:43.393556+00:00 app[web.1]: 10.69.185.233 - - [27/Mar/2019:16:4
7:43 +0000] "GET /predict HTTP/1.1" 500 290 "https://lesionlegion1.herokuapp.com
/" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gec
ko) Chrome/73.0.3683.86 Safari/537.36"
2019-03-27T16:47:43.396781+00:00 app[web.1]: <Request 'https://lesionlegion1.her
okuapp.com/predict' [POST]>
2019-03-27T16:48:13.443130+00:00 heroku[router]: at=error code=H12 desc="Request
 timeout" method=POST path="/predict" host=lesionlegion1.herokuapp.com request_i
d=4ad7f81f-27a9-4b46-9423-24ccb3b59d25 fwd="96.35.158.2" dyno=web.1 connect=0ms
service=30052ms status=503 bytes=0 protocol=https
2019-03-27T16:48:14.067005+00:00 app[web.1]: [2019-03-27 16:48:14 +0000] [4] [CR
ITICAL] WORKER TIMEOUT (pid:101)
2019-03-27T16:48:15.091482+00:00 app[web.1]: [2019-03-27 16:48:15 +0000] [109] [
INFO] Booting worker with pid: 109

【问题讨论】:

  • 嗨@SpacePatroller 我的回答是否有意义并帮助了你?
  • 你好@Nathan Wright,这是有道理的,但不是问题的解决方案。就在今天早上,我的一个队友能够弄清楚。它最终出现在我的 JS 代码中,其中我有一个 setTimeout 围绕 on click 函数来调用 /predict 路由。在我的本地计算机上,我需要它,因为路由需要时间来处理,但由于某种原因,在部署时它导致它无法运行。不过您的回复对我的学习体验很有帮助,谢谢!
  • @NathanWright 没关系你是对的!今天早上我很困惑,我很抱歉。我们还将 AJAX 请求中的 Async 设置为 false,因为这是有问题的。

标签: heroku flask


【解决方案1】:

这是因为您的 /predict 路由同时支持 GETPOST 请求,但是当您从 GET 请求中访问您的 /predict 路由时,您将返回诊断变量的值:return jsonify(diagnosis)但是这个diagnosis 变量没有在这个范围内定义,而是在你的POST 路由中定义为一个全局变量,所以这就是你得到以下错误的原因:

NameError:名称“诊断”未定义

您可以从堆栈跟踪的这一部分中看到这是由您的 GET 方法引起的:

2019-03-27T16:47:43.394981+00:00 heroku[路由器]: at=info method=GET path="/predi ct" 主机=lesionlegion1.herokuapp.com request_id=6a8b52fa-33c4-4c23-881f-25a626bc 73ae fwd="96.35.158.2" dyno=web.1 连接=1ms 服务=5ms 状态=500 字节=455 p 协议=https 2019-03-27T16:47:43.392702+00:00 app[web.1]: [2019-03-27 16:47:43,390] 错误 应用程序:/predict [GET] 上的异常

因此,为了修复此错误,您需要在处理特定请求类型之前声明您的 diagnosis 变量,类似于:

@app.route('/predict', methods=['GET', 'POST'])
def upload():
    diagnosis = []
    if request.method == 'POST':
       # ... handle POST request 
       return jsonify(diagnosis)

    # Default response for GET requests
    return jsonify(diagnosis)


if __name__ == "__main__":
    app.run(port=5002, debug=True, threaded=False)

希望对您有所帮助!

【讨论】:

    猜你喜欢
    • 2018-05-20
    • 1970-01-01
    • 1970-01-01
    • 2012-02-22
    • 2013-11-03
    • 2021-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多