code: 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 IPKernelApp.initialized():
          app = IPKernelApp.instance()
      else:
          app = IPKernelApp.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()
  
imports: import sys
  from IPython.utils.frame import extract_module_locals
  from .kernelapp import IPKernelApp
label_desc: Use image node_id 1 for calling a global function with example usage: embed_kernel(module, local_ns) without return types