Начните приложение с флягой в отдельной нити
В настоящее время я разрабатываю приложение Python, на котором я хочу видеть статистику в реальном времени. Я хотел использовать Flask
, чтобы упростить его использование и понять.
Проблема в том, что мой сервер Flask должен начинаться с самого начала моего приложения Python и останавливаться в самом конце. Он должен выглядеть следующим образом:
def main():
""" My main application """
from watcher.flask import app
# watcher.flask define an app as in the Quickstart flask documentation.
# See: http://flask.pocoo.org/docs/0.10/quickstart/#quickstart
app.run() # Starting the flask application
do_my_stuff()
app.stop() # Undefined, for the idea
Поскольку мне нужен контекст приложения (для статистики), я не могу использовать multiprocessing.Process
. Затем я пытался использовать threading.Thread
, но похоже, что Werkzeug не нравится:
* Running on http://0.0.0.0:10079/
Exception in thread Flask Server:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner
self.run()
File "/usr/lib/python2.7/threading.py", line 763, in run
self.__target(*self.__args, **self.__kwargs)
File ".../develop-eggs/watcher.flask/src/watcher/flask/__init__.py", line 14, in _run
app.run(host=HOSTNAME, port=PORT, debug=DEBUG)
File ".../eggs/Flask-0.10.1-py2.7.egg/flask/app.py", line 772, in run
run_simple(host, port, self, **options)
File ".../eggs/Werkzeug-0.7-py2.7.egg/werkzeug/serving.py", line 609, in run_simple
run_with_reloader(inner, extra_files, reloader_interval)
File ".../eggs/Werkzeug-0.7-py2.7.egg/werkzeug/serving.py", line 524, in run_with_reloader
signal.signal(signal.SIGTERM, lambda *args: sys.exit(0))
ValueError: signal only works in main thread
Как я могу это сделать без запуска Flask в основном потоке?
Ответы
Ответ 1
Вы запускаете Flask
в режиме отладки, что позволяет перезагрузить (перезагружает сервер Flask при изменении кода).
Флажок может работать отлично в отдельном потоке, но перезагрузчик ожидает выполнения в основном потоке.
Чтобы решить вашу проблему, вы должны либо отключить debug (app.debug = False
), либо отключить перезагрузку (app.use_reloader=False
).
Они также могут передаваться как аргументы app.run
: app.run(debug=True, use_reloader=False)
.
Ответ 2
если вы ищете доступ к ipython-терминалу в колбе
запустите приложение в отдельном потоке,
попробуйте этот пример: -
from flask import Flask
import thread
data = 'foo'
app = Flask(__name__)
@app.route("/")
def main():
return data
def flaskThread():
app.run()
if __name__ == "__main__":
thread.start_new_thread(flaskThread,())
запустите этот файл в ipython
Ответ 3
Из документации werkzeug:
Выключение сервера
Новое в версии 0.7.
Начиная с Werkzeug 0.7 сервер разработки обеспечивает способ завершите работу сервера после запроса. В настоящее время это работает только с Python 2.6 и более поздних версий, и будет работать только с сервером разработки. Чтобы инициировать выключение, вы должны вызвать функцию с именем 'werkzeug.server.shutdown' в среде WSGI:
def shutdown_server(environ):
if not 'werkzeug.server.shutdown' in environ:
raise RuntimeError('Not running the development server')
environ['werkzeug.server.shutdown']()
Ответ 4
Обновленный ответ для Python 3, который немного проще:
from flask import Flask
import threading
data = 'foo'
app = Flask(__name__)
@app.route("/")
def main():
return data
if __name__ == "__main__":
threading.Thread(target=app.run).start()