Каков правильный подход к вызову функций после запуска колбы? - PullRequest
30 голосов
/ 14 февраля 2012

Я немного озадачен тем, как сделать что-то, что, как мне показалось, будет довольно простым.У меня есть простое приложение, написанное с использованием Flask.Это выглядит примерно так:

from flask import Flask

app = Flask(__name__)

def _run_on_start(a_string):
    print "doing something important with %s" % a_string

@app.route('/')
def root():
    return 'hello world'

if __name__ == "__main__":
    if len(sys.argv) < 2:
        raise Exception("Must provide domain for application execution.")
    else:
        DOM = sys.argv[1]
        _run_on_start("%s" % DOM)
        app.run(debug=True)

Я обнаружил, что мой терминал выводит операторы печати в _run_on_start, но не из другого обычного кода отладки приложения Flask.Если я уберу вызов перед app.run, вывод нормальный.Кроме того, я обнаружил, что вывод _run_on_start будет повторяться дважды при запуске, хотя я не знаю, является ли это какой-то странный вывод или функция на самом деле вызывается дважды.

Я предполагаю, что этоне правильный способ добавить вызов функции перед вызовом app.run.Я просмотрел документы Flask и нашел упоминания о различных декораторах, которые можно использовать, которые позволяют выполнять функцию до / после определенных запросов, но я хочу выполнить вызов при запуске сервера приложений.

Далее,Я понимаю, что если я вызову этот модуль из другого модуля, то есть не тогда, когда __name__ != "__main__" my, я не получу свой вызов _run_on_start.

Какой правильный подход здесь?В обоих случаях, когда я начинаю с CL и с другого модуля?

Ответы [ 3 ]

47 голосов
/ 13 апреля 2014

Возможно, вы искали Flask.before_first_request декоратор, например:

@app.before_first_request
def _run_on_start(a_string):
    print "doing something important with %s" % a_string
13 голосов
/ 16 февраля 2012

Повторяющийся вывод из вашей функции может быть объяснен перегрузчиком. Сначала он запускает основную функцию в новом потоке, чтобы он мог отслеживать исходные файлы и перезапускать поток при их изменении. Отключите это с опцией use_reloader=False.

Если вы хотите иметь возможность запускать свою функцию при запуске сервера из другого модуля, оберните его в функцию и вызовите эту функцию из другого модуля:

def run_server(dom):
        _run_on_start("%s" % dom)
        app.run(debug=True, use_reloader=False)

if __name__ == '__main__':
    if len(sys.argv) < 2:
        raise Exception("Must provide domain for application execution.")
    else:
        DOM = sys.argv[1]
        run_server(DOM)

«Правильный подход» зависит от того, чего вы на самом деле пытаетесь достичь здесь. Встроенный сервер предназначен для запуска приложения в локальной тестовой среде перед его развертыванием на производственном сервере, поэтому проблема запуска его из другого модуля сама по себе не имеет особого смысла.

0 голосов
/ 17 февраля 2019
from flask import Flask

def create_app():
    app = Flask(__name__)
    def run_on_start(*args, **argv):
        print "function before start"
    run_on_start()
    return app

app = create_app()

@app.route("/")
def hello():
    return "Hello World!"
...