.. image:: https://img.shields.io/pypi/v/hupper.svg :target: https://pypi.python.org/pypi/hupper
.. image:: https://github.com/Pylons/hupper/workflows/Build/test%20on%20Linux/badge.svg?branch=master :target: https://github.com/Pylons/hupper/actions?query=workflow%3A%22Build%2Ftest+on+Linux%22
.. image:: https://github.com/Pylons/hupper/workflows/Build/test%20on%20MacOS/badge.svg?branch=master :target: https://github.com/Pylons/hupper/actions?query=workflow%3A%22Build%2Ftest+on+MacOS%22
.. image:: https://github.com/Pylons/hupper/workflows/Build/test%20on%20Windows/badge.svg?branch=master :target: https://github.com/Pylons/hupper/actions?query=workflow%3A%22Build%2Ftest+on+Windows%22
.. image:: https://readthedocs.org/projects/hupper/badge/?version=latest :target: https://readthedocs.org/projects/hupper/?badge=latest :alt: Documentation Status
hupper is an integrated process monitor that will track changes to
any imported Python files in
sys.modules as well as custom paths. When
files are changed the process is restarted.
Hupper can load any Python code similar to
python -m <module> by using the
hupper -m <module> program.
.. code-block:: console
$ hupper -m myapp Starting monitor for PID 23982.
Start by defining an entry point for your process. This must be an importable
path in string format. For example,
.. code-block:: python
# myapp/scripts/serve.py import sys import hupper import waitress def wsgi_app(environ, start_response): start_response('200 OK', [('Content-Type', 'text/plain')]) yield b'hello' def main(args=sys.argv[1:]): if '--reload' in args: # start_reloader will only return in a monitored subprocess reloader = hupper.start_reloader('myapp.scripts.serve.main') # monitor an extra file reloader.watch_files(['foo.ini']) waitress.serve(wsgi_app)
hupper is inspired by initial work done by Carl J Meyer and David Glick
during a Pycon sprint and is built to be a more robust and generic version of
Ian Bicking's excellent PasteScript
paste serve --reload and Pyramid's
Support Python 3.8 and 3.9.
Fix an issue with bare
.pyc files in the source folder causing unhandled
Fix issues with using the Watchman file monitor on versions newer than
Watchman 4.9.0. This fix modifies
hupper to use Watchman's
watch-project capabilities which also support reading the
.watchmanconfig file to control certain properties of the monitoring.
SIGTERM signal by forwarding it to the child process and
gracefully waiting for it to exit. This should enable using
from within docker containers and other systems that want to control
the reloader process.
SIGTERM would shutdown
hupper immediately, stranding
the worker and relying on it to shutdown on its own.
Avoid acquiring locks in the reloader process's signal handlers. See https://github.com/Pylons/hupper/pull/65
Fix deprecation warnings caused by using the
imp module on newer
versions of Python.
site-packages. These were previously being ignored by the file monitor but should now be tracked. See https://github.com/Pylons/hupper/pull/61
--shutdown-interval on the
--reload-interval on the
Do not choke when stdin is not a TTY while waiting for changes after a crash. For example, when running in Docker Compose. See https://github.com/Pylons/hupper/pull/58
KeyboardInterruptstacktrace when killing
hupperwhile waiting for a reload.
huppercan be forced to reload the worker by pressing the
ENTERkey in the terminal instead of waiting to change a file. See https://github.com/Pylons/hupper/pull/53
reloader.watch_files. See https://github.com/Pylons/hupper/pull/52
hupperwould go into a restart loop instead of waiting for a code change. See https://github.com/Pylons/hupper/pull/50
On systems that support
SIGTERM (not Windows),
will now send a
SIGKILL to the worker process as a last resort. Normally,
SIGINT (Ctrl-C) or
SIGTERM (on reload) will kill the worker. If,
shutdown_interval seconds, the worker doesn't exit, it will
logger argument to
hupper.start_reloader to override
the default logger that outputs messages to
huppercli also supports ignoring files via the
-xoption. See https://github.com/Pylons/hupper/pull/46
site-packages. Anything that is installed in editable mode or not installed at all will still be monitored. This drastically reduces the number of files that
hupperneeds to monitor. See https://github.com/Pylons/hupper/pull/40
Support Python 3.7.
Avoid a restart-loop if the app is failing to restart on certain systems.
There was a race where
hupper failed to detect that the app was
crashing and thus fell into its restart logic when the user manually
triggers an immediate reload.
Ignore corrupted packets coming from watchman that occur in semi-random scenarios. See https://github.com/Pylons/hupper/pull/38
Added watchman support via
This is the new preferred file monitor on systems supporting unix sockets.
hupper.watchdog.WatchdogFileMonitor will now output some info
when it receives ulimit or other errors from
-v cli options to control verbosity.
logger value to the
This is an instance of
hupper.interfaces.ILogger and can be used by
file monitors to output errors and debug information.
Track only Python source files. Previously
hupper would track all pyc
and py files. Now, if a pyc file is found then the equivalent source file
is searched and, if found, the pyc file is ignored.
Allow overriding the default monitor lookup by specifying the
HUPPER_DEFAULT_MONITOR environment variable as a Python dotted-path
to a monitor factory. For example,
Backward-incompatible changes to the
hupper.interfaces.IFileMonitorFactory API to pass arbitrary kwargs
to the factory.
-won the CLI to watch custom file paths. See https://github.com/Pylons/hupper/pull/28
sys.pathto the worker process and ensure
hupperis on the
PYTHONPATHso that the subprocess can import it to start the worker. This fixes an issue with how
zc.buildoutinjects dependencies into a process which is done entirely by
sys.pathmanipulation. See https://github.com/Pylons/hupper/pull/27
Pause briefly after receiving a SIGINT to allow the worker to kill itself. If it does not die then it is terminated. See https://github.com/Pylons/hupper/issues/11
Python 3.6 compatibility.
hupper -m <module>. This is equivalent to
python -mexcept will fully reload the process when files change. See https://github.com/Pylons/hupper/pull/8
globmodule. On Python 3.5+ this allows recursive globs using
**. Prior to this, the globbing is more limited.
Support triggering reloads via SIGHUP when hupper detected a crash and is waiting for a file to change.
Setup the reloader proxy prior to importing the worker's module. This should allow some work to be done at module-scope instead of in the callable.
Fix package long description on PyPI.
Ensure that the stdin file handle is inheritable incase the "spawn" variant of multiprocessing is enabled.
Disable bytecode compiling of files imported by the worker process. This should not be necessary when developing and it was causing the process to restart twice on Windows due to how it handles pyc timestamps.
Fix hupper's support for forwarding stdin to the worker processes on Python < 3.5 on Windows.
Fix some possible file descriptor leakage.
hupper.interfaces.IFileMonitor interface by internalizing
some of the hupper-specific integrations. They can now focus on just
looking for changes.
hupper.interfaces.IFileMonitorFactory interface to improve
the documentation for the
callback argument required by
Added support for
watchdog <https://pypi.org/project/watchdog/>_ if it's
installed to do inotify-style file monitoring. This is an optional dependency
hupper will fallback to using polling if it's not available.