将 Google App Engine 与 flask 和 flask-restplus 一起使用时出现 404 错误

404 error when using Google App Engine with flask and flask-restplus

我的 main.py 根文件夹中的文件如下所示。

app = Flask(__name__)

def configure_app(app):
    app.config['SERVER_NAME'] = settings.FLASK_SERVER_NAME
    app.config['SWAGGER_UI_DOC_EXPANSION'] = settings.RESTPLUS_SWAGGER_UI_DOC_EXPANSION
    app.config['RESTPLUS_VALIDATE'] = settings.RESTPLUS_VALIDATE
    app.config['RESTPLUS_MASK_SWAGGER'] = settings.RESTPLUS_MASK_SWAGGER
    app.config['ERROR_404_HELP'] = settings.RESTPLUS_ERROR_404_HELP

def initialize_app(app):
    configure_app(app)
    blueprint = Blueprint('api', __name__, url_prefix='/api')
    api.init_app(blueprint)
    api.namespaces.pop(0) #this is to remove default namespace from swagger doc
    api.add_namespace(user_namespace)
    app.register_blueprint(blueprint)

def main():
    initialize_app(app)
    app.run(debug=settings.FLASK_DEBUG)


if __name__ == "__main__":
    main()

我的 app.yaml 文件如下所示。

runtime: python
env: flex
entrypoint: gunicorn -b :$PORT main:app

runtime_config:
  python_version: 3

manual_scaling:
  instances: 1
resources:
  cpu: 1
  memory_gb: 0.5
  disk_size_gb: 10

下面是 requirements.txt 文件。

Flask==1.0.2
flask-restplus==0.11.0
gunicorn==19.9.0

我是运行 flex 环境中的GAE。

我按照 https://cloud.google.com/appengine/docs/flexible/python/quickstart 中的步骤操作,并成功将应用程序部署到 App Engine。

当我转到 appspot link 时,我收到 404 错误并且 gcloud 日志尾部如下所示。

2018-09-09 01:49:00 default[20180909t113222]  "GET /" 404
2018-09-09 01:49:01 default[20180909t113222]  "GET /favicon.ico" 404
2018-09-09 01:49:09 default[20180909t113222]  "GET /api/" 404

我尝试寻找一种解决方案,但从未找到与我的情况相似的解决方案。

非常感谢任何帮助。

谢谢。

您现有的代码只添加了一个带有 /api URL 前缀的蓝图,因此它将无法处理 //favicon.ico 的请求(许多浏览器默认请求) - 解释请求日志中的前 2 404 个错误。如果您的应用程序旨在被常规浏览器访问,您可能需要添加其他蓝图来覆盖那些 URLs,否则那些 404s 是 expected/normal.

我不熟悉 Flask 和蓝图,所以我不确定您拥有的蓝图是否应该像现在这样启动,已经为 /api/ URL 服务。如果不是 - 那将解释请求日志中的第三个 404。我怀疑您可能需要在蓝图中为它添加一个 route/rule,不过。

部署到 App Engine 时不会调用您的 main 函数。相反,App Engine 使用 Gunicorn 和您在 app.yaml 文件中定义的 entrypoint

由于 main 没有被调用,您的 initialize_app 函数也没有被调用,它添加了您正在寻找的端点。

相反,您应该执行如下操作:

app = Flask(__name__)
initialize_app(app)

def configure_app(app):
    ...

def initialize_app(app):
    ... 

if __name__ == "__main__":
    # Only use this for things need to run the app locally,
    # will not be used when deploying to App Engine
    app.run(debug=settings.FLASK_DEBUG)

编辑:我能够使用这个最小的 main.py:

from flask import Flask, Blueprint
from flask_restplus import Api

app = Flask(__name__)
api = Api()
blueprint = Blueprint('api', __name__, url_prefix='/api')
api.init_app(blueprint)
app.register_blueprint(blueprint)