158 votes

Comment arrêter une application flask sans utiliser ctrl-c

Je veux implémenter une commande qui peut arrêter une application flask en utilisant flask-script. J'ai cherché la solution pendant un certain temps. Parce que le framework ne fournit pas app.stop() API, je suis curieux de savoir comment coder cela. Je travaille sur Ubuntu 12.10 et Python 2.7.3.

0 votes

Pourquoi devez-vous être capable d'arrêter votre application à partir d'un script ? (Le meilleur outil pour ce travail dépend de ce que vous essayez de faire).

0 votes

Sérieusement, qu'est-ce que vous essayez de faire ici ? Si vous parlez de devserver pour le développement, il est tout à fait possible de l'arrêter comme ça. En production, on ne déploie pas comme ça et on peut arrêter une requête à n'importe quel moment, donc "l'application s'arrête de tourner".

0 votes

@SeanVieira Je voudrais savoir s'il existe des solutions pour faire cela.

3voto

QtRoS Points 626

Si quelqu'un d'autre cherche comment arrêter le serveur Flask à l'intérieur service win32 - le voici. C'est une combinaison un peu bizarre de plusieurs approches, mais ça marche bien. Les idées clés :

  1. C'est shutdown qui peut être utilisé pour l'arrêt progressif. Note : il s'appuie sur request.environ.get qui est utilisable uniquement dans le contexte de la demande web (dans @app.route fonction -ed)
  2. de win32service SvcStop la méthode utilise requests pour faire une demande HTTP au service lui-même.

myservice_svc.py

import win32service
import win32serviceutil
import win32event
import servicemanager
import time
import traceback
import os

import myservice

class MyServiceSvc(win32serviceutil.ServiceFramework):
    _svc_name_ = "MyServiceSvc"                       # NET START/STOP the service by the following name
    _svc_display_name_ = "Display name"  # this text shows up as the service name in the SCM
    _svc_description_ = "Description" # this text shows up as the description in the SCM

    def __init__(self, args):
        os.chdir(os.path.dirname(myservice.__file__))
        win32serviceutil.ServiceFramework.__init__(self, args)

    def SvcDoRun(self):
        # ... some code skipped
        myservice.start()

    def SvcStop(self):
        """Called when we're being shut down"""
        myservice.stop()
        # tell the SCM we're shutting down
        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
        servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
                              servicemanager.PYS_SERVICE_STOPPED,
                              (self._svc_name_, ''))

if __name__ == '__main__':
    os.chdir(os.path.dirname(myservice.__file__))
    win32serviceutil.HandleCommandLine(MyServiceSvc)

myservice.py

from flask import Flask, request, jsonify

# Workaround - otherwise doesn't work in windows service.
cli = sys.modules['flask.cli']
cli.show_server_banner = lambda *x: None

app = Flask('MyService')

# ... business logic endpoints are skipped.

@app.route("/shutdown", methods=['GET'])
def shutdown():
    shutdown_func = request.environ.get('werkzeug.server.shutdown')
    if shutdown_func is None:
        raise RuntimeError('Not running werkzeug')
    shutdown_func()
    return "Shutting down..."

def start():
    app.run(host='0.0.0.0', threaded=True, port=5001)

def stop():
    import requests
    resp = requests.get('http://0.0.0.0:5001/shutdown')

1voto

Alex Points 101

Vous pouvez utiliser la méthode suivante

app.do_teardown_appcontext()

1 votes

Il s'agit d'une supposition erronée. Cette fonction n'arrête pas l'application, elle est appelée automatiquement pour libérer un certain contexte à la fin du traitement d'une demande individuelle. flask.palletsprojects.com/fr/1.1.x/api/

0 votes

Cela ne fonctionne pas pour moi

0voto

Rohit Singh Points 1934

Instance VM Google Cloud + App Flask

J'ai hébergé mon application Flask sur une machine virtuelle de Google Cloud Platform. J'ai démarré l'application en utilisant python main.py Mais le problème était que ctrl+c ne fonctionnait pas pour arrêter le serveur.

Cette commande $ sudo netstat -tulnp | grep :5000 met fin au serveur.

Mon application Flask fonctionne sur le port 5000 par défaut.

Note : Mon instance VM fonctionne sous Linux 9.

Cela fonctionne pour cela. Je n'ai pas testé pour d'autres plateformes. N'hésitez pas à mettre à jour ou à commenter si cela fonctionne aussi pour d'autres versions.

0 votes

Remarque : ni netstat ni grep n'arrêteront un processus actif.

0voto

Une solution Python

Fonctionne avec : python kill_server.py .

C'est pour Windows uniquement . Tue les serveurs avec taskkill, par PID, recueillis avec netstat.

# kill_server.py

import os
import subprocess
import re

port = 5000
host = '127.0.0.1'
cmd_newlines = r'\r\n'

host_port = host + ':' + str(port)
pid_regex = re.compile(r'[0-9]+$')

netstat = subprocess.run(['netstat', '-n', '-a', '-o'], stdout=subprocess.PIPE)  
# Doesn't return correct PID info without precisely these flags
netstat = str(netstat)
lines = netstat.split(cmd_newlines)

for line in lines:
    if host_port in line:
        pid = pid_regex.findall(line)
        if pid:
            pid = pid[0]
            os.system('taskkill /F /PID ' + str(pid))

# And finally delete the .pyc cache
os.system('del /S *.pyc')

Si vous avez des problèmes avec le chargement du favicon / des modifications de l'index.html (c'est-à-dire que les anciennes versions sont mises en cache), alors Essayez "Effacer les données de navigation > Images et fichiers" dans Chrome. également.

En faisant tout ce qui précède, j'ai obtenu que mon favicon se charge enfin lors de l'exécution de mon application Flask.

0voto

user3076105 Points 71
app = MyFlaskSubclass()

...

app.httpd = MyWSGIServerSubclass()

...

@app.route('/shutdown')
def app_shutdown():
    from threading import Timer
    t = Timer(5, app.httpd.shutdown)
    t.start()
    return "Server shut down"

0 votes

Fournir contexte supplémentaire en expliquant pourquoi et comment cette réponse fonctionne et quand elle doit être utilisée améliorera sa valeur à long terme en aidant les lecteurs.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X