Last active
October 8, 2015 22:05
-
-
Save abegong/bc4310de32ca25be73d8 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
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