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
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.
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.
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
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!”
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.
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.
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.
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 ?
Product | Good points | Dislikes |
Jupyter | Most 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 + | Very 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.