Как использовать маршруты Flask с Apache и mod_wsgi?

У меня есть настройка сервера Apache, и он обрабатывает ответы Flask через mod_wsgi. Я зарегистрировал WSGI script через псевдоним:

[httpd.conf]

WSGIScriptAlias /service "/mnt/www/wsgi-scripts/service.wsgi"

Я добавил соответствующий файл WSGI по указанному выше пути:

[/мнт/WWW/WSGI-скрипты/service.wsgi]

import sys
sys.path.insert(0, "/mnt/www/wsgi-scripts")

from service import application

И у меня есть простой тест Flask Python script, который предоставляет сервисный модуль:

[/мнт/WWW/WSGI-скрипты/service.py]

from flask import Flask

app = Flask(__name__)

@app.route('/')
def application(environ, start_response):
        status = '200 OK'
        output = "Hello World!"
        response_headers = [('Content-type', 'text/plain'),
                            ('Content-Length', str(len(output)))]
        start_response(status, response_headers)
        return [output]

@app.route('/upload')
def upload(environ, start_response):
        output = "Uploading"
        status = '200 OK'
        response_headers = [('Content-type', 'text/plain'),
                            ('Content-Length', str(len(output)))]
        start_response(status, response_headers)
        return [output]

if __name__ == '__main__':
        app.run()

Когда я перехожу на мой сайт URL [hostname]/service, он работает так, как ожидалось, и я получаю "Hello World!". назад. Проблема в том, что я не знаю, как использовать другие маршруты, например, "upload" в приведенном выше примере. Это отлично работает в автономной Flask, но в mod_wsgi я в тупике. Единственное, что я могу себе представить, - зарегистрировать отдельный URL-адрес WSGI script в httpd.conf для каждой конечной точки, которую я хочу, но это отвлекает поддержку флеш-маршрутизации. Есть ли способ сделать эту работу?

Ответ 1

В вашем файле wsgi вы делаете from service import application, который импортирует только ваш метод application.

Измените это на from service import app as application, и все будет работать как ожидалось.

После вашего комментария я подумал, что немного разберу ответ:

Ваш файл wsgi - это код python - у вас может быть любой действительный код python внутри этого файла. Обработчик wsgi, который установлен в Apache, ищет имя приложения в этом файле, от которого он будет передавать запросы. Экземпляр класса Flask - app = Flask(__name__) - предоставляет такой интерфейс, но поскольку он называется app, а не application, вы должны его псевдоним при импорте - это то, что делает строка из строки.

Вы можете - и это прекрасно - просто сделайте это application = Flask(__name__), а затем укажите обработчик wsgi в Apache в ваш файл service.py. Если service.py был импортируемым (это значит, где-то в PYTHONPATH), вам не нужен посредник wsgi script.

Хотя вышеизложенное работает, его плохая практика. Для работы файла wsgi необходимы разрешения от процесса Apache; и вы обычно отделяете это от фактического исходного кода, который должен быть где-то еще в вашей файловой системе, с соответствующими разрешениями.