protected JupyterRequestHandlerTestBase(ITestOutputHelper output) { _frontendEnvironment = new JupyterFrontendEnvironment(); _disposables.Add(output.SubscribeToPocketLogger()); _cSharpKernel = new CSharpKernel() .UseDefaultFormatting() .UseKernelHelpers() .UseJupyterHelpers() .UseMathAndLaTeX(); _fSharpKernel = new FSharpKernel() .UseDefaultFormatting() .UseKernelHelpers() .UseDefaultNamespaces() .UseMathAndLaTeX(); _compositeKernel = new CompositeKernel { _cSharpKernel, _fSharpKernel } .UseDefaultMagicCommands(); _compositeKernel.UseFrontedEnvironment(context => _frontendEnvironment); SetKernelLanguage(Language.CSharp); _compositeKernel.Name = ".NET"; Kernel = _compositeKernel; JupyterMessageSender = new RecordingJupyterMessageSender(); _disposables.Add(_compositeKernel); _disposables.Add(Kernel.LogEventsToPocketLogger()); }
public static Parser Create( IServiceCollection services, StartServer startServer = null, Jupyter jupyter = null, StartKernelServer startKernelServer = null, ITelemetry telemetry = null, IFirstTimeUseNoticeSentinel firstTimeUseNoticeSentinel = null) { if (services == null) { throw new ArgumentNullException(nameof(services)); } startServer ??= (startupOptions, invocationContext) => Program.ConstructWebHost(startupOptions).Run(); jupyter ??= JupyterCommand.Do; startKernelServer ??= async(startupOptions, kernel, console) => { var disposable = Program.StartToolLogging(startupOptions); if (kernel is KernelBase kernelBase) { kernelBase.RegisterForDisposal(disposable); } var server = new StandardIOKernelServer( kernel, Console.In, Console.Out); await server.Input.LastAsync(); }; // Setup first time use notice sentinel. firstTimeUseNoticeSentinel ??= new FirstTimeUseNoticeSentinel(VersionSensor.Version().AssemblyInformationalVersion); // Setup telemetry. telemetry ??= new Telemetry.Telemetry( VersionSensor.Version().AssemblyInformationalVersion, firstTimeUseNoticeSentinel); var filter = new TelemetryFilter(Sha256Hasher.HashWithNormalizedCasing); var verboseOption = new Option <bool>( "--verbose", "Enable verbose logging to the console"); var httpPortOption = new Option <int>( "--http-port", "Specifies the port on which to enable HTTP services"); var logPathOption = new Option <DirectoryInfo>( "--log-path", "Enable file logging to the specified directory"); var defaultKernelOption = new Option <string>( "--default-kernel", description: "The default language for the kernel", getDefaultValue: () => "csharp"); var rootCommand = DotnetInteractive(); rootCommand.AddCommand(Jupyter()); rootCommand.AddCommand(KernelServer()); rootCommand.AddCommand(HttpServer()); return(new CommandLineBuilder(rootCommand) .UseDefaults() .UseMiddleware(async(context, next) => { if (context.ParseResult.Errors.Count == 0) { telemetry.SendFiltered(filter, context.ParseResult); } // If sentinel does not exist, print the welcome message showing the telemetry notification. if (!firstTimeUseNoticeSentinel.Exists() && !Telemetry.Telemetry.SkipFirstTimeExperience) { context.Console.Out.WriteLine(); context.Console.Out.WriteLine(Telemetry.Telemetry.WelcomeMessage); firstTimeUseNoticeSentinel.CreateIfNotExists(); } await next(context); }) .Build()); RootCommand DotnetInteractive() { var command = new RootCommand { Name = "dotnet-interactive", Description = "Interactive programming for .NET." }; command.AddOption(logPathOption); command.AddOption(verboseOption); command.AddOption(httpPortOption); return(command); } Command Jupyter() { var jupyterCommand = new Command("jupyter", "Starts dotnet-interactive as a Jupyter kernel") { defaultKernelOption, logPathOption, verboseOption, new Argument <FileInfo> { Name = "connection-file" }.ExistingOnly() }; jupyterCommand.Handler = CommandHandler.Create <StartupOptions, JupyterOptions, IConsole, InvocationContext>(JupyterHandler); var installCommand = new Command("install", "Install the .NET kernel for Jupyter") { logPathOption, verboseOption }; installCommand.Handler = CommandHandler.Create <IConsole, InvocationContext>(InstallHandler); jupyterCommand.AddCommand(installCommand); return(jupyterCommand); Task <int> JupyterHandler(StartupOptions startupOptions, JupyterOptions options, IConsole console, InvocationContext context) { var frontendEnvironment = new JupyterFrontendEnvironment(); services.AddSingleton(c => ConnectionInformation.Load(options.ConnectionFile)) .AddSingleton(_ => frontendEnvironment) .AddSingleton <FrontendEnvironmentBase>(_ => frontendEnvironment) .AddSingleton(c => { return(CommandScheduler.Create <JupyterRequestContext>(delivery => c.GetRequiredService <ICommandHandler <JupyterRequestContext> >() .Trace() .Handle(delivery))); }) .AddSingleton(c => CreateKernel(options.DefaultKernel, c.GetRequiredService <FrontendEnvironmentBase>(), startupOptions)) .AddSingleton(c => new JupyterRequestContextHandler( c.GetRequiredService <IKernel>(), c.GetRequiredService <JupyterFrontendEnvironment>()) .Trace()) .AddSingleton <IHostedService, Shell>() .AddSingleton <IHostedService, Heartbeat>() ; return(jupyter(startupOptions, console, startServer, context)); } Task <int> InstallHandler(IConsole console, InvocationContext context) => new JupyterInstallCommand(console, new JupyterKernelSpec()).InvokeAsync(); } Command HttpServer() { var startKernelHttpCommand = new Command("http", "Starts dotnet-interactive with kernel functionality exposed over http") { defaultKernelOption, logPathOption, }; startKernelHttpCommand.Handler = CommandHandler.Create <StartupOptions, KernelHttpOptions, IConsole, InvocationContext>( (startupOptions, options, console, context) => { var frontendEnvironment = new JupyterFrontendEnvironment(); services .AddSingleton(c => CreateKernel(options.DefaultKernel, frontendEnvironment, startupOptions)); return(jupyter(startupOptions, console, startServer, context)); }); return(startKernelHttpCommand); } Command KernelServer() { var startKernelServerCommand = new Command( "stdio", "Starts dotnet-interactive with kernel functionality exposed over standard I/O") { defaultKernelOption, logPathOption, }; startKernelServerCommand.Handler = CommandHandler.Create <StartupOptions, KernelServerOptions, IConsole, InvocationContext>( (startupOptions, options, console, context) => startKernelServer( startupOptions, CreateKernel(options.DefaultKernel, new JupyterFrontendEnvironment(), startupOptions), console)); return(startKernelServerCommand); } }