JupyterLab执行JS获取Notebook URL报unexpected token错误
JupyterLab获取当前Notebook访问URL报错修复方案
错误原因
执行JS代码抛出Javascript Error: unexpected token: identifier的核心原因有三点:
- 代码中Python拼接JS字符串时没有添加语句分隔符,多段JS字符串直接拼接后变成无分隔的连写内容,例如
var kernel = IPython.notebook.kernelvar host = window.location.href,JS引擎无法识别连在一起的变量名,直接抛出语法错误。 - 原经典Jupyter Notebook的全局
IPython.notebookAPI在JupyterLab环境中做了调整,即使修复语法问题,原代码也会因为找不到对应对象无法运行。 - 原测试代码存在逻辑错误:拼接的
host是Python作用域变量,并非JS环境下的window.location.href,本身逻辑就无法取到前端地址。
经典Jupyter Notebook可用实现
在经典Notebook中通过%%javascript魔法命令注入前端JS可以正常获取地址,代码如下:
%%javascript var kernel = IPython.notebook.kernel var host = window.location.href kernel.execute("notebook_url='"+host+"'")
执行完成后查询Python变量notebook_url即可拿到结果,示例返回值:'http://localhost:8889/notebooks/LTIBootCamp.ipynb',执行效果参考:
JupyterLab环境可行方案
推荐两种稳定可用的实现方式:
方案1:修正后的JS注入实现
修复语法问题、适配JupyterLab前端API,代码如下:
from IPython.display import display, Javascript js_code = """ // JS语句间用分号分隔,直接在JS作用域取当前页面地址 const pageUrl = window.location.href; // 调用内核API将值写入Python变量 Jupyter.notebook.kernel.execute(`notebook_url = "${pageUrl}"`); """ display(Javascript(js_code))
执行完成后直接读取notebook_url变量即可拿到当前Notebook的完整访问地址。
方案2:纯Python实现(无前端依赖,兼容性最好)
不依赖前端JS注入,直接通过Jupyter服务端接口匹配当前内核对应的Notebook路径,不受前端环境变化影响:
from notebook import notebookapp import urllib.request import json import os import ipykernel def get_current_notebook_url(): # 提取当前运行内核的ID conn_file = os.path.basename(ipykernel.get_connection_file()) kernel_id = conn_file.split('-', 1)[1].split('.')[0] # 遍历所有运行中的Jupyter服务,匹配当前内核对应的Notebook for server in notebookapp.list_running_servers(): token = server.get('token', '') api_url = f"{server['url']}api/sessions?token={token}" try: with urllib.request.urlopen(api_url) as resp: sessions = json.load(resp) for sess in sessions: if sess['kernel']['id'] == kernel_id: # 拼接完整访问URL return f"{server['url'].rstrip('/')}/notebooks/{sess['notebook']['path']}" except Exception: continue return None # 直接调用即可获取URL notebook_url = get_current_notebook_url()
内容的提问来源于stack exchange,提问作者Ranji Raj
相关产品推荐
相关产品推荐

