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.

183voto

Zorayr Points 2637

Si vous n'exécutez le serveur que sur votre bureau, vous pouvez exposer un point de terminaison pour tuer le serveur (pour en savoir plus, consultez le site suivant Arrêter le serveur simple ) :

from flask import request
def shutdown_server():
    func = request.environ.get('werkzeug.server.shutdown')
    if func is None:
        raise RuntimeError('Not running with the Werkzeug Server')
    func()

@app.get('/shutdown')
def shutdown():
    shutdown_server()
    return 'Server shutting down...'

Voici une autre approche qui est plus contenue :

from multiprocessing import Process

server = Process(target=app.run)
server.start()
# ...
server.terminate()
server.join()

Faites-moi savoir si cela vous aide.

25 votes

Savez-vous s'il existe un moyen d'obtenir la propriété "werkzeug.server.shutdown" sans avoir besoin d'un contexte de requête ?

5 votes

J'ai dû changer la méthode d'acheminement en "GET" pour que cela fonctionne.

7 votes

Pour être complète, cette réponse ne contient pas la fonction que vous appelleriez en dehors d'un contexte de requête pour effectuer l'arrêt, qui ne serait rien d'autre qu'une requête HTTP vers le serveur (qui peut provenir de/vers l'hôte local).

68voto

Ruben Decorp Points 56

Je l'ai fait de manière légèrement différente en utilisant des fils

from werkzeug.serving import make_server

class ServerThread(threading.Thread):

    def __init__(self, app):
        threading.Thread.__init__(self)
        self.server = make_server('127.0.0.1', 5000, app)
        self.ctx = app.app_context()
        self.ctx.push()

    def run(self):
        log.info('starting server')
        self.server.serve_forever()

    def shutdown(self):
        self.server.shutdown()

def start_server():
    global server
    app = flask.Flask('myapp')
    # App routes defined here
    server = ServerThread(app)
    server.start()
    log.info('server started')

def stop_server():
    global server
    server.shutdown()

Je l'utilise pour faire des tests de bout en bout pour l'api restful, où je peux envoyer des requêtes en utilisant la bibliothèque python requests.

4 votes

Je n'ai pas réussi à faire fonctionner les autres solutions, mais celle-ci fonctionne très bien ! Merci beaucoup ! Pour les autres : ça marche aussi avec flask restful !

1 votes

Cela semble se bloquer sous Windows jusqu'à ce que je lui soumette une autre demande... Y a-t-il un moyen de contourner ce problème ?

0 votes

J'ai le même problème que @Claudiu, mais sous Linux avec python 3.6.2.

34voto

R J Points 54

C'est un fil un peu ancien, mais si quelqu'un qui expérimente, apprend ou teste une application flask de base, a commencé à partir d'un script qui s'exécute en arrière-plan, le moyen le plus rapide de l'arrêter est de tuer le processus qui s'exécute sur le port sur lequel vous exécutez votre application. Note : Je suis conscient que l'auteur cherche un moyen de ne pas tuer ou arrêter l'application. Mais cela peut aider quelqu'un qui apprend.

sudo netstat -tulnp | grep :5001

Vous obtiendrez quelque chose comme ça.

tcp 0 0 0 0.0.0.0:5001 0.0.0.0:* LISTEN 28834/python

Pour arrêter l'application, tuer le processus

sudo kill 28834

2 votes

J'ai dû utiliser sudo kill -9 28834 avant que le processus ne puisse être tué.

21voto

Nam G VU Points 5954

Ma méthode peut être poursuivie via le terminal/console bash

1) exécuter et obtenir le numéro du processus

$ ps aux | grep yourAppKeywords

2a) tuer le processus

$ kill processNum

2b) tuer le processus si ce qui précède ne fonctionne pas

$ kill -9 processNum

11 votes

Je suis presque sûr que la question n'est pas "comment tuer un processus", et que le problème est que faire ctrl+c ne le tue pas. Par ailleurs, j'utilise kill -9 `lsof -i:5000 -t` parce qu'il n'y a qu'une seule application qui peut utiliser le port et que c'est facile.

13voto

danvk Points 2129

Comme d'autres l'ont fait remarquer, vous pouvez uniquement utiliser werkzeug.server.shutdown d'un gestionnaire de demandes. Le seul moyen que j'ai trouvé pour arrêter le serveur à un autre moment est d'envoyer une requête à soi-même. Par exemple, la requête /kill dans cet extrait va tuer le serveur de développement à moins qu'une autre demande n'arrive dans la seconde suivante :

import requests
from threading import Timer
from flask import request
import time

LAST_REQUEST_MS = 0
@app.before_request
def update_last_request_ms():
    global LAST_REQUEST_MS
    LAST_REQUEST_MS = time.time() * 1000

@app.post('/seriouslykill')
def seriouslykill():
    func = request.environ.get('werkzeug.server.shutdown')
    if func is None:
        raise RuntimeError('Not running with the Werkzeug Server')
    func()
    return "Shutting down..."

@app.post('/kill')
def kill():
    last_ms = LAST_REQUEST_MS
    def shutdown():
        if LAST_REQUEST_MS <= last_ms:  # subsequent requests abort shutdown
            requests.post('http://localhost:5000/seriouslykill')
        else:
            pass

    Timer(1.0, shutdown).start()  # wait 1 second
    return "Shutting down..."

3 votes

Ça marche mais ça fait... très bidouillé. Je sais que cela fait un moment, mais avez-vous trouvé un moyen propre de faire cela, sans vous envoyer une requête à vous-même ?

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