ipykernel

repository·main·Indexed 20 days ago

https://github.com/ipython/ipykernel

The IPython kernel for Jupyter, enabling users to run IPython code within Jupyter notebooks and other Jupyter-compatible interfaces. It provides utilities for managing kernel connections, embedding kernels into running processes, GUI integration, and a debugger interface bridging the Debug Adapter Protocol (DAP) with debugpy.

Tokens
18.2K
Snippets
60
Records
92
Agent score
73%

What's inside ipykernel

  1. Access IPython Kernel documentation

    main
    The ipykernel package contains minimal, version-sensitive documentation within this repository. For comprehensive, up-to-date documentation regarding the IPython ecosystem, refer to the main IPython documentation site.
  2. Run tests with coverage reporting

    main

    To run the test suite with detailed coverage information, use pytest with the following flags. This command provides verbose output, disables stdout capturing, calculates branch coverage, and reports missing coverage in the terminal.

    pytest -vv -s --cov ipykernel --cov-branch --cov-report term-missing:skip-covered --durations 10
  3. Install ipykernel from source

    main

    To install ipykernel from source for development, clone the repository, navigate to the ipykernel directory, and install it in editable mode using pip. Including the [test] extra ensures that testing dependencies are also installed. Once installed, standard ipython commands will utilize this local version of the kernel.

    git clone <repository_url>
    cd ipykernel
    pip install -e ".[test]"
  4. Override Kernel message handlers

    main

    The Kernel class uses a dispatch mechanism for different message types. It maintains two dictionaries of handlers:

    • shell_handlers: Handles messages on the shell channel (e.g., execute_request, inspect_request).
    • control_handlers: Handles messages on the control channel (e.g., interrupt_request, shutdown_request).

    While the base class provides default implementations for the request methods (which call the do_* methods), you can customize the dispatch logic by overriding the msg_types or control_msg_types lists or by providing your own handler methods.

  5. Implement a custom kernel by subclassing Kernel

    main

    The Kernel class is the base class for all kernel implementations that communicate with frontends over ZeroMQ (0MQ). To create a new language kernel, you must subclass Kernel and override several core methods that handle the Jupyter protocol messages.

    Key methods to override:

    • do_execute(...): The core logic for executing user code. It must be an async def or return an awaitable.
    • do_complete(...): Logic for code completion/intellisense.
    • do_inspect(...): Logic for object introspection.
    • do_history(...): Logic for accessing execution history.

    Note: For consistency, it is highly recommended that these methods are coroutine functions (async def).

    from ipykernel.kernelbase import Kernel
    
    class MyCustomKernel(Kernel):
        implementation = 'my_lang'
        implementation_version = '1.0.0'
        banner = 'My Custom Language Kernel'
        language_info = {'name': 'mylang', 'version': '1.0'}
    
        async def do_execute(self, code, silent, store_history=True, user_expressions=None, allow_stdin=False, *, cell_meta=None, cell_id=None):
            # Your execution logic here
            return {'status': 'ok', 'execution_count': 1, 'payload': []}
    
        async def do_complete(self, code, cursor_pos):
            # Your completion logic here
            return {'matches': [], 'cursor_end': cursor_pos, 'cursor_start': cursor_pos, 'metadata': {}, 'status': 'ok'}
    
        # ... override other do_* methods as needed
  6. Extend Kernel functionality by overriding lifecycle methods

    main

    When implementing a custom kernel by subclassing the base kernel class, you can override several key methods to define how the kernel responds to frontend requests.

    Key methods to override include:

    • do_shutdown(restart): Called when the frontend requests a shutdown. Returns a dictionary, typically {"status": "ok", "restart": restart}.
    • do_is_complete(code): Used to provide code completion logic. Returns a dictionary, e.g., {"status": "unknown"}.
    • do_debug_request(msg): Handles debug requests. This method must be implemented in subclasses.
    • _at_shutdown(): An internal hook for cleanup actions taken during shutdown.
  7. Configure CurveZMQ for transport encryption

    main

    To enable transport encryption for the kernel communication, provide CurveZMQ keys. If curve_secretkey is provided, the application will apply CurveZMQ server-side options to the sockets (shell, stdin, control, iopub) before binding them.

    If the transport is set to tcp but no Curve keys are provided, the kernel will log a warning that communication is being sent in plain text.

  8. How CommManager works in ipykernel

    main

    The CommManager handles Jupyter Comm messages (comm_open, comm_msg, comm_close). In an ipykernel process, there can only be one CommManager instance.

    To ensure a singleton pattern within a process, use _get_comm_manager(). This function uses a threading lock to safely initialize the global _comm_manager if it does not exist. The IPythonKernel automatically attaches this manager to its shell's configurables and maps the Comm message types to the manager's handlers.

    from ipykernel.comm.manager import CommManager
    # Internal mechanism used by the kernel to ensure singleton behavior
    manager = _get_comm_manager()
  9. How to use the VariableExplorer

    main

    The VariableExplorer class allows for inspecting variables within the kernel's current state. It uses a SuspendedFramesManager to track and retrieve variable data from suspended frames.

    To use it:

    1. Call track() to start tracking the current IPython user namespace.
    2. Use get_children_variables(variable_ref=None) to retrieve the list of child variables for a given reference. If no reference is provided, it defaults to the current frame.
    3. Call untrack_all() to stop tracking and clean up.

    Note: inspectVariables in the Debugger class internally re-instantiates the explorer to ensure a clean state.

    class VariableExplorer:
        """A variable explorer."""
    
        def track(self):
            """Start tracking."""
            ...
    
        def untrack_all(self):
            """Stop tracking."""
            ...
    
        def get_children_variables(self, variable_ref=None):
            """Get the child variables for a variable reference."""
            ...
  10. How IPKernelApp manages connection files

    main

    The IPKernelApp manages a connection file (typically a JSON file) that contains the IP, ports, and security keys (like CurveZMQ) required for a client to connect to the kernel.

    • Default Directory: The connection files are stored in the directory returned by jupyter_runtime_dir().
    • Custom Connection File: You can specify a custom filename via the connection_file configuration. The application will attempt to find it in the current directory or the connection_dir.
    • Cleanup: The application automatically registers a cleanup task to delete the connection file when the process exits gracefully.
  11. Customize the Kernel class in IPKernelApp

    main

    You can use the kernel_class configuration option to specify a different subclass of ipykernel.kernelbase.Kernel to be used by the application. This allows the IPKernelApp entry point to be reused for launching kernels other than the default IPython kernel.

    This is a configuration-level setting (using traitlets).