Skip to content

ipython

ConsoleWriter

Bases: Magics

Class that connects IPython with mkreports using magics.

Source code in mkreports/ipython.py
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
@magics_class
class ConsoleWriter(Magics):
    """
    Class that connects IPython with mkreports using magics.
    """

    handlers: List[Handler]
    console: Page

    def __init__(self, ip):
        """Initialization. Not for end-users."""
        super().__init__(ip)
        self.shell = ip
        self.handlers = []
        self.stored_code = []

        # identify an mkreport
        self.report = Report.create(
            get_mkreports_dir(),
            report_name="Mkreports console",
            exist_ok=True,
        )
        self._open_console()
        self._set_default_handlers()

    def _set_default_handlers(self):
        self.handlers = create_default_handlers(self.console.md)

    def _get_handler(self, obj: Any) -> Optional[Handler]:
        return get_handler(obj, self.handlers)

    def _open_console(self) -> None:
        self.console = self.report.page(Path("console/active.md"), add_bottom=False)
        # make sure the table of contents does not get shown
        self.console.HideToc()

    @line_magic
    def archive_console(self, line):
        """
        Function to archive the console. This is also a line magic, however
        the line itself will be ignored.

        Args:
            line (str): ignored.
        """
        del line
        # we also need to add a navigation entry
        new_entry = ["Console", f"{datetime.now().strftime('%Y/%m/%d %H:%M:%S')}"]
        new_path = (
            self.console.path.parent / f"{datetime.now().strftime('%Y%m%d_%H%M%S')}.md"
        )

        # we move the page out of the way
        shutil.move(
            str(self.console.path),
            new_path,
        )
        self.report._add_nav_entry((new_entry, new_path))
        self._open_console()

    def post_run_cell(self, result):
        """
        Print any results of certain classes automatically to the console.

        Here we set some defaults so that results of certain classes are
        automatically written to the console, mostly data tables and images.
        These will then also have the corresponding code attached to them.
        """
        if result.success:
            # we store the cell content
            self.stored_code.append(result.info.raw_cell)
            handler = self._get_handler(result.result)
            if handler is not None:
                content = handler.func(result.result)
                code = md.Code("\n".join(self.stored_code), language="python")

                code_content = do_layout(
                    code=code,
                    content=content,
                    layout=self.console.code_layout,
                    page_info=self.console.page_info,
                )
                # and we also want a separator and a date
                post = (
                    md.H6(f"{datetime.now().strftime('%Y/%m/%d %H:%M:%S')}")
                    + code_content
                )
                self.console.add(post)
                self.stored_code = []

__init__(ip)

Initialization. Not for end-users.

Source code in mkreports/ipython.py
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
def __init__(self, ip):
    """Initialization. Not for end-users."""
    super().__init__(ip)
    self.shell = ip
    self.handlers = []
    self.stored_code = []

    # identify an mkreport
    self.report = Report.create(
        get_mkreports_dir(),
        report_name="Mkreports console",
        exist_ok=True,
    )
    self._open_console()
    self._set_default_handlers()

archive_console(line)

Function to archive the console. This is also a line magic, however the line itself will be ignored.

Parameters:

Name Type Description Default
line str

ignored.

required
Source code in mkreports/ipython.py
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
@line_magic
def archive_console(self, line):
    """
    Function to archive the console. This is also a line magic, however
    the line itself will be ignored.

    Args:
        line (str): ignored.
    """
    del line
    # we also need to add a navigation entry
    new_entry = ["Console", f"{datetime.now().strftime('%Y/%m/%d %H:%M:%S')}"]
    new_path = (
        self.console.path.parent / f"{datetime.now().strftime('%Y%m%d_%H%M%S')}.md"
    )

    # we move the page out of the way
    shutil.move(
        str(self.console.path),
        new_path,
    )
    self.report._add_nav_entry((new_entry, new_path))
    self._open_console()

post_run_cell(result)

Print any results of certain classes automatically to the console.

Here we set some defaults so that results of certain classes are automatically written to the console, mostly data tables and images. These will then also have the corresponding code attached to them.

Source code in mkreports/ipython.py
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
def post_run_cell(self, result):
    """
    Print any results of certain classes automatically to the console.

    Here we set some defaults so that results of certain classes are
    automatically written to the console, mostly data tables and images.
    These will then also have the corresponding code attached to them.
    """
    if result.success:
        # we store the cell content
        self.stored_code.append(result.info.raw_cell)
        handler = self._get_handler(result.result)
        if handler is not None:
            content = handler.func(result.result)
            code = md.Code("\n".join(self.stored_code), language="python")

            code_content = do_layout(
                code=code,
                content=content,
                layout=self.console.code_layout,
                page_info=self.console.page_info,
            )
            # and we also want a separator and a date
            post = (
                md.H6(f"{datetime.now().strftime('%Y/%m/%d %H:%M:%S')}")
                + code_content
            )
            self.console.add(post)
            self.stored_code = []

load_ipython_extension(ip)

Loading of the IPython Extension.

Identify the report to use and export a page representing the console to use.

Also insert handlers that automatically send appropriate results to be appended to the console. The console object should be part of the user-space, same as the markdown module for use.

Source code in mkreports/ipython.py
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
def load_ipython_extension(ip):
    """
    Loading of the IPython Extension.

    Identify the report to use and
    export a page representing the console to use.

    Also insert handlers that automatically send appropriate results
    to be appended to the console. The console object should be part
    of the user-space, same as the markdown module for use.
    """
    cw = ConsoleWriter(ip)

    cw.shell.push({"md": cw.console.md, "cons": cw.console})
    ip.events.register("post_run_cell", cw.post_run_cell)
    ip.register_magics(cw)