Skip to content

Instantly share code, notes, and snippets.

@abegong
Last active October 8, 2015 22:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save abegong/bc4310de32ca25be73d8 to your computer and use it in GitHub Desktop.
Save abegong/bc4310de32ca25be73d8 to your computer and use it in GitHub Desktop.
"""
watcher.py
A nifty little script for responsive coding ala Brackets, but in python
It watches a directory for file changes, then executes an aribtrary python script.
Imports and large data loads can be cached at setup so that the remaining code can execute very fast.
See more about intended use case here:
http://stackoverflow.com/questions/32997698/auto-run-a-python-script-without-reloading-dependencies
The imported module must have methods for setup() and update().
Setup can return a dictionary object that will be used to populate arguments for update.
Ex:
def setup():
foo = set_up_some_stuff()
return {
'foo' : foo,
'bar' = "bar, naturally",
}
def update(foo, bar):
print foo, bar
"""
import sys
import datetime
import time
import traceback
import json
import argh
import importlib
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
class MyHandler(FileSystemEventHandler):
def __init__(self, module, module_data):
super(MyHandler, self).__init__()
self.module = module
self.module_data = module_data
def on_modified(self, event):
now = datetime.datetime.now()
if hasattr(self, 'last_ts'):
if (now - self.last_ts).total_seconds() < 1:
# print "too soon, doing nothing"
return
print "Handling a new event..."
self.last_ts = now
try:
reload(self.module)
self.module.update(**self.module_data)
except Exception, err:
print "===== Ran into an error ====="
print(traceback.format_exc())
@argh.arg('module_name')
@argh.arg('-p', '--file_path', default='.')
@argh.arg('-c', '--config_file', default=None)
def main(module_name, **kwargs):
print 'Launching watcher...'
if kwargs['config_file']:
config = json.load(file(kwargs['config_file']))
else:
config = {}
print 'Importing and setting up module', module_name
module = importlib.import_module(module_name)
module_data = module.setup(**config)
print 'Launching event_handler and observer to watch for file changes...'
event_handler = MyHandler(module, module_data)
observer = Observer()
observer.schedule(event_handler, kwargs['file_path'])
observer.start()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
observer.join()
argh.dispatch_command(main)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment