Importing Code in Polyglot Notebooks

Importing Code in Polyglot Notebooks

Using NuGet and Local Files to Import Code into Notebooks

We’ve seen that Polyglot Notebooks allow you to mix together markdown and code (including C# code) in an interactive notebook and these notebooks allow you to share data between cells and between languages. However, frequently in programming you want to reference code that others have written without having to redefine everything yourself.

In this article we’ll explore how Polyglot Notebooks allows you to import dotnet code from stand-alone files, DLLs, and NuGet packages so your notebooks can take advantage of external code files and the same libraries that you can work with from your code in Visual Studio.

Importing Local Code Files

First of all, if you have a small amount of code that lives in an individual C# file and you wanted to reference it in your notebook, you can do this via the #!import magic command as shown below:

#!import Person.cs

This assumes that there is a file named Person.cs in the current directory, but assuming it is present the code in that file will be imported as if you had declared it in your notebook.

This can be helpful for hiding code like test data or class definitions that isn’t the main focus of your notebook.

If your code file has issues, those issues will typically be displayed immediately below the cell as pictured below:

Import Error

However, I have noticed at least one instance where an import silently failed and I could not immediately find a good answer as to why. If this happens to you, I recommend you check VS Code’s Output pane and look at the Polyglot Notebook : diagnostics data source for additional information.

Polyglot Diagnostics

NuGet Packages

Often in dotnet code you’ll want to refer to packages that others have created to complete common tasks. This could be anything from working with JSON, APIs, machine learning, to generating random data.

The standard dotnet package manager is NuGet Package Manager which many readers will be familiar with from development in Visual Studio.

It turns out that Polyglot Notebooks support importing NuGet packages via the #r magic command followed by the word nuget: and then the name of the package you wish to import.

For example, the following block of code imports the Microsoft.ML and Microsoft.ML.AutoML NuGet packages related to ML.NET into the Notebook:

#r "nuget:Microsoft.ML"
#r "nuget:Microsoft.ML.AutoML"

When this cell runs you should see the following output:

Importing NuGet Packages

After the NuGet packages are installed you’ll be able to access public classes and namespaces contained in that package, for example:

using Microsoft.ML;
using Microsoft.ML.AutoML;
using Microsoft.ML.Data;

MLContext Context = new();

One additional thing I want to point out with installing NuGet packages is that some packages may contain extensions for Polyglot Notebooks. If that is the case, you will see those extensions detected and installed into your notebook automatically during their installation process.

Finally, you should note that only NuGet packages compatible with your version of the .NET SDK are ones you can install. Typically this will be something written targeting .NET Standard or .NET 6 or 7. See my article on installing Polyglot Notebooks for more information on .NET versions.

Pre-Release Packages

Sometimes you’ll want to refer to packages that are currently in pre-release. To work with these particular files, you’ll use slightly different syntax for importing them:

#r "nuget: Microsoft.DotNet.Interactive.SqlServer, *-*"

Here we import the Microsoft.DotNet.Interactive.SqlServer package which does not have a non-preview version available at the time of this writing.

If you do not include the , *-* syntax, NuGet will automatically exclude pre-release packages. This is usually a good thing unless you are trying to work with a NuGet package that is not yet released. In the case where a NuGet package is in pre-release, you need to use the , *-* syntax to refer to it successfully.

Custom NuGet Feeds

Sometimes you work with an organization or team that uses its own private NuGet feed. You can tell Polyglot Notebooks about these custom NuGet feeds via the #i syntax as shown below:

#i "nuget:"

Now when you run NuGet install commands Polyglot Notebook will also search your custom NuGet feed.

Note: the above website is fictitious and should not be used. Replace this instead with your custom NuGet feed’s actual URL.

Most users won’t need to care about this feature, but this is very handy if you have a special shared NuGet feed that you and your team use.

Importing Local DLLs

If you want to work with a local .dll file with dotnet code, you can import that using the following code:

#r "..\DLLs\Bogus.dll"

This is very similar to referencing a NuGet package, but doesn’t require the nuget: prefix and uses a path to the actual .dll file instead of relying on NuGet to find the dependency.

Realistically, you likely won’t work with this too much. I’ve used this feature to test local projects before publishing them to NuGet and to demonstrate things at conferences where I knew I wouldn’t have reliable internet access to install remote dependencies.

Additionally, I’ve noticed that while referencing NuGet packages extensions are installed automatically, this does not seem to happen when installing .dll files directly.

Still, being able to work with local .dll files can be handy in certain circumstances.

Closing Thoughts

While some of these magic commands to import dependencies can be slightly hard to recall exactly, these commands allow you to quickly and easily work with code outside of your notebooks.

This allows you to focus your notebooks on larger tasks by referencing utilities and libraries from other packages.

Later on this week I’ll illustrate how helpful this can be for working with things like ML .NET for Machine Learning and Azure Cognitive Services inside of Polyglot Notebooks.

Finally, never underestimate the value of importing a simple code file in simplifying your notebooks by pulling non-critical code out of the notebook and into a separate file.

I love Polyglot Notebooks and being able to work with other code from our notebooks just makes them even more awesome.