Categories
Jupyter lab

Setup VSCode to debug your Jupyter notebook server extension

Setting up VSCode to allow debugging a jupyter notebook extension in Python.

If you’re using pycharm, debugging seems to be as easy as starting a jupyter server locally and attaching the debugger to the process. While it is possible to attach the debugger to a process in VSCode, I would always get a timeout error:

"Timed out waiting for debug server to connect." 

One solution I’ve found is to use python on wheels and let it run the debug server locally. I didn’t try it but didn’t like this approach as I find it too invasive (too many files to add to the extension).

I’ve worked around this problem by configuring vscode and adding a short python script to start a local server.

Note: In this article I’m using Jupyter Lab 2.x and VSCode 1.52

Setting up VSCode

I’m developing some extensions for jupyterlab and so I use anaconda on a windows machine provided by my client. If you do work with conda too, make sure it is setup properly with powershell (open powershell and type conda init powershell). You will need the vscode python extension installed too.

Then we need to create a launch.json file: In the Run panel in VSCode press the link ‘create a launch.json file’, in the popup select Python, Module and enter your package name.

The VScode run panel when no launch.json file exists for the project

You should end up with a launch.json file in the .vscode folder, similar to this, with your module name:

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python: Module",
            "type": "python",
            "request": "launch",
            "module": "your_extension"
        }
    ]
}

Setting up the debug script

VSCode will load the package ‘as an application’ using the package __main__.py file, we need to boostrap a jupyter server and load the handlers in it.
At the root level of your package, create the __main__.py file (so if your package is called your_extension it should be your_extension/__main.py) containing:

import tornado
from notebook.notebookapp import NotebookApp

# Update this import to reflect your package name
from your_extension import load_jupyter_server_extension

# Starts a local server, used to attach a debugger
if __name__ == "__main__":
    notebookapp = NotebookApp()
    # Initialise config file and setup the app
    notebookapp.initialize()
    
    # Load the handlers
    load_jupyter_server_extension(notebookapp)

    # Start tornado server
    notebookapp.web_app.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

Update the import on line 4 so it loads the function load_jupyter_server_extension from your package.

And voilà, you’re good to go!

How to use

Put a breakpoint in one of your handlers then in the VSCode run pannel click on the arrow at the top to start the debugger.

When the server starts if you need the UI you will have to open it manually in your browser. Send a request to the endpoint and VSCode will stop automatically at the breakpoint.

No more print to debug your extension!

Leave a Reply

Your email address will not be published. Required fields are marked *

*

code