web-dev-qa-db-fra.com

Quelle est la bonne approche pour appeler des fonctions après l’exécution d’une application de flacon?

Je suis un peu confus sur la façon de faire quelque chose qui, à mon avis, serait assez simple. J'ai une application simple écrit en utilisant Flask. Cela ressemble à quelque chose comme ça:

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 __== "__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)

Ce que je constate, c’est que mon terminal envoie les instructions print au format _run_on_start, mais pas du code de débogage habituel de l’application Flask. Si je retire l'appel avant app.run, la sortie est normale. De plus, je constate que la sortie de _run_on_start doit être répétée deux fois au démarrage, bien que je ne sache pas s’il s’agit d’une sortie étrange ou si la fonction est appelée deux fois.

Je suppose que ce n'est pas la bonne façon d'ajouter un appel de fonction avant d'appeler app.run. J'ai consulté la documentation Flask et trouvé des mentions de divers décorateurs que l'on peut utiliser, qui vous permettent d'exécuter une fonction avant/après certaines demandes, mais je veux exécuter l'appel lorsque le serveur d'applications est exécuté.

De plus, je réalise que si j’appelle ce module à partir d’un autre module, c’est-à-dire pas lorsque __!= "__main__" mon, je ne recevrai pas mon appel à _run_on_start.

Quelle est la bonne approche ici? Dans les deux cas, quand je commence à partir du CL et d'un autre module?

28
Edwardr

La sortie dupliquée de votre fonction peut être expliquée par le rechargeur. La première chose à faire est de lancer la fonction principale dans un nouveau thread afin qu'il puisse surveiller les fichiers source et redémarrer le thread lorsqu'ils changent. Désactivez ceci avec l'option use_reloader=False.

Si vous voulez pouvoir exécuter votre fonction lorsque vous démarrez le serveur à partir d'un module différent, intégrez-le dans une fonction et appelez cette fonction à partir de l'autre module:

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

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

La "bonne approche" dépend de ce que vous essayez réellement d'accomplir ici. Le serveur intégré est conçu pour exécuter votre application dans un environnement de test local avant de la déployer sur un serveur de production. Par conséquent, le problème de son démarrage à partir d'un module différent n'a pas vraiment de sens.

13
robots.jpg

Vous cherchiez probablement un décorateur Flask.before_first_request, comme dans:

@app.before_first_request
def _run_on_start(a_string):
    print "doing something important with %s" % a_string
44
the-happy-hippo
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!"
0
Peretz30