Source code for schrodinger.ui.qt.schrodinger_ipython
import types
import warnings
from IPython import get_ipython
from qtconsole import inprocess
from qtconsole import rich_jupyter_widget
from schrodinger import get_maestro
from schrodinger.ui.qt.appframework2 import af2
with warnings.catch_warnings():
    warnings.filterwarnings(action="ignore",
                            category=DeprecationWarning,
                            module="ipykernel",
                            message="the imp module")
    from ipykernel.inprocess import ipkernel
[docs]class SchrodingerIPython(af2.App):
[docs]    def setPanelOptions(self):
        super(SchrodingerIPython, self).setPanelOptions()
        self.title = 'IPython with Maestro integration' 
[docs]    def setup(self):
        super(SchrodingerIPython, self).setup()
        # Add a warning filter so that we don't get deprecation warnings printed
        # to the terminal every time the user hits Enter
        warnings.filterwarnings("ignore",
                                category=DeprecationWarning,
                                module=r".*(jupyter)|(traitlets)")
        # Ignore all DeprecationWarnings that get generated during setup.
        # Traitlets somehow ignores the warning filters for one warning it
        # generates, so we use record=True to temporarily override
        # warning.showwarning and suppress that one as well.
        with warnings.catch_warnings(record=True):
            # Create an in-process kernel
            self.kernel_manager = KernelManagerWithUserModule()
            self.kernel_manager.start_kernel()
            kernel = self.kernel_manager.kernel
            kernel.gui = 'qt'
            self.kernel_client = self.kernel_manager.client()
            self.kernel_client.start_channels()
            # disable Jedi to fix tab-completion
            # in maestro IPython shell BLDMGR-4613
            get_ipython().Completer.use_jedi = False
            self.widget = rich_jupyter_widget.RichJupyterWidget()
            self.widget.kernel_manager = self.kernel_manager
            self.widget.kernel_client = self.kernel_client
            self.widget.execute("%matplotlib inline")
            if get_maestro():
                self.widget.execute("from schrodinger import maestro")
            # A blank execute call is required to clear the input area.
            # Otherwise the terminal will start with "from schrodinger import
            # maestro" on the current input line.
            self.widget.execute("") 
[docs]    def layOut(self):
        super(SchrodingerIPython, self).layOut()
        self.main_layout.addWidget(self.widget)  
[docs]class KernelManagerWithUserModule(inprocess.QtInProcessKernelManager):
    """
    This kernel manager starts its kernel with a custom namespace rather than
    replacing the __main__ namespace, which is the standard
    InProcessKernelManager behavior.  If the __main__ namespace gets replaced,
    then we'll get exceptions every time Maestro runs a Python command.  (When
    executing Python code from C++, Maestro temporarily modifies sys.path to
    ensure that the executed code can import any modules that it needs.  This
    code is runs in the __main__ namespace, so replacing that namespace removes
    the sys import and the temporary variables that Maestro expects.  See
    MAE-35487.)
    """
[docs]    def __init__(self, *args, **kwargs):
        super(KernelManagerWithUserModule, self).__init__(*args, **kwargs)
        self._user_module = types.ModuleType(
            "ipython_kernel_namespace",
            "The module that the IPython InProcessKernel is executed in") 
[docs]    def start_kernel(self, **kwargs):
        """
        Start the kernel using a non-__main__ namespace.  Note that all
        arguments to this method are ignored, as that's the behavior of
        QtInProcessKernelManager.
        """
        self.kernel = ipkernel.InProcessKernel(parent=self,
                                               session=self.session,
                                               user_module=self._user_module)