代码之家  ›  专栏  ›  技术社区  ›  Austin Cory Bart

获取整个Jupyter笔记本的当前内容

  •  2
  • Austin Cory Bart  · 技术社区  · 6 年前

    我有一个笔记本。我希望能够从python中访问当前jupyter笔记本的源代码。我的最终目标是 ast.parse 所以我可以对用户的代码做一些分析。理想情况下,我可以这样做:

    import ast
    ast.parse(get_notebooks_code())
    

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

    到目前为止,我已经找到了使用 list_running_servers ipython对象的函数,以便发出请求并匹配内核ID—这给了我当前运行的笔记本的文件名。这是可行的,除了磁盘上的源代码可能与用户在浏览器中的源代码不匹配(除非保存新的检查点)。

    我见过一些使用javascript提取数据的想法,但这需要使用magic的单独单元格或调用display.javascript函数-该函数异步触发,因此不允许将结果传递给 ast.parse解析 是的。

    对于如何在python中以字符串形式动态获取当前笔记本电脑的源代码以供即时处理,有没有人有什么聪明的想法?我很好,如果我需要使它成为一个扩展甚至是一个内核包装器,我只需要以某种方式获取源代码。

    1 回复  |  直到 6 年前
        1
  •  1
  •   Austin Cory Bart    6 年前

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

    %%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("\n");
    // Embed the code as a Python string literal.
    source_code = JSON.stringify(source_code);
    var instructor_code = "student_code="+source_code;
    instructor_code += "\nimport ast\nprint(ast.dump(ast.parse(student_code)))\nprint('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+"\n"+x.content.traceback.join("\n"))
        } else {
            element.html(x.content.text.replace(/\n/g, "<br>"));
            console.log(x);
        }
    }}});