Source code for custom_step.custom

# -*- coding: utf-8 -*-

"""Non-graphical part of the Custom step in a SEAMM flowchart"""

import logging
import os

import custom_step
import seamm
import seamm_util.printing as printing
from seamm_util.printing import FormattedText as __

logger = logging.getLogger(__name__)
job = printing.getPrinter()
printer = printing.getPrinter("Custom")


[docs] class cd: """Context manager for changing the current working directory""" def __init__(self, newPath): self.newPath = os.path.expanduser(newPath) def __enter__(self): self.savedPath = os.getcwd() os.chdir(self.newPath) def __exit__(self, etype, value, traceback): os.chdir(self.savedPath)
[docs] class Custom(seamm.Node): def __init__( self, flowchart=None, title="Custom Python", extension=None, logger=logger ): """A step for custom python in a SEAMM flowchart. You may wish to change the title above, which is the string displayed in the box representing the step in the flowchart. Parameters ---------- flowchart: seamm.Flowchart The non-graphical flowchart that contains this step. title: str The name displayed in the flowchart. extension: None Not yet implemented logger : Logger = logger The logger to use and pass to parent classes Returns ------- None """ logger.debug("Creating Custom {}".format(self)) super().__init__( flowchart=flowchart, title=title, extension=extension, logger=logger ) self.parameters = custom_step.CustomParameters() @property def version(self): """The semantic version of this module.""" return custom_step.__version__ @property def git_revision(self): """The git version of this module.""" return custom_step.__git_revision__
[docs] def description_text(self, P=None): """Create the text description of what this step will do. The dictionary of control values is passed in as P so that the code can test values, etc. Parameters ---------- P: dict An optional dictionary of the current values of the control parameters. Returns ------- str A description of the current step. """ if not P: P = self.parameters.values_to_dict() script = P["script"].splitlines() if len(script) > 10: text = "\n".join(script[0:9]) text += "\n..." else: text = "\n".join(script) return self.header + "\n" + __(text, indent=4 * " ", wrap=False).__str__()
[docs] def run(self): """Run a Custom step.""" next_node = super().run(printer) # Get the values of the parameters, dereferencing any variables P = self.parameters.current_values_to_dict( context=seamm.flowchart_variables._data ) # Print what we are doing -- getting formatted values for printing printer.normal(self.header) # Override simple print statements script = ( "import builtins\n" "import seamm_util.printing as printing\n" "job = printing.getPrinter()\n" "original_print = print\n" "\n" "def new_print(*objects, sep=' ', **kwargs):\n" " if len(kwargs) > 0:\n" " builtins.print(*objects, sep=sep, **kwargs)\n" " else:\n" " job.job(sep.join(objects))\n" "print = new_print\n" ) script += P["script"] # And do it! os.makedirs(self.directory, exist_ok=True) try: with cd(self.directory): exec(script, seamm.flowchart_variables._data) except Exception as e: printer.normal(f"\n ***{e.__class__.__name__}*** {str(e)}") raise else: printer.normal(" --- end of script ---") printer.normal("") return next_node