***Please note this post is outdated. The .NET Interactive Notebooks Extension is now named Polyglot Notebooks. See here to learn more: https://devblogs.microsoft.com/dotnet/dotnet-interactive-notebooks-is-now-polyglot-notebooks/ ***
In .NET Interactive Preview 2, we announced that in addition to Jupyter Notebook and Jupyter Lab, users could use nteract as well. In this preview, users can add VS Code Insiders to that list. With the VS Code Insiders experience, users can get started with .NET notebooks without needing to install Jupyter. The VS Code experience is still a work in progress, and is only available in VS Code Insiders. We look forward to your feedback.
Getting started
To get started with .NET notebooks, please install the following:
- The latest version of VS Code Insiders.
- The latest .NET Core 3.1 SDK.
- The .NET Interactive Notebooks extension.
Creating a new .NET notebook
Once you have the requirements listed above installed, you are ready to start creating .NET Notebooks in VS Code Insiders.
To create a new notebook, open the Command Palette(Ctrl+Shift+P
), and select Create new blank notebook. You can also create a new notebook with Ctrl+Shift+Alt+N
key combination.
Every notebook has a default language. A new blank notebook starts with a C# cell, as noted in the lower right corner of the cell. If you click on C# (.NET Interactive), you can change the language of the cell. If you change the language of the cell, the next cell you create will continue with that language.
To add a cell, hover above or below an existing cell. Buttons appear allowing you to specify the type of cell to add, +Code or +Markdown. If you select +Code, you can change the language afterward.
Opening an existing .NET notebook
To open an existing .NET notebook, bring up the Command Palette and select Open notebook. Now, navigate to a local .ipynb
file.
With .NET notebooks in VS Code, you can take advantage of rich coding experiences like IntelliSense, and you can use all of your favorite VS Code extensions.
Polyglot Notebooks: Variable Sharing
.NET Interactive is a multi-language kernel that allows you to create notebooks that use different languages together. You switch languages from one cell to another, as appropriate to the task at hand. Pulling values into the notebook and moving values between languages are useful capabilities, which we’ve enabled with a pair of magic commands: #!share
and #!value
.
#!share
.NET Interactive provides subkernels for three languages (C#, F#, and PowerShell) within the same process. You can share variables between the .NET subkernels using the #!share
magic command. Once a variable has been declared in one of these subkernels, it can be accessed from another. And because these kernels run in the same process, if the type of a variable is a reference type, changes to its state can be observed immediately from other kernels.
Example: In this GIF, I’ve declared a C# variable csharpVariable
in one cell, which I then share with F# using #!share --from csharp csharpVariable
.
#!value
Importing text into a notebook, whether from the clipboard or a JSON or CSV file or a URL, is a fairly common scenario. The #!value
magic command makes it easier to get text into your notebook without having to explicitly declare a string variable and worry about correctly escaping it. When you execute a cell using #!value
, the content is stored in memory. (It will also be stored in your .ipynb
output, and displayed, if you use the --mime-type
switch.) So how do you access the value once it’s stored? The #!value
magic command actually refers to another subkernel. In the GIF above, you can see it in the IntelliSense list that’s shown when #!share
is typed. Once a value has been stored using #!value
, you can share it with another subkernel just like you can from C#, F#, or PowerShell.
There are a few ways to use #!value
to store data in a notebook session. The example below shows you how to do it from the clipboard. For examples of other ways to use it, including reading from files and URLs, please check out Direct data entry with #!value
.
Sharing kernel values with JavaScript
.NET Interactives has APIs available that simplify the process of directly writing HTML and JavaScript in the same notebook where you write .NET code. This enables you to create custom visualizations and access the broader ecosystem of JavaScript libraries without needing .NET wrappers.
In the example below, we are sharing code from the .NET kernel using JavaScript and using it to render HTML, all in a single notebook.
First, I build a collection of items in C# representing fruits
with prices and quantities.
Next, since .NET Interactive is polyglot, I can switch to JavaScript. (While the VS Code experience has a language chooser, you can also switch languages using magic commands like #!javascript
, so that you can use these features in Jupyter as well). In the JavaScript cell, I load the D3.js visualization library and when it’s loaded, I access the fruits
variable from the C# kernel using interactive.csharp.getVariable("fruits")
. This interactive
object has properties corresponding to each of the .NET Interactive subkernels. The variable from the subkernel is serialized into JSON and then deserialized into a JavaScript object (basket
) that I’ll use to render my bar chart with D3.js.
Final step: Let’s render the results. We are now going to use HTML to render our chart and JavaScript to call our function. The HTML has to be rendered first because that’s where the JavaScript will build the visualization. But we don’t have to put them in separate cells. Using magic commands, we can switch languages within the same cell so that the output renders at the bottom of the notebook.
#!html
<svg id = "fruit_display" width = "100%"></svg>
#!js
renderfruits("svg#fruit_display");
And there you have it! A simple demonstration on how you can leverage .NET Interactive polyglot notebooks.
To learn more about variable sharing, sub-kernels, and HTML and JavaScript in .NET Interactive, please check out the linked documentation.
Documentation
We are also happy to share some progress on .NET Interactive documentation. You can now learn more about .NET Interactive’s architecture, variable sharing, visualization, and other features.
The documentation is still a work progress, so we look forward to hearing from you.
Resources
Happy interactive programming!
Great! A fun way to try out or demo some c#.
Preview features – like C# 9.0 pattern matching – how can they be turned on?
Are there any plans to mix Python and .NET within one notebook?
It’s something we’re definitely interested in.
So, if my set of nuget package sources includes one that requires authentication, how can I configure the that's run by the notebook to either ignore failed sources, or provide an interactive authentication prompt?
Right now I'm facing this error and I've no idea how to configure the notebook's package restore.
warning : The plugin credential provider could not acquire credentials. Authentication may require manual action. Consider re-running the command with --interactive for dotnet, /p:NuGetInteractive="true" for...
Right now, the way to solve this is to put a personal access token in your user-level NuGet.config file. We’re planning to support a more focused solution: https://github.com/dotnet/interactive/issues/702.
Very cool functionality! Unfortunately, when I created a notebook with markdown, PowerShell, C#, JavaScript, and HTML cells, while it worked, I’m unable to save it. I get the error message “Failed to save ‘Untitled-1.ipynb’: Cannot read property ‘startsWith’ of undefined”.
I installed the requirements, but when I try to create a new notebook (ctrl+shift+alt+n), I get a message (Activating extensions) And nothing happens
If you’re still seeing a problem, please open an issue: https://github.com/dotnet/interactive/issues. We’re updating the extension frequently and the VS Code team is updating the preview notebook APIs as well, so while things tend to be pretty stable, if there’s a bug we’re not aware we generally can fix it pretty quickly.