如何使用 Flask+uWSGI 设置自动重新加载?

发布于 2024-12-26 03:03:50 字数 114 浏览 1 评论 0原文

我正在为 Flask 寻找类似于 uWSGI + django 自动重载模式 的东西。

I am looking for something like uWSGI + django autoreload mode for Flask.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

撑一把青伞 2025-01-02 03:03:50

我正在运行 uwsgi 版本 1.9.5 并且该选项

uwsgi --py-autoreload 1

效果很好

I am running uwsgi version 1.9.5 and the option

uwsgi --py-autoreload 1

works great

鸠魁 2025-01-02 03:03:50

如果您使用命令参数配置 uwsgi,请传递 --py-autoreload=1

uwsgi --py-autoreload=1

如果您使用 .ini 文件配置 uwsgi 并使用 uwsgi --ini,将以下内容添加到您的 .ini 文件中:

py-autoreload = 1

If you're configuring uwsgi with command arguments, pass --py-autoreload=1:

uwsgi --py-autoreload=1

If you're using a .ini file to configure uwsgi and using uwsgi --ini, add the following to your .ini file:

py-autoreload = 1
好听的两个字的网名 2025-01-02 03:03:50

对于开发环境,您可以尝试使用
--python-autoreload uwsgi的参数。
查看源代码,它可能仅在线程模式下工作(--enable-threads)。

For development environment you can try using
--python-autoreload uwsgi's parameter.
Looking at the source code it may work only in threaded mode (--enable-threads).

情话难免假 2025-01-02 03:03:50

您可以尝试使用supervisord作为您的Uwsgi应用程序的管理器。它还具有监视功能,可以在文件或文件夹被“触摸”/修改时自动重新加载进程。

您会在这里找到一个很好的教程: Flask+NginX+Uwsgi+Supervisord

You could try using supervisord as a manager for your Uwsgi app. It also has a watch function that auto-reloads a process when a file or folder has been "touched"/modified.

You will find a nice tutorial here: Flask+NginX+Uwsgi+Supervisord

江城子 2025-01-02 03:03:50

开发模式 Flask 的自动重载功能实际上是由底层 Werkzeug 库提供的。相关代码位于 werkzeug/serving.py 中——值得一看。但基本上,主应用程序将 WSGI 服务器作为子进程生成,每秒对每个活动 .py 文件进行一次统计,以查找更改。如果它看到任何内容,子进程就会退出,父进程会再次启动它——实际上是重新加载更改。

您没有理由不能在 uWSGI 层实现类似的技术。如果您不想使用统计循环,可以尝试使用底层操作系统文件监视命令。显然(根据 Werkzeug 的代码), pyinotify 是有问题的,但也许 看门狗 有效吗?尝试一些事情,看看会发生什么。

编辑:

针对评论,我认为这很容易重新实现。基于您的链接提供的示例以及 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

它未经测试,但应该可以工作。

The auto-reloading functionality of development-mode Flask is actually provided by the underlying Werkzeug library. The relevant code is in werkzeug/serving.py -- it's worth taking a look at. But basically, the main application spawns the WSGI server as a subprocess that stats every active .py file once per second, looking for changes. If it sees any, the subprocess exits, and the parent process starts it back up again -- in effect reloading the chages.

There's no reason you couldn't implement a similar technique at the layer of uWSGI. If you don't want to use a stat loop, you can try using underlying OS file-watch commands. Apparently (according to Werkzeug's code), pyinotify is buggy, but perhaps Watchdog works? Try a few things out and see what happens.

Edit:

In response to the comment, I think this would be pretty easy to reimplement. Building on the example provided from your link, along with the code from 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

It's untested, but should work.

聚集的泪 2025-01-02 03:03:50

py-autoreload=1

.ini 文件中的

py-autoreload=1

in the .ini file does the job

撑一把青伞 2025-01-02 03:03:50
import gevent.wsgi
import werkzeug.serving

@werkzeug.serving.run_with_reloader
def runServer():
    gevent.wsgi.WSGIServer(('', 5000), app).serve_forever()

(您可以使用任意 WSGI 服务器)

import gevent.wsgi
import werkzeug.serving

@werkzeug.serving.run_with_reloader
def runServer():
    gevent.wsgi.WSGIServer(('', 5000), app).serve_forever()

(You can use an arbitrary WSGI server)

留蓝 2025-01-02 03:03:50

我担心 Flask 实在是太简单了,无法默认捆绑这样的实现。

在生产环境中动态重新加载代码通常是一件坏事,但如果您关心开发环境,请看一下这个 bash shell 脚本 http://aplawrence.com/Unixart/watchdir.html

只需将睡眠间隔更改为适合您需要的值,并将 echo 命令替换为您用来重新加载 uwsgi 的命令即可。我在主模式下运行 uwsgi 并只发送一个 Killall uwsgi 命令。

I am afraid that Flask is really too bare bones to have an implementation like this bundled by default.

Dynamically reloading code in production is generally a bad thing, but if you are concerned about a dev environment, take a look at this bash shell script http://aplawrence.com/Unixart/watchdir.html

Just change the sleep interval to whatever suits your needs and substitute the echo command with whatever you use to reload uwsgi. I run uwsgi un master mode and just send a killall uwsgi command.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文