Source code for schrodinger.job.driver_decorator

"""
Main function decorator designed for backend jobs. For example::

    @driver_decorator.main_wrapper("A super nifty backend")
    def main():
        do_some_cool_work()

Copyright Schrodinger, LLC. All rights reserved.
"""

import datetime

from decorator import decorator

from schrodinger.job import jobcontrol
from schrodinger.utils import cmdline
from schrodinger.utils import log

logger = log.get_output_logger(__file__)


[docs]@decorator def main_wrapper(func, driver_name="Job", *args, **kwargs): """ The backend job's application header string is logged only if job is running under jobcontrol. Running time is logged after job succeeds, or when an exception is caught. Running time won't be logged if sys.exit() in called inside main(), or job is terminated via keyboard interruption. """ def _driver_wrapper(*args, **kwargs): backend = jobcontrol.get_backend() if backend: logger.info(backend.getJob().getApplicationHeaderString()) t1 = datetime.datetime.now() status = "successfully completed." try: result = func(*args, **kwargs) except KeyboardInterrupt: status = "interrupted." raise except SystemExit as e: status = f"exited.\n\nSystemExit: {e}" raise except Exception: status = "failed." raise finally: t2 = datetime.datetime.now() dt = str(t2 - t1)[:-4] # Hack to only print only hundredths of sec logger.info("") logger.info(f"Current time: {t2.ctime()}") logger.info(f"Elapsed time: {dt}") logger.info(f"{driver_name} {status}") logger.info("") return result return cmdline.main_wrapper(_driver_wrapper, *args, **kwargs)