Chcę zaimplementować polecenie, które może zatrzymać aplikację kolby za pomocą skryptu flask. Przez chwilę szukałem rozwiązania. Ponieważ framework nie zapewnia API "app.stop ()", jestem ciekawy, jak to zakodować. Pracuję na Ubuntu 12.10 i Python 2.7.3.
python
flask
flask-extensions
ofiara
źródło
źródło
Odpowiedzi:
Jeśli po prostu uruchamiasz serwer na swoim pulpicie, możesz ujawnić punkt końcowy, aby zabić serwer (przeczytaj więcej w 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...'
Oto inne podejście, które jest bardziej ograniczone:
from multiprocessing import Process server = Process(target=app.run) server.start() # ... server.terminate() server.join()
Daj mi znać, jeśli to pomoże.
źródło
methods='POST'
otrzymuję405 Method not allowed
błąd, podczas gdy z metodami = 'GET' 'działa tak, jak sugerował @CS.Zrobiłem to trochę inaczej używając wątków
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()
Używam go do wykonywania testów od końca do końca dla restful api, gdzie mogę wysyłać żądania za pomocą biblioteki żądań Pythona.
źródło
To trochę stary wątek, ale jeśli ktoś eksperymentuje, uczy się lub testuje podstawową aplikację flask, rozpoczął od skryptu działającego w tle, najszybszym sposobem na zatrzymanie go jest zabicie procesu działającego na porcie, na którym uruchamiasz aplikację na. Uwaga: zdaję sobie sprawę, że autor szuka sposobu, aby nie zabijać ani nie zatrzymywać aplikacji. Ale to może pomóc komuś, kto się uczy.
sudo netstat -tulnp | grep :5001
Dostaniesz coś takiego.
Aby zatrzymać aplikację, zakończ proces
sudo kill 28834
źródło
sudo kill -9 28834
zanim proces został zabity.Moją metodę można kontynuować za pośrednictwem terminala / konsoli bash
1) uruchom i uzyskaj numer procesu
2a) zakończyć proces
2b) zabij proces, jeśli powyższe nie działa
$ kill -9 processNum
źródło
kill -9 `lsof -i:5000 -t`
ponieważ żadna inna aplikacja nie może korzystać z portu i jest to łatwe.Jak zauważyli inni, możesz używać tylko
werkzeug.server.shutdown
od osoby zajmującej się wnioskami. Jedynym sposobem, w jaki znalazłem wyłączenie serwera w innym czasie, jest wysłanie żądania do siebie. Na przykład/kill
program obsługi w tym fragmencie kodu zabije serwer deweloperski, chyba że w ciągu następnej sekundy nadejdzie kolejne żądanie: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.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..."
źródło
To stare pytanie, ale wyszukiwanie w Google nie dało mi wglądu w to, jak to osiągnąć.
Ponieważ nie przeczytałem tutaj poprawnie kodu ! (Doh!) To, co robi, to podbić,
RuntimeError
gdy nie mawerkzeug.server.shutdown
wrequest.environ
...Więc co możemy zrobić, gdy nie ma,
request
to podbićRuntimeError
def shutdown(): raise RuntimeError("Server going down")
i złap to, gdy
app.run()
wrócisz:... 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 ...
Nie musisz wysyłać sobie prośby.
źródło
Nie musisz naciskać „CTRL-C”, ale możesz podać punkt końcowy, który zrobi to za Ciebie:
from flask import Flask, jsonify, request import json, os, signal @app.route('/stopServer', methods=['GET']) def stopServer(): os.kill(os.getpid(), signal.SIGINT) return jsonify({ "success": True, "message": "Server is shutting down..." })
Teraz możesz po prostu wywołać ten punkt końcowy, aby bezpiecznie zamknąć serwer:
curl localhost:5000/stopServer
źródło
os.kill
klient nie może odebrać zwróconej odpowiedzi. W przypadkucurl
, wyświetla komunikat „curl: (56) Recv failure: Connection has reset”. Może zobaczyć także Wykonaj funkcję po tym, jak Flask zwróci odpowiedź, aby ją rozwiązać.Możesz użyć poniższej metody
źródło
Jeśli pracujesz na CLI i masz uruchomioną tylko jedną aplikację / proces kolby (a raczej chcesz po prostu zabić dowolny proces kolby działający w twoim systemie), możesz go zabić:
kill $(pgrep -f flask)
źródło
Jeśli nie zajmujesz się obsługą zapytań i odpowiedzi, nadal możesz:
import os import signal sig = getattr(signal, "SIGKILL", signal.SIGTERM) os.kill(os.getpid(), sig)
źródło
Jeśli ktoś jeszcze szuka sposobu zatrzymania serwera Flask w usłudze win32 - oto on. To trochę dziwne połączenie kilku podejść, ale działa dobrze. Kluczowe pomysły:
shutdown
punkt końcowy, który może służyć do bezpiecznego zamykania. Uwaga : opiera się na tym,request.environ.get
który jest użyteczny tylko w kontekście żądania internetowego (@app.route
funkcja wewnątrz-wewnątrz )SvcStop
Metoda win32service używarequests
do wysyłania żądań HTTP do samej usługi.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://localhost:5001/shutdown')
źródło
Instancja maszyny wirtualnej Google Cloud + aplikacja Flask
Hostowałem moją aplikację Flask na maszynie wirtualnej Google Cloud Platform. Uruchomiłem aplikację za pomocą,
python main.py
ale problem polegał na tym, że ctrl + c nie działało, aby zatrzymać serwer.To polecenie
$ sudo netstat -tulnp | grep :5000
przerywa działanie serwera.Moja aplikacja Flask działa domyślnie na porcie 5000.
Uwaga: moja maszyna wirtualna działa w systemie Linux 9.
To działa w tym przypadku. Nie testowano na innych platformach. Możesz zaktualizować lub skomentować, jeśli działa to również w innych wersjach.
źródło
W systemie Windows zatrzymanie / zabicie serwera flask jest dość łatwe -
źródło