Voglio realizzare un comando che può fermare applicazione pallone utilizzando pallone-script. Ho cercato la soluzione per un po '. Poiché il framework non fornisce l'API "app.stop()", sono curioso di sapere come codificarlo. Sto lavorando su Ubuntu 12.10 e Python 2.7.3.come smettere di applicazione pallone senza usare ctrl-c
risposta
Se sono solo in esecuzione il server sul desktop, è possibile esporre un endpoint per uccidere il server (continua a Shutdown The Simple Server):
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.route('/shutdown', methods=['POST'])
def shutdown():
shutdown_server()
return 'Server shutting down...'
Ecco un altro approccio che è più contenuto:
from multiprocessing import Process
server = Process(target=app.run)
server.start()
# ...
server.terminate()
server.join()
fatemi sapere se questo aiuta.
Sai se esiste un modo per ottenere la proprietà 'werkzeug.server.shutdown' senza bisogno di un contesto di richiesta? – akatkinson
Ho dovuto cambiare il metodo del percorso in "GET" per farlo funzionare. –
Per completezza questa risposta manca la funzione che si chiamerebbe al di fuori di un contesto di richiesta per eseguire l'arresto, che non sarebbe nient'altro che una richiesta HTTP al server (che può provenire da/a localhost) – JamesHutchison
Come altri hanno sottolineato, è possibile utilizzare solo werkzeug.server.shutdown
da un gestore richieste. L'unico modo in cui ho trovato di spegnere il server in un altro momento è quello di inviare una richiesta a te stesso. Ad esempio, il gestore /kill
in questo frammento ucciderà il server dev meno che un altro richiesta arriva durante il prossimo secondo:
import requests
from threading import Timer
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.route('/seriouslykill', methods=['POST'])
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.route('/kill', methods=['POST'])
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..."
funziona ma si sente .. ._very_ hacky. So che è passato un po 'di tempo, ma hai mai trovato un modo pulito per farlo, senza inviare una richiesta a te stesso? – Juicy
Il mio metodo può procedere tramite il morsetto bash/console
1) gestito e ottenere il numero di processo
$ ps aux | grep yourAppKeywords
2a) uccidere il processo
$ kill processNum
2b) uccidere il processo se sopra non funziona
$ kill -9 processNum
Sono quasi sicuro che la domanda non è "come uccidere un processo", e il problema è che fare ctrl + c non lo uccide. A proposito, io uso 'kill -9 \' lsof -i: 5000 -t \ '' cuz nientemeno che solo 1 app può usare la porta ed è facile. – erm3nda
Questa è una vecchia questione, ma googling non mi ha dato una visione chiara su come raggiungere questo obiettivo.
Perché non ho letto correttamente il code here! (Doh!) Ciò che fa è quello di sollevare un RuntimeError
quando non c'è werkzeug.server.shutdown
nel request.environ
...
Allora cosa possiamo fare quando non c'è request
è quello di sollevare una RuntimeError
def shutdown():
raise RuntimeError("Server going down")
e cattura che quando app.run()
rendimenti:
...
try:
app.run(host="0.0.0.0")
except RuntimeError, msg:
if str(msg) == "Server going down":
pass # or whatever you want to do when the server goes down
else:
# appropriate handling/logging of other runtime errors
# and so on
...
Non c'è bisogno di inviare a te stesso una richiesta.
ho fatto un po 'diversi thread utilizzando
from werkzeug.serving import make_server
class ServerThread(threading.Thread):
def __init__(self, app):
threading.Thread.__init__(self)
self.srv = make_server('127.0.0.1', 5000, app)
self.ctx = app.app_context()
self.ctx.push()
def run(self):
log.info('starting server')
self.srv.serve_forever()
def shutdown(self):
self.srv.shutdown()
def start_server():
global server
app = flask.Flask('myapp')
...
server = ServerThread(app)
server.start()
log.info('server started')
def stop_server():
global server
server.shutdown()
Io lo uso per fare un capo all'altro test per RESTful API, dove posso inviare richieste utilizzando la libreria richieste pitone.
Non sono riuscito a far funzionare le altre cose ma questa soluzione funziona benissimo! Grazie mille! Per le altre persone: funziona anche con il pallone riposante! –
Questo sembra bloccare su Windows fino a quando non lo colpisco con un'altra richiesta ... in ogni modo intorno a questo? – Claudiu
Sto avendo lo stesso problema di @Claudiu, tranne su Linux con Python 3.6.2 – micahscopes
Perché è necessario essere in grado di interrompere l'applicazione da uno script? (Lo strumento migliore per il lavoro dipenderà da ciò che stai cercando di fare). –
Seriamente, cosa stai cercando di fare qui? Se stai parlando di devserver per lo sviluppo, è perfettamente corretto fermarlo in questo modo. In produzione non si distribuisce in questo modo e si può interrompere una richiesta in qualsiasi momento, quindi "l'app smette di funzionare". –
@SeanVieira Voglio sapere se ci sono soluzioni per fare questo. – vrootic