关于python:获取整个Jupyter Notebook的当前内容

Get the current contents of the entire Jupyter Notebook

我有一个Jupyter笔记本正在运行。我希望能够从Python中访问当前Jupyter Notebook的源代码。我的最终目标是将其传递给ast.parse,以便我可以对用户的代码进行一些分析。理想情况下,我可以做这样的事情:

1
2
import ast
ast.parse(get_notebooks_code())

显然,如果源代码是IPYNB文件,则需要从Python单元中提取代码的中间步骤,但这是一个相对容易解决的问题。

到目前为止,我发现代码将使用IPython对象的list_running_servers函数来发出请求并匹配内核ID - 这给了我当前运行的笔记本的文件名。这可以工作,除了磁盘上的源代码可能与用户在浏览器中的内容不匹配(直到您保存新的检查点)。

我已经看到了一些涉及使用JavaScript提取数据的想法,但这需要一个带魔术的单独单元格或调用display.Javascript函数 - 它异步触发,因此不允许我将结果传递给ast.parse

任何人都有任何聪明的想法,如何动态获取当前笔记本源代码可用作Python中的字符串,以便立即处理?如果我需要将它作为扩展甚至内核包装器,我完全没问题,我只需要以某种方式获取源代码。


嗯,这不是我想要的,但这是我目前的策略。 我需要根据用户的代码运行一些Python代码,但实际上并不需要直接连接到用户的代码。 所以我之后将会运行以下魔术:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
%%javascript
// Get source code from cells
var source_code = Jupyter.notebook.get_cells().map(function(cell) {
    if (cell.cell_type =="code") {
        var source = cell.code_mirror.getValue();
        if (!source.startsWith("%%javascript")) {
            return source;
        }
    }
}).join("
"
);
// Embed the code as a Python string literal.
source_code = JSON.stringify(source_code);
var instructor_code ="student_code="+source_code;
instructor_code +="
import ast
print(ast.dump(ast.parse(student_code)))
print('Great')"

// Run the Python code along with additional code I wanted.
var kernel = IPython.notebook.kernel;
var t = kernel.execute(instructor_code, { 'iopub' : {'output' : function(x) {
    if (x.msg_type =="error") {
        console.error(x.content);
        element.text(x.content.ename+":"+x.content.evalue+"
"
+x.content.traceback.join("
"
))
    } else {
        element.html(x.content.text.replace(/
/g,""));
        console.log(x);
    }
}}});