404 для всех маршрутов с Flask на uWSGI / Gunicorn - PullRequest
0 голосов
/ 12 марта 2020

Я нашел и разложил следующий пример проекта Flask / SQLAlchemy / Marshmallow:

https://github.com/summersab/RestaurantAPI

Он работает как шарм, и я использовал его для сборки пользовательский API. Он работает без ошибок:

python run.py

Затем я попытался запустить его на соответствующем веб-сервере:

uwsgi --http localhost:5000 --wsgi-file run.py --callable app

Однако я получаю 404 для всех маршрутов, кроме /, /api и /api/v1.0. Я попробовал это на Gunicorn с теми же результатами, что заставило меня поверить, что проблема в коде, а не в конфигурации веб-сервера.

Все следующие посты имеют ту же проблему, но из того, что я мог сказать, нет из них были решения, которые работали для меня (возможно, я что-то упустил):

Может кто-то посмотрите на код в моем репо и помогите разобраться в чем дело?

РЕДАКТИРОВАТЬ:

В ответ на @ 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

Спасибо за вашу помощь! * 10 54 *

1 Ответ

1 голос
/ 13 марта 2020

Это можно быстро решить, создав новый файл 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

Почему это работает ...

Если у вас есть , загляните в файл run.py и обратите внимание, что происходит, когда вы запускаете это непосредственно с помощью python:

if __name__ == "__main__":
    PresentConfig = BaseConfig
    app = create_app(PresentConfig)
    app.run(use_debugger=False, use_reloader=False, passthrough_errors=True)

, вы можете видеть, что создается app на основе возвращаемого значения функции create_app, которая передается в конфигурации. Также обратите внимание, что функция create_app регистрирует «другие URL» как часть проекта api_bp.

Однако код в этом предложении if никогда не выполняется, когда приложение выполняется с помощью uwsgi / gunicorn ; вместо этого импортируемый объект 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 (маловероятно в этом случае).

Дайте мне знать, если вам нужно что-то прояснить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...