Skip to content

Instantly share code, notes, and snippets.

@campanelli-resonon
Created April 24, 2019 20:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save campanelli-resonon/5b4f4a5648f49716e9bf4995d0d3a0fc to your computer and use it in GitHub Desktop.
Save campanelli-resonon/5b4f4a5648f49716e9bf4995d0d3a0fc to your computer and use it in GitHub Desktop.
Creating a Spyder-compatible kernel to run embedded within another Python app using IPython
"""Simple function for embedding an IPython kernel."""
import sys
from IPython.utils.frame import extract_module_locals
import ipykernel.kernelapp
from traitlets import Type
# Subclass the IPKernelApp, making it point to the SpyderKernel subclass of the IPython kernel.
class SpyderKernelApp(ipykernel.kernelapp.IPKernelApp):
kernel_class = Type(
'spyder_kernels.console.kernel.SpyderKernel', klass='ipykernel.kernelbase.Kernel').tag(config=True)
def __init__(self, *args, **kwargs):
super(SpyderKernelApp, self).__init__(*args, **kwargs)
# This is copy pasta of embed_kernel() from ipykernel's embed.py.
def embed_kernel(module=None, local_ns=None, **kwargs):
"""Embed and start an IPython kernel in a given scope.
Parameters
----------
module : ModuleType, optional
The module to load into IPython globals (default: caller)
local_ns : dict, optional
The namespace to load into IPython user namespace (default: caller)
kwargs : various, optional
Further keyword args are relayed to the IPKernelApp constructor,
allowing configuration of the Kernel. Will only have an effect
on the first embed_kernel call for a given process.
"""
# get the app if it exists, or set it up if it doesn't
if SpyderKernelApp.initialized():
app = SpyderKernelApp.instance()
else:
app = SpyderKernelApp.instance(**kwargs)
app.initialize([])
# Undo unnecessary sys module mangling from init_sys_modules.
# This would not be necessary if we could prevent it
# in the first place by using a different InteractiveShell
# subclass, as in the regular embed case.
main = app.kernel.shell._orig_sys_modules_main_mod
if main is not None:
sys.modules[app.kernel.shell._orig_sys_modules_main_name] = main
# load the calling scope if not given
(caller_module, caller_locals) = extract_module_locals(1)
if module is None:
module = caller_module
if local_ns is None:
local_ns = caller_locals
app.kernel.user_module = module
app.kernel.user_ns = local_ns
app.shell.set_completer_frame()
app.start()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment