Beispiel #1
0
    def load_cells_params(self):

        if self.args.cells:
            # module and function name passed with args.cells parameter
            pathname, func_name = self.set_cells(self.args.cells)
            logging.info('Loading cells from {}'.format(self.args.cells))
            uid = '{}:{}'.format(os.path.abspath(pathname), func_name)
            self.cells_name = self.args.cells
        else:
            # Notebook class extended, .cells method contains the target cell
            # Let's make sure that this is the case...
            if self.__class__ == Notebook:
                fatal(
                    'Notebook class not extended and cells parameter is missing'
                )
            logging.info('Loading notebook {}'.format(self.__class__.__name__))
            uid = '{}:{}'.format(
                os.path.abspath(inspect.getfile(self.__class__)),
                self.__class__.__name__)

        # Process parameters passed by custom arguments
        arg_spec = inspect.getargspec(self.cells)
        func_params = arg_spec.args
        # Get default parameters
        default_params = arg_spec.defaults

        self.kwargs = {}

        if default_params:
            default_args_with_value = dict(
                zip(func_params[-len(default_params):], default_params))
            logging.debug(
                'Found default values {}'.format(default_args_with_value))
            # Add default values to kwargs
            self.kwargs.update(default_args_with_value)

        if not self.args.cells:
            # self is always present in case of subclassed Notebook, since cells(self, ...) is a method.
            func_params.remove('self')
            for param in func_params:
                self.kwargs[param] = getattr(self.args, param, None)

        # Process parameters passed with --param
        if self.args.param:
            for param in self.args.param:
                k, v = param.split('=', 1)
                self.kwargs[k] = v

        # Check parameters completeness
        for param in func_params:
            if self.kwargs[param] is None:
                fatal('Notebook parameter {} required but not found'.format(
                    param))

        logging.info('Parameters: {}'.format(self.kwargs))

        self.add(self.cells, **self.kwargs)

        return uid
Beispiel #2
0
    def run(self):
        """
        Run notebook as an application
        :param params: parameters to inject in the notebook
        :return:
        """
        if not self.args:
            self.parse_args()

        added_cells_func = False
        try:
            if self.args.with_generate_cellsfunc:
                self.add_cells_funcion(self.args.cells)
                added_cells_func = True

            if self.args.log_level:
                logging.getLogger().setLevel(
                    logging.getLevelName(self.args.log_level))
                logging.debug('Enabled {} logging level'.format(
                    self.args.log_level))

            if self.args.import_ipynb:
                check_isfile(self.args.import_ipynb)
                logging.info('Loading Jupyter notebook {}'.format(
                    self.args.import_ipynb))
                self.nb = nbf.read(self.args.import_ipynb, as_version=4)
                uid = self.args.import_ipynb
            else:
                uid = self.load_cells_params()

            logging.debug("Unique id: '{}'".format(uid))
            logging.info('Disable cache: {}'.format(self.args.disable_cache))
            logging.info('Ignore cache: {}'.format(self.args.ignore_cache))

            if self.args.export_pynb and not self.args.no_exec:
                fatal('--export-pynb requires --no-exec')

            if self.args.kernel:
                self.set_kernel(self.args.kernel)

            self.process(uid=uid,
                         add_footer=not self.args.disable_footer,
                         no_exec=self.args.no_exec,
                         disable_cache=self.args.disable_cache,
                         ignore_cache=self.args.ignore_cache)

            if self.args.export_html:
                self.export_html(self.args.export_html)

            if self.args.export_ipynb:
                self.export_ipynb(self.args.export_ipynb)

            if self.args.export_pynb:
                self.export_pynb(self.args.export_pynb)
        finally:
            if added_cells_func:
                self.remove_cells_funcion(self.args.cells)
Beispiel #3
0
    def run(self):
        """
        Run notebook as an application
        :param params: parameters to inject in the notebook
        :return:
        """

        if not self.args:
            self.parse_args()

        logging.info(self.long_name)

        if self.args.debug:
            logging.getLogger().setLevel(logging.DEBUG)
            logging.debug('Enabled DEBUG logging level')

        if self.args.import_ipynb:
            check_isfile(self.args.import_ipynb)
            logging.info('Loading Jupyter notebook {}'.format(
                self.args.import_ipynb))
            self.nb = nbf.read(self.args.import_ipynb, as_version=4)
            uid = self.args.import_ipynb
        else:
            uid = self.load_cells_params()

        logging.debug("Unique id: '{}'".format(uid))
        logging.info('Disable cache: {}'.format(self.args.disable_cache))
        logging.info('Ignore cache: {}'.format(self.args.ignore_cache))

        if self.args.export_pynb and not self.args.no_exec:
            fatal('--export-pynb requires --no-exec')

        self.process(uid=uid,
                     no_exec=self.args.no_exec,
                     disable_cache=self.args.disable_cache,
                     ignore_cache=self.args.ignore_cache)

        if self.args.export_html:
            self.export_html(self.args.export_html)

        if self.args.export_ipynb:
            self.export_ipynb(self.args.export_ipynb)

        if self.args.export_pynb:
            self.export_pynb(self.args.export_pynb)
Beispiel #4
0
    def set_cells(self, cells_location):
        """
        Set self.cells to function :cells in file pathname.py
        :param cells_location: cells location, format 'pathname.py:cells'
        :return:
        """

        if ':' in cells_location:
            pathname, func_name = cells_location.split(':')
        else:
            pathname = cells_location
            func_name = 'cells'

        check_isfile(pathname)

        try:
            self.cells = get_func(func_name, pathname)
        except SyntaxError as e:
            fatal(traceback.format_exc(limit=1))

        return pathname, func_name
Beispiel #5
0
    def set_cells(self, cells_location):
        """
        Set self.cells to function :cells in file pathname.py
        :param cells_location: cells location, format 'pathname.py:cells'
        :return:
        """

        if ':' in cells_location:
            pathname, func_name = cells_location.split(':')
        else:
            pathname = cells_location
            func_name = 'cells'

        check_isfile(pathname)

        try:
            self.cells = get_func(func_name, pathname)
        except Exception as e:
            logging.error(traceback.format_exc())
            fatal("Function '{}' not found in '{}': {}".format(
                func_name, pathname, e))

        return pathname, func_name
Beispiel #6
0
    def add(self, func, **kwargs):
        """
        Parse func's function source code as Python and Markdown cells.
        :param func: Python function to parse
        :param kwargs: variables to inject as first Python cell
        :return:
        """

        params = set(kwargs.keys())
        func_params = set(inspect.getargspec(func).args)

        # ignore self, which is present when extending Notebook.
        if 'self' in func_params:
            func_params.remove('self')

        if params != func_params:
            fatal('Params {} not matching cells function params {}'.format(
                list(params), list(func_params)))

        lines = inspect.getsourcelines(func)[0][1:]

        buffer = ""
        indent_count = None
        inside_markdown = False
        return_found = False

        for line in lines:

            # remove base indentation of function 'func'
            if len(line.strip()) > 0:
                if not indent_count:
                    indent_count = 0
                    for c in line:
                        if c not in [' ', '\t']:
                            break
                        else:
                            indent_count += 1
                line = line[indent_count:]

            if not inside_markdown and line.strip() == "return":
                logging.info(
                    'Encountered "return" statement, ignoring the rest of the notebook.'
                )
                break

            if line.strip() == "'''":  # if md block begin/end, or new cell...
                if len(buffer.strip()) > 0:
                    if not inside_markdown:  # if md block begin: new markdown block! flush buffer
                        self.add_cell_code(buffer)
                    else:  # if md block end: markdown block completed! flush buffer
                        self.add_cell_markdown(buffer)
                buffer = ""
                inside_markdown = not inside_markdown
            else:
                buffer += line

        if len(buffer.strip()) > 0:
            if not inside_markdown:
                self.add_cell_code(buffer)
            else:
                self.add_cell_markdown(buffer)

        if len(kwargs) > 0:
            # We have parameters to inject into the notebook.
            # If the first cell is Markdown, assume that is the title and
            # insert parameters as 2nd cell. Otherwise, as 1st cell.
            if len(self.nb['cells']
                   ) > 0 and self.nb['cells'][0].cell_type == 'markdown':
                self.add_cell_params(kwargs, 1)
            else:
                self.add_cell_params(kwargs, 0)