dotnet / interactive

.NET Interactive combines the power of .NET with many other languages to create notebooks, REPLs, and embedded coding experiences. Share code, explore data, write, and learn across your apps in ways you couldn't before.
MIT License
2.91k stars 389 forks source link

Add support for Go, using GoNB kernel #3511

Open janpfeifer opened 7 months ago

janpfeifer commented 7 months ago

Is your feature request related to a problem? Please describe.

I maintain GoNB, I think the only currently supported Go kernel for Jupyter notebooks, and there has been requests for better support for VSCode+Polyglot -- without auto-complete, notebooks are not as useful.

Notice GoNB does support Jupyter's Completion protocol, but VSCode won't use it.

I'm not sure what is required for dotnet/interactive to add support for another language, but Go provides a great Language Server (LSP), see gopls.

Describe the solution you'd like Go language to be included in the set of languages supported.

Describe alternatives you've considered Maybe Polyglot to talk Jupyter's Completion protocol ? I'm not sure if this is feasible. This way it would be "future compatible" with new languages or custom kernels ...

jonsequitur commented 6 months ago

Since GoNB already supports the Jupyter Message Protocol, you should be able to follow the same process that enables Python and R to work within a Polyglot Notebook.

https://github.com/dotnet/interactive/blob/main/docs/adding-jupyter-kernels.md

janpfeifer commented 6 months ago

Thanks for the pointer @jonsequitur !

I'll have to investigate further ... my first read at the document I don't know what is referred by a #!connect jupyter command (and I wonder why it seems to be hardcoding conda) among other things. I haven't used the Polyglot yet, so I'm probably missing something obvious.

But GoNB does implement the comms protocol, so hopefully it should work somehow.

tonidy commented 2 months ago

@janpfeifer I've tried to connect gonb subkernel but after 1 minute got nothing

image

@jonsequitur how to check the error log when connect to subkernel?

jonsequitur commented 2 months ago

It can be useful to configure logging (even if you're not using a local build of the tool), as shown here:

https://github.com/dotnet/interactive/blob/main/DEVELOPER-GUIDE.md#use-a-local-build-of-the-dotnet-interactive-tool

So just add the --verbose --log-path _____ options to the kernelTransportArgs.

tonidy commented 2 months ago

@jonsequitur thanks for the tip, after configured the logging I can see this error:

2024-09-13T17:09:53.3889700Z [00-a1b958cb466a2e7e8ffc1e3887df7429-82cd24b1681a95af-00] [CommandLine] [StartProcess]  ℹ (0.097ms) > /Users/me/go/bin/gonb --kernel "/Users/me/Library/Application Support/jupyter/runtime/kernel-a167ee7c-e732-4d7a-9ae1-8df75e41c217.json" --logtostderr 
2024-09-13T17:09:53.4229460Z [00-a1b958cb466a2e7e8ffc1e3887df7429-82cd24b1681a95af-00] [CommandLine] [StartProcess]  ⏹ (34.074ms)  
2024-09-13T17:09:54.3512990Z [00-a1b958cb466a2e7e8ffc1e3887df7429-82cd24b1681a95af-00] [gonb]  ❌ I0914 00:09:53.426524   82645 main.go:124] [1d8c3c33] kernel created 
2024-09-13T17:09:54.3517440Z [00-a1b958cb466a2e7e8ffc1e3887df7429-82cd24b1681a95af-00] [gonb]  ❌ I0914 00:09:53.457395   82645 exec.go:29] [1d8c3c33] gopls.Client.Start() 
2024-09-13T17:09:54.3518250Z [00-a1b958cb466a2e7e8ffc1e3887df7429-82cd24b1681a95af-00] [gonb]  ❌ I0914 00:09:53.457570   82645 exec.go:54] [1d8c3c33] Executing "/Users/me/go/bin/gopls -listen unix;/var/folders/fs/mjcxy3_s7ls84f603q6gl9fw0000gn/T/gonb_1d8c3c33/gopls_socket" 
2024-09-13T17:09:54.3518630Z [00-a1b958cb466a2e7e8ffc1e3887df7429-82cd24b1681a95af-00] [gonb]  ❌ W0914 00:09:53.458504   82645 goexec.go:192] [1d8c3c33] Could not find Jupyter root directory, %wasm will not work: cannot figure out Jupyter root directory, because environment variable "JPY_PARENT_PID" is not set!? 
2024-09-13T17:09:54.3518990Z [00-a1b958cb466a2e7e8ffc1e3887df7429-82cd24b1681a95af-00] [gonb]  ❌ I0914 00:09:53.458539   82645 goexec.go:201] [1d8c3c33] GoNB: jupyter root in "", tmp Go code in "/var/folders/fs/mjcxy3_s7ls84f603q6gl9fw0000gn/T/gonb_1d8c3c33" 
2024-09-13T17:10:27.8512090Z [00-a1b958cb466a2e7e8ffc1e3887df7429-3e23f2285a36e43b-00] [KernelInvocationContext] [KernelInvocationContext]  ▶  +[ ⁞Ϲ⁞ RequestHoverText #!connect jupyter --kernel-name golang --kernel-sp ... (0, 28) (Token: EfHH0XrGRg62btS/2UrWXw==, TargetKernelName: pythonkernel, DestinationUri: ) ] 
2024-09-13T17:10:28.2171100Z [00-a1b958cb466a2e7e8ffc1e3887df7429-9549059862caf864-00] [KernelInvocationContext] [KernelInvocationContext]  ▶  +[ ⁞Ϲ⁞ Cancel  (Token: 8oh5bgZBTJCPaBvI+f6/WA==, TargetKernelName: , DestinationUri: ) ] 
2

here output log from the .NET interactive tools is the same as the gonb log

I0914 18:54:59.211126   16703 main.go:124] [4e28df4e] kernel created
I0914 18:54:59.240391   16703 exec.go:29] [4e28df4e] gopls.Client.Start()
I0914 18:54:59.240496   16703 exec.go:54] [4e28df4e] Executing "/Users/me/go/bin/gopls -listen unix;/var/folders/fs/mjcxy3_s7ls84f603q6gl9fw0000gn/T/gonb_4e28df4e/gopls_socket"
W0914 18:54:59.242251   16703 goexec.go:192] [4e28df4e] Could not find Jupyter root directory, %wasm will not work: cannot figure out Jupyter root directory, because environment variable "JPY_PARENT_PID" is not set!?
W0914 18:54:59.242251   16703 goexec.go:192] [4e28df4e] Could not find Jupyter root directory, %wasm will not work: cannot figure out Jupyter root directory, because environment variable "JPY_PARENT_PID" is not set!?
I0914 18:54:59.242283   16703 goexec.go:201] [4e28df4e] GoNB: jupyter root in "", tmp Go code in "/var/folders/fs/mjcxy3_s7ls84f603q6gl9fw0000gn/T/gonb_4e28df4e"

I’m not familiar with the Jupyter protocol details. Perhaps @janpfeifer could take care of this issue.

janpfeifer commented 2 months ago

hi @tonidy sorry for the delayed response -- I'm in the middle of a trip in September, and my internet has been spotty.

I haven't used Gonb with VSCode in a very long time (I've been using mostly GoLand the last years), so I'm not sure what is going on.

But it seems it has recognized the Gonb kernel, since it executed it. The lack of JPY_PARENT_PID, per error message, should not be fatal, most things (except the experimental %wasm that has this requirement) should just work in principle. So there are no error messages there that I would be concerned about.

I don't recall how to select a different kernel in VSCode. Is that the what the #!connect command do ? Is there another way to select a kernel, or to show which kernels are installed in VSCode ?

What happens if after that you would execute a cell with:

%%
fmt.Println("hello")

?

When I'm back at home -- probably in a couple of weeks -- I'll try VSCode again. Apologies I'm not able to do it now.

Maybe @jonsequitur can help ?

jonsequitur commented 2 months ago

I don't recall how to select a different kernel in VSCode. Is that the what the #!connect command do ? Is there another way to select a kernel, or to show which kernels are installed in VSCode ?

@janpfeifer Polyglot Notebooks uses the .NET Interactive kernel, which has intrinsic support for multiple kernels (including kernels that are not Jupyter kernels.) It's somewhat different from the VS Code Jupyter support.

The #!connect magic command is extensible and allows for different kernels to be added at runtime and mixed within a single notebook. #!connect jupyter allows adding ordinary Jupyter kernels, and was my suggestion for adding support for Go via the GoNB kernel.

jonsequitur commented 2 months ago

@shibbas Any ideas here?

tonidy commented 2 months ago

@janpfeifer thanks for your answer.

What happens if after that you would execute a cell with:


%%
fmt.Println("hello")

I am unable to execute that code because we first need to switch the subkernel (in this case, the gonb kernel). You can refer to my gist for instructions on setting up Deno in .NET Interactive here

@jonsequitur I have a few questions:

  1. How can I debug the #! connect magic command?
  2. Is it necessary to use VSCode Insiders for debugging? I just went through this documentation Manual Testing, and it might be a good starting point for debugging.
  3. I also tested it with another Jupyter kernel (I believe it was the Clang kernel), and like with gonb, it hangs as well.

If I could debug it, I might be able to identify the issue. At this point, I'm out of ideas on how to debug .NET Interactive.

janpfeifer commented 2 months ago

hi @tonidy , apologies, just now I'm back from my trip, and only now had a chance to try it out.

Selecting the GoNB kernel manually (as sub-option under "Jupyter Kernel...") worked out of the box:

image

After that, I selected back ".NET Interactive" kernel, and then created the cell with the #!connect... line, and got the following:

image

After that it was looping forever, and I had to stop the execution. But manually reverting back to Go worked again.

But that seems to be an issue with Polyglot -- I know very little about it ...

Or am I misunderstanding the issue ?