You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JupyterLab实现.ipynb链接点击触发文档分栏打开

Fixing Comm Communication Between Jupyter Notebook and Custom Plugin

Key Issues in Current Implementation

  • Mismatched Comm Channels: Python creates an independent Comm object instead of using the one established when the plugin initiates the connection.
  • Unreliable Kernel Retrieval: Plugin code uses a non-deterministic way to get the kernel, which may fail if multiple sessions exist.
  • Missing Widget Import: Original Python code lacks the import for Button from ipywidgets, causing runtime errors.

Corrected Implementation

1. Python Notebook Code

Store the comm instance received from the plugin's connection, then use it to send messages on button click:

from ipykernel.comm import Comm
from IPython import get_ipython
from ipywidgets import Button

# Global variable to hold the active comm connection
active_comm = None

def comm_target(comm, open_msg):
    global active_comm
    active_comm = comm
    print("Comm connection established with plugin")
    
    @comm.on_msg
    def _recv(msg):
        print("Message from plugin:", msg)

# Register the comm target
get_ipython().kernel.comm_manager.register_target('schedule_reference_link', comm_target)

# Button click handler
def on_schedule_reference_clicked(b):
    print('Button clicked')
    if active_comm is not None:
        active_comm.send(data={'event': 'schedule_ref_event', 'data': 'https://example.com'})
    else:
        print("No active comm connection to plugin")

# Create and display the button
schedule_reference = Button(description="Schedule Reference")
schedule_reference.on_click(on_schedule_reference_clicked)
schedule_reference

2. JupyterLab Plugin Code

Properly retrieve the kernel, handle session activation, and listen for Comm messages:

import { JupyterFrontEnd, JupyterFrontEndPlugin } from '@jupyterlab/application';
import { ISessionContext, SessionManager } from '@jupyterlab/apputils';

const plugin: JupyterFrontEndPlugin<void> = {
  id: 'schedule-reference-plugin:plugin',
  autoStart: true,
  requires: [SessionManager],
  activate: (app: JupyterFrontEnd, sessionManager: SessionManager) => {
    let comm: any = null;

    // Setup comm connection when a session is active
    const setupComm = (sessionContext: ISessionContext) => {
      if (!sessionContext.session?.kernel) return;

      const kernel = sessionContext.session.kernel;
      // Create comm connection to the Python target
      kernel.createComm('schedule_reference_link').then((newComm) => {
        comm = newComm;
        console.log("Comm connection established with kernel");

        comm.onMsg = (msg: { content: { data: any; }; }) => {
          const eventData = msg.content.data;
          if (eventData.event === 'schedule_ref_event') {
            console.log('Event received:', eventData.data);
            // Trigger split-panel opening logic
            openInSplitPanel(eventData.data);
          }
        };

        // Handle comm closure
        comm.onClose = () => {
          console.log("Comm connection closed");
          comm = null;
        };
      }).catch(err => {
        console.error("Failed to create comm connection:", err);
      });
    };

    // Listen for active session changes
    app.serviceManager.sessions.currentChanged.connect((_, session) => {
      if (session) {
        setupComm(session);
      } else {
        comm?.close();
        comm = null;
      }
    });

    // Initialize comm if a session is already active
    app.serviceManager.sessions.currentSession && setupComm(app.serviceManager.sessions.currentSession);

    // Open document in split panel
    const openInSplitPanel = (url: string) => {
      const widget = app.commands.execute('docmanager:open', { path: url }) as any;
      if (widget) {
        const mainArea = app.shell.mainArea;
        mainArea.splitRight(widget);
      }
    };
  }
};

export default plugin;

Explanation of Fixes

  • Shared Comm Channel: Python now uses the comm instance established by the plugin, ensuring messages are sent through the same channel the plugin listens to.
  • Reliable Session Handling: Plugin listens for active session changes and initializes the comm only when a valid kernel exists, avoiding non-deterministic kernel retrieval.
  • Proper Comm Lifecycle: Handles comm closure and reconnection when sessions change.
  • Split Panel Logic: Added openInSplitPanel to implement the required split-view document opening feature.

Additional Notes

  • Ensure your plugin is properly packaged and installed via jupyter labextension install.
  • Test by running the notebook code first, then confirming the plugin is active before clicking the button.
  • Use browser dev tools (F12) for plugin logs and Jupyter server logs for Python-side debugging.

内容的提问来源于stack exchange,提问作者Sathiyanarayanan Marimuthu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 05:05:01