web-dev-qa-db-ja.com

Flask + uWSGIで自動再読み込みを設定する方法は?

私は WSGI + Django autoreload mode for Flaskのようなものを探しています。

31
Florian

あなたはあなたのUwsgiアプリのマネージャーとしてsupervisordを使ってみることができます。また、ファイルまたはフォルダーが「タッチ」/変更されたときにプロセスを自動再読み込みする監視機能もあります。

ここに素敵なチュートリアルがあります: Flask + NginX + Uwsgi + Supervisord

10
verrochio

私はuwsgiバージョン1.9.5とオプションを実行しています

uwsgi --py-autoreload 1

よく働く

53
srossross

コマンド引数を使用してuwsgiを構成する場合は、--py-autoreload=1を渡します。

uwsgi --py-autoreload=1

.iniファイルを使用してuwsgiを構成し、uwsgi --iniを使用している場合は、.iniファイルに以下を追加します。

py-autoreload = 1
16
Luke Taylor

開発環境では、-python-autoreload uwsgiのパラメーターを使用してみてください。ソースコードを見ると、スレッドモード(--enable-threads)でしか機能しない可能性があります。

13
Tagar

Development-mode Flaskの自動リロード機能は、実際には基盤となるWerkzeugライブラリによって提供されます。関連するコードはwerkzeug/serving.pyにあります-見てみる価値があります。ただし、基本的には、メインアプリケーションがWSGIサーバーをサブプロセスとして生成し、すべてのアクティブな.pyファイルを毎秒1回統計し、変更を探します。変更が見つかると、サブプロセスは終了し、親プロセスが再びそれを開始します-事実上変更をリロードします。

UWSGIのレイヤーで同様の手法を実装できなかった理由はありません。 statループを使用したくない場合は、基礎となるOSのファイル監視コマンドを使用してみてください。どうやら(Werkzeugのコードによると) pyinotify はバグが多いですが、おそらく Watchdog は機能しますか?いくつかのことを試して、何が起こるかを確認してください。

編集:

コメントに応じて、これは再実装するのがかなり簡単になると思います。リンクから提供された例とwerkzeug/serving.pyのコードを基に作成します。

""" NOTE: _iter_module_files() and check_for_modifications() are both
    copied from Werkzeug code. Include appropriate attribution if
    actually used in a project. """
import uwsgi
from uwsgidecorators import timer

import sys
import os

def _iter_module_files():
    for module in sys.modules.values():
        filename = getattr(module, '__file__', None)
        if filename:
            old = None
            while not os.path.isfile(filename):
                old = filename
                filename = os.path.dirname(filename)
                if filename == old:
                    break
            else:
                if filename[-4:] in ('.pyc', '.pyo'):
                    filename = filename[:-1]
                yield filename

@timer(3)
def check_for_modifications():
    # Function-static variable... you could make this global, or whatever
    mtimes = check_for_modifications.mtimes
    for filename in _iter_module_files():
        try:
            mtime = os.stat(filename).st_mtime
        except OSError:
            continue

        old_time = mtimes.get(filename)
        if old_time is None:
            mtimes[filename] = mtime
            continue
        Elif mtime > old_time:
            uwsgi.reload()
            return

check_for_modifications.mtimes = {} # init static

テストされていませんが、動作するはずです。

5
twooster