在 uWSGI/Gunicorn 上使用 Flask 的所有路由都是 404
404 for all routes with Flask on uWSGI/Gunicorn
我找到并分叉了以下 Flask/SQLAlchemy/Marshmallow 示例项目:
https://github.com/summersab/RestaurantAPI
它就像一个魅力,我用它来构建一个自定义 API。 运行完美搭配:
python run.py
然后,我尝试 运行 它在合适的网络服务器上:
uwsgi --http localhost:5000 --wsgi-file run.py --callable app
但是,除了 /
、/api
和 /api/v1.0
之外的所有路线我都得到 404。我在 Gunicorn 上试过,结果相同,这让我相信问题出在代码上,而不是网络服务器配置上。
以下所有帖子都有同样的问题,但据我所知,none 个帖子有适合我的解决方案(我可能遗漏了一些东西):
- Flask on nginx + uWSGI returns a 404 error unless the linux directory exists
- Unexplainable Flask 404 errors
- Nginx+bottle+uwsgi Server returning 404 on every request
- Flask application with Blueprints+uWSGI+nginx returning 404's (no routing?)
有人可以查看我的代码库中的代码并帮助我找出问题所在吗?
编辑:
根据@v25 的回复,我将 run.py
更改为以下内容:
from flask import Flask, redirect, render_template
from app import api_bp
from model import db, redis_cache
from config import DevelopmentConfig, TestingConfig, BaseConfig, PresentConfig
app = Flask(__name__)
t = 0
def create_app(config_filename):
app.config.from_object(config_filename)
global t
if t == 0:
app.register_blueprint(api_bp, url_prefix='/api/v1.0')
t = 1
if config_filename != TestingConfig:
db.init_app(app)
redis_cache.init_app(app)
return app
@app.route('/')
@app.route('/api/')
@app.route('/api/v1.0/')
def availableApps():
return render_template('availableApp.html')
PresentConfig = BaseConfig
app = create_app(PresentConfig)
if __name__ == "__main__":
app.run(use_debugger=False, use_reloader=False, passthrough_errors=True)
然后我 运行 使用 uwsgi,它按预期工作:
uwsgi --http localhost:5000 --wsgi-file run.py --callable app
感谢您的帮助!
这可以通过创建一个包含以下内容的新文件 wsgi.py
来快速解决:
import run
PresentConfig = run.BaseConfig
app = run.create_app(PresentConfig)
然后执行:
uwsgi --http localhost:5000 --wsgi-file wsgi.py --callable app
或...
gunicorn --bind 'localhost:5000' wsgi:app
为什么这样做...
如果您有 look inside the run.py
file,请注意直接使用 python
启动它时发生的情况:
if __name__ == "__main__":
PresentConfig = BaseConfig
app = create_app(PresentConfig)
app.run(use_debugger=False, use_reloader=False, passthrough_errors=True)
您可以看到正在创建 app
,基于传递给配置的 create_app
函数的 return 值。另请注意,create_app
函数将 "other URLs" 注册为 api_bp
蓝图的一部分。
然而,当使用 uwsgi/gunicorn 执行应用程序时,此 if
子句中的代码永远不会执行;相反,导入的 app
对象是一个没有注册其他 URL 的对象。
通过创建上面的 wsgi.py
文件,您正在以一种随后可以由 wsgi/gunicorn 可执行文件改进的方式执行所有这些操作。
考虑到这一点,解决此问题的另一种方法是更改 run.py
的最后四行,使其看起来更像:
PresentConfig = BaseConfig
app = create_app(PresentConfig)
if __name__ == "__main__":
app.run(use_debugger=False, use_reloader=False, passthrough_errors=True)
然后您可以使用原始 wsgi 命令执行此操作。
值得注意的是,这可能会破坏其他执行 from run import app
并期望 app
不是 create_app
的 return 值的代码(在这种情况下不太可能)。
如果您需要任何说明,请告诉我。
我找到并分叉了以下 Flask/SQLAlchemy/Marshmallow 示例项目:
https://github.com/summersab/RestaurantAPI
它就像一个魅力,我用它来构建一个自定义 API。 运行完美搭配:
python run.py
然后,我尝试 运行 它在合适的网络服务器上:
uwsgi --http localhost:5000 --wsgi-file run.py --callable app
但是,除了 /
、/api
和 /api/v1.0
之外的所有路线我都得到 404。我在 Gunicorn 上试过,结果相同,这让我相信问题出在代码上,而不是网络服务器配置上。
以下所有帖子都有同样的问题,但据我所知,none 个帖子有适合我的解决方案(我可能遗漏了一些东西):
- Flask on nginx + uWSGI returns a 404 error unless the linux directory exists
- Unexplainable Flask 404 errors
- Nginx+bottle+uwsgi Server returning 404 on every request
- Flask application with Blueprints+uWSGI+nginx returning 404's (no routing?)
有人可以查看我的代码库中的代码并帮助我找出问题所在吗?
编辑:
根据@v25 的回复,我将 run.py
更改为以下内容:
from flask import Flask, redirect, render_template
from app import api_bp
from model import db, redis_cache
from config import DevelopmentConfig, TestingConfig, BaseConfig, PresentConfig
app = Flask(__name__)
t = 0
def create_app(config_filename):
app.config.from_object(config_filename)
global t
if t == 0:
app.register_blueprint(api_bp, url_prefix='/api/v1.0')
t = 1
if config_filename != TestingConfig:
db.init_app(app)
redis_cache.init_app(app)
return app
@app.route('/')
@app.route('/api/')
@app.route('/api/v1.0/')
def availableApps():
return render_template('availableApp.html')
PresentConfig = BaseConfig
app = create_app(PresentConfig)
if __name__ == "__main__":
app.run(use_debugger=False, use_reloader=False, passthrough_errors=True)
然后我 运行 使用 uwsgi,它按预期工作:
uwsgi --http localhost:5000 --wsgi-file run.py --callable app
感谢您的帮助!
这可以通过创建一个包含以下内容的新文件 wsgi.py
来快速解决:
import run
PresentConfig = run.BaseConfig
app = run.create_app(PresentConfig)
然后执行:
uwsgi --http localhost:5000 --wsgi-file wsgi.py --callable app
或...
gunicorn --bind 'localhost:5000' wsgi:app
为什么这样做...
如果您有 look inside the run.py
file,请注意直接使用 python
启动它时发生的情况:
if __name__ == "__main__":
PresentConfig = BaseConfig
app = create_app(PresentConfig)
app.run(use_debugger=False, use_reloader=False, passthrough_errors=True)
您可以看到正在创建 app
,基于传递给配置的 create_app
函数的 return 值。另请注意,create_app
函数将 "other URLs" 注册为 api_bp
蓝图的一部分。
然而,当使用 uwsgi/gunicorn 执行应用程序时,此 if
子句中的代码永远不会执行;相反,导入的 app
对象是一个没有注册其他 URL 的对象。
通过创建上面的 wsgi.py
文件,您正在以一种随后可以由 wsgi/gunicorn 可执行文件改进的方式执行所有这些操作。
考虑到这一点,解决此问题的另一种方法是更改 run.py
的最后四行,使其看起来更像:
PresentConfig = BaseConfig
app = create_app(PresentConfig)
if __name__ == "__main__":
app.run(use_debugger=False, use_reloader=False, passthrough_errors=True)
然后您可以使用原始 wsgi 命令执行此操作。
值得注意的是,这可能会破坏其他执行 from run import app
并期望 app
不是 create_app
的 return 值的代码(在这种情况下不太可能)。
如果您需要任何说明,请告诉我。