Notebooks: part 2, beyond Jupyter with VS Code

In part one I talked about Jupyter and ipynb files – they were called “Interactive Python” before the Jupyter name was coined- and I said the Python extension for Visual Studio Code can work with them, but it’s not great at handling other languages like those found in dotnet interactive notebooks – which I wanted for PowerShell support.

While I was looking at code, I saw that there is a preview of notebook support in the PowerShell Extension. It requires VS Code insiders and the preview edition of the PowerShell extension. With those in place you need to turn on the PowerShell > Notebooks: Show Toggle Button option in VS Code’s settings

Screen shot of settings in VSCode for PowerShell notebook functionality (preview) showing options, "Save Markdown Cells As" and "Show Toggle Button"

The preview PowerShell extension leverages a proposed Notebook API for VS Code (hence it is only in the Insiders version) and embeds markdown as comments in standard PS1 files - the second option in settings determines whether to insert it as block comments wrapped in <# … #> or line comments. The extension turns a .PS1 file into notebook cells by reading into a code cell until it hits a comment; the comment goes into a markdown cell; at the end of the comment the next code cell begins, and the process repeats until the end of the file.

Screen Shot showing a PS1 file with comments containing markdown to use with the preview Notebook functionality.

A file like the one above has two simple markdown cells – one of them is plain text, the other a heading2 style, alternating with two PowerShell commands. And toggling into notebook view (with the button that’s circled in the screen shot) produces the results below.

Screen shot showing PowerShell extension preview in VSCode. It has PowerShell and Markdown cells but the script runs in the VSCode terminal and doesn't put output back into the notebook.

There are shortcomings, most of which are answered saying “It’s a preview”. Execution and results are in the PowerShell-integrated-Console (no new environment required) but the results don’t come back to the document. It’s useful for scripts which alternate detailed explanation with their work or for training cases where the reader will run the code for themselves. Where this preview will go is hard to say, because almost in competition with it is a VS Code extension for .NET Interactive.

The .NET Interactive Notebooks extension is also in preview and has the same need for the insiders version of VS Code. It shows a lot of potential – to the point where I found myself thinking of it as a finished product. The extension manages and updates its own instance of .NET Interactive - separate from the one used for Jupyter (set-up is just the .NET SDK, VS Code and the Extension) whenever .NET Interactive is updated the extension updates itself and its copy of .NET interactive. The “daily build” nature of it means thing do break and get fixed – in a couple of weeks that’s only caused me a problem once, and only for one day. It gave me a newer, but still not absolutely up-to-the-minute version of PowerShell (7.0.2 instead of 7.0.3) than the command line installation I’d used for Jupyter in part one
(I went back and updated that with the command
dotnet tool –global update "Microsoft.dotnet-interactive" ).
EDIT 2nd October 2020 I now have the build 1.0.150105 which includes PowerShell 7.0.3

The extension originally had its own file format for notebooks, but it can now import and save .ipnyb files as well, formats may evolve further during the preview. To avoid conflict with the Python extension the Open command is on the tool palette not the file menu

ipynb files are opened from the VSCode command palette

NET interactive supports “magic commands” to switch between its languages, which allows a single notebook or even a single cell to contain PowerShell, C#, and/or F#. To allow other ipynb tools to read such “polyglot” files, it adds a magic command at the start of each code block, so Jupyter sees a C# notebook where each block says ‘run this bit in PowerShell’: but only the VS Code extension understands that intelisense for the current cell might need to different from the file setting (usually C#).

Between the version I first installed for Jupyter and the one used by VS Code, a mechanism was added to allow one language to ask for a variable set in another, so, for example PowerShell can copy a variable from F#, or pooled variables can be set for all the languages.

With the PowerShell extension disabled and without an F# extension installed VS Code could still parse and tab complete PowerShell and F# - suggesting language support is in the .NET Interactive extension. It feels like normal PowerShell editing, although support for snippets is missing and PowerShell cells don’t follow all the PowerShell extension options that I set. Everything I had tried in Jupyter imported into VS Code, including plotly, as you can see in the screen-shot below. VS-Code’s embedded output didn’t always read with perfect fidelity in Jupyter, another place to say, “But it’s a preview!”

The .NET Interactive extension in action with a Markdown cell, a PowerShell code cell showing rich editing and its result, showing plotly in action.

I mentioned in part 1 that having a shell in a notebook is a good way to capture and document command lines, and a shell in .NET interactive can run commands from the dotnet cli as in the screen shot below, and I’m using it to put together notes on those git commands that I only use occasionally.

Dotnet cli in a .NET Interactive notebook in VS code

The screen shot above shows Jupyter and the VS Code extension sometimes render the same output differently – it has become double-spaced above, and the next two screen shots show the difference in how a table is rendered. I also found that that Jupyter renders markdown with a language block better than VS Code does.

HTML Table rendering in VS Code

HTML Table rendering in Jupyter

It looks like HTML Style sheets making the difference, so again, this may change. There are other differences – Jupyter has an easy way to expand or collapse output. In VS Code it’s buried in a menu, but there are also options to hide the code. If your markdown uses title styles, VS code can use it for outlining and fold up code and markdown up to the next title. Jupyter doesn’t have folding but does have “run all cells” and “clear all output”, which VS Code doesn’t at the moment. Again, it’s a preview and any of this might change.

The final notebook tool for this round up is Azure data studio. Database admins like it, but it was a new product to me – and the first thing I noticed was the striking similarity to Visual studio code.

Azure data studio - looks similar to VS Code and the about box lists shared components

The VS Code About box listing very similar components to Azure Data studio As well as a near identical layout, it references VS Code in the help information and has a very similar set of components to the release VS Code.

I think of Data Studio as an app built from VS Code parts to know about connecting to SQL Servers, submitting queries and doing useful things with the results (extending what SQL Management Studio can do, and taking it cross-platform) -which grew into putting SQL, results and annotations into notebooks and got more “notebooky” by connecting to Jupyter server (so it needs Python installed). Whether or not that’s historically accurate, it is good way to understand what it does.

Anaconda -which I used in part 1 - doesn’t install the R language Kernel out of the box, but Azure Data Studio knows about it and will do the necessary Python / Jupyter setup to make it work. It also has a Windows PowerShell 5 Kernel and again sets that up for Jupyter on first use. One slightly odd behaviour is that Data Studio doesn’t get the names of additional Kernels from the Jupyter server until a notebook is opened, but then -unlike the Jupyter web interface – you can change a notebook’s language to any that server has- it will turn ipynb files saved by VS Code from presenting as C# files with embedded PowerShell blocks to fully PowerShell files. Unfortunately, some stuff – like plotly - just didn’t render.

If I were spending a lot of time working on SQL server, I’d find Azure data studio more compelling.

What did I like in the different tools ?

ProductGood pointsDislikes
JupyterMost mature product.
All languages supported.
Built-in translation and printing support.
Some things just render better.
The Python / web server architecture.
Editing is the least sophisticated
(but still a reasonable experience).
VS-Code + .NET InteractiveVery good editing experience.
Multiple languages per file.
Simple set-up.
Folding at markdown titles.
Other tools see .Ipynb files as C#,
and don’t always read output parts correctly.
VS-Code +
PowerShell
Best PowerShell editing experience.
Native PS1 files can be used directly.
Doesn’t save results.
Single language.
Azure
Data Studio
Adds Windows PowerShell to Jupyter.
(for modules which can’t run in PowerShell core)
Works with all Jupyter Kernels.
Database orientation.
Some output failures. (e.g. Plotly)
Has Jupyter as a pre-requisite.

Not keeping the results in the file killed the pure-PowerShell one for me – although I can see cases where a .PS1 file with embedded markdown would be a great solution. None of the others really lands a knockout punch. Someone spending a lot of their day working with SQL Server will have a use for Azure Data Studio even without Jupyter support, and that might give the final push to adopt it, that doesn’t apply to me. I do use VS Code and using the insiders build, for now, doesn’t cause me too many problems; so that’s the solution I lean towards. It’s not finished, and for sharing I would want to modify the file’s metadata to ensure it is seen as PowerShell and re-generate the output in Jupyter. Some things are better in one and other things are better in the other: I’m happy working in Jupyter and slightly happier working in VS code.


<<Previous post       Next Post>>