Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge main to release/jupyter #2504

Merged
merged 15 commits into from
Nov 23, 2022
Merged
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<NewtonsoftJsonVersion>13.0.1 </NewtonsoftJsonVersion>
<MicrosoftCodeAnalysisCommonVersion>4.4.0</MicrosoftCodeAnalysisCommonVersion>
<SystemReactiveVersion>5.0.0</SystemReactiveVersion>
<SystemSecurityCryptographyXmlVersion>6.0.1</SystemSecurityCryptographyXmlVersion>
<SystemSecurityCryptographyXmlVersion>7.0.0</SystemSecurityCryptographyXmlVersion>
<xunitVersion>2.4.2</xunitVersion>
<xunitrunnervisualstudioVersion>2.4.5</xunitrunnervisualstudioVersion>
</PropertyGroup>
Expand Down
1 change: 1 addition & 0 deletions eng/SignCheckExclusionsFile.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ Microsoft.Management.Infrastructure.dll;Microsoft.dotnet-interactive.*.nupkg;
Microsoft.PowerShell.Host.psd1;Microsoft.dotnet-interactive.*.nupkg;
Microsoft.PowerShell.Management.psd1;Microsoft.dotnet-interactive.*.nupkg;
Microsoft.PowerShell.Security.psd1;Microsoft.dotnet-interactive.*.nupkg;
Security.types.ps1xml;Microsoft.dotnet-interactive.*.nupkg;
Microsoft.PowerShell.Utility.psd1;Microsoft.dotnet-interactive.*.nupkg;
dotnet-interactive.js
1 change: 1 addition & 0 deletions eng/Signing.props
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@

<!-- Microsoft.PowerShell.Security -->
<FileSignInfo Include="Microsoft.PowerShell.Security.psd1" CertificateName="None" />
<FileSignInfo Include="Security.types.ps1xml" CertificateName="None" />

<!-- Microsoft.PowerShell.Utility -->
<FileSignInfo Include="Microsoft.PowerShell.Utility.psd1" CertificateName="None" />
Expand Down
2 changes: 1 addition & 1 deletion eng/perf-tests/perf-tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.13.1" />
<PackageReference Include="BenchmarkDotNet" Version="0.13.2" />
<PackageReference Include="Newtonsoft.Json" Version="$(NewtonsoftJsonVersion)" />
</ItemGroup>

Expand Down
310 changes: 310 additions & 0 deletions samples/stand-alone-kernels/perl/kernel.pl
Original file line number Diff line number Diff line change
@@ -0,0 +1,310 @@
# Copyright (c) .NET Foundation and contributors. All rights reserved.
# Licensed under the MIT license. See LICENSE file in the project root for full license information.

# This is designed to be a stand-alone, out-of-process kernel, primarily used to ensure proper proxy
# handling. It requires a local `perl.exe` interpreter be available and can be used by executing
# the following in a notebook:
#
# #!connect stdio --kernel-name perl --command perl.exe kernel.pl

use JSON;
use Try::Tiny;

$|++; # autoflush

# run with `perl.exe kernel.pl test` to ensure the value serialization works as expected
if (length(@ARGV) > 0 && $ARGV[0] eq "test") {
test();
} else {
main(@ARGV);
}

sub test {
$scalarNumber = 4;
$scalarString = "four";
@array = (1, 2, 3);
$arrayRef = [4, 5, 6];
%hash = ("theAnswer" => 42, "pi" => 3.14159);
$hashRef = {"theAnswer" => 42, "pi" => 3.14159};

@names = ("scalarNumber", "scalarString", "array", "arrayRef", "hash", "hashRef");
@mimeTypes = ("text/plain", "application/json");
foreach my $mimeType (@mimeTypes) {
print "$mimeType:\n";
foreach my $name (@names) {
print " $name: " . getStringRepresentationOfValueName($name, $mimeType) . "\n";
}
}
}

sub main {
my $kernelHost = "pid-$$";

# the line "#!connect stdio ..." auto-appends these arguments
for (my $i = 0; $i < $#_; $i++) {
my $arg = $_[$i];
if ($arg eq "--kernel-host") {
$i++;
$kernelHost = $_[$i];
}
}

my $kernelUri = "kernel://$kernelHost/";

%suppressedValues = {};
foreach my $valueName ( keys %main:: ) {
if (!$suppressedValues{$valueName}) {
$suppressedValues{$valueName} = 1;
}
}

$kernelInfo = {
"localName" => "perl",
"languageName" => "perl",
"languageVersion" => "$^V",
"displayName" => "Perl $^V",
"uri" => $kernelUri,
"supportedKernelCommands" => [
{ "name" => "RequestKernelInfo" },
{ "name" => "RequestValue" },
{ "name" => "RequestValueInfos" },
{ "name" => "SendValue" },
{ "name" => "SubmitCode" },
{ "name" => "Quit" }
],
"supportedDirectives" => []
};

publish({
"eventType" => "KernelReady",
"event" => {},
"command" => undef,
"routingSlip" => [
$kernelUri
]
});

publish({
"eventType" => "KernelInfoProduced",
"event" => {
"kernelInfo" => $kernelInfo,
},
"command" => undef,
"routingSlip" => [
$kernelUri
]
});

while (<STDIN>) {
chomp;
try {
$envelope = decode_json($_);
$envelopeRoutingSlip = $envelope->{"routingSlip"};
push(@$envelopeRoutingSlip, $kernelUri . "?tag=arrived");
$commandType = $envelope->{'commandType'};
if ($commandType) {
$token = $envelope->{'token'};
$command = $envelope->{'command'};
$succeeded = false;
if ($commandType eq "Quit") {
#
# Quit
#
return;
} elsif ($commandType eq "RequestKernelInfo") {
#
# RequestKernelInfo
#
publish({
"eventType" => "KernelInfoProduced",
"event" => {
"kernelInfo" => $kernelInfo
},
"command" => $envelope,
"routingSlip" => [
$kernelUri
]
});
$succeeded = true;
} elsif ($commandType eq "RequestValue") {
#
# RequestValue
#
$valueName = $command->{'name'};
$mimeType = $command->{'mimeType'};
$formattedValue = getStringRepresentationOfValueName($valueName, $mimeType);
publish({
"eventType" => "ValueProduced",
"event" => {
"name" => $valueName,
"formattedValue" => {
"mimeType" => $mimeType,
"value" => $formattedValue
}
},
"command" => $envelope,
"routingSlip" => [
$kernelUri
]
});
$succeeded = true;
} elsif ($commandType eq "RequestValueInfos") {
#
# RequestValueInfos
#
my @valueInfos = ();
foreach my $valueName ( keys %main:: ) {
if (!$suppressedValues{$valueName}) {
push(@valueInfos, { "name" => "$valueName" });
}
}
publish({
"eventType" => "ValueInfosProduced",
"event" => {
"valueInfos" => \@valueInfos
},
"command" => $envelope,
"routingSlip" => [
$kernelUri
]
});
$succeeded = true;
} elsif ($commandType eq "SendValue") {
#
# SendValue
#
$formattedValue = $command->{'formattedValue'};
# if `application/json` or `text/json`
if ($formattedValue->{'mimeType'} =~ m/\/json$/) {
$valueName = $command->{'name'};
$jsonValue = $formattedValue->{'value'};
$runtimeValue = decode_json($jsonValue);
$main::{$valueName} = $runtimeValue;
$succeeded = true;
}
} elsif ($commandType eq "SubmitCode") {
#
# SubmitCode
#
$code = $command->{'code'};
$result = eval $code;
publish({
"eventType" => "ReturnValueProduced",
"event" => {
"formattedValues" => [{
"mimeType" => "text/plain",
"value" => "$result"
}],
},
"command" => $envelope,
"routingSlip" => [
$kernelUri
]
});
$succeeded = true;
} else {
$succeeded = false;
}

push(@$envelopeRoutingSlip, $kernelUri);
if ($succeeded) {
publish({
"eventType" => "CommandSucceeded",
"event" => {},
"command" => $envelope,
"routingSlip" => [
$kernelUri
]
});
} else {
publish({
"eventType" => "CommandFailed",
"event" => {
"message" => "Unknown command type: $commandType"
},
"command" => $envelope,
"routingSlip" => [
$kernelUri
]
});
}
}
$eventType = $envelope->{'eventType'};
if ($eventType) {
# TODO: respond to events
}
} catch {
print STDERR "error: $_\n";
}
}
}

sub publish {
print encode_json(\%{$_[0]}) . "\n";
}

sub getStringRepresentationOfValueName {
my $valueName = shift;
my $mimeType = shift;
my $rawValue = $main::{$valueName};
my $formattedValue;
# if `application/json` or `text/json`
if ($mimeType =~ m/\/json$/) {
my @asArray = @{getArray($rawValue)};
my %asHash = %{getHash($rawValue)};
if (@asArray) {
$rawValue = \@asArray;
}
elsif (%asHash) {
$rawValue = \%asHash;
}
elsif ( length do { no warnings "numeric"; $$rawValue & '' }) {
$rawValue = $$rawValue + 0;
}
else {
$rawValue = $$rawValue;
}

$formattedValue = encode_json($rawValue);
}
else {
# assume text/plain
my @asArray = @{getArray($rawValue)};
my %asHash = %{getHash($rawValue)};
if (@asArray) {
$formattedValue = "(" . join(", ", @asArray) . ")";
}
elsif (%asHash) {
$formattedValue = "(" . join(", ", map { "$_ => $asHash{$_}" } keys %asHash) . ")";
}
else {
$formattedValue = "" . $$rawValue;
}
}

return $formattedValue;
}

sub getArray {
my $rawValue = shift;
if (ref($$rawValue) eq "ARRAY") {
return \@$$rawValue;
}
elsif (@$rawValue) {
return \@$rawValue;
}

return undef;
}

sub getHash {
my $rawValue = shift;
if (ref($$rawValue) eq "HASH") {
return \%$$rawValue;
}
elsif (%$rawValue) {
return \%$rawValue;
}

return undef;
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,9 @@ Microsoft.DotNet.Interactive.Documents
public System.Collections.Generic.List<InteractiveDocumentOutputElement> Outputs { get;}
public abstract class InteractiveDocumentOutputElement
public class KernelInfo
.ctor(System.String name, System.Collections.Generic.IReadOnlyCollection<System.String> aliases = null)
.ctor(System.String name, System.String languageName = null, System.Collections.Generic.IReadOnlyCollection<System.String> aliases = null)
public System.Collections.Generic.IReadOnlyCollection<System.String> Aliases { get;}
public System.String LanguageName { get;}
public System.String Name { get;}
public System.String ToString()
public class KernelInfoCollection, System.Collections.Generic.ICollection<KernelInfo>, System.Collections.Generic.IEnumerable<KernelInfo>, System.Collections.IEnumerable
Expand Down Expand Up @@ -77,7 +78,8 @@ Microsoft.DotNet.Interactive.Documents
public System.String Text { get;}
Microsoft.DotNet.Interactive.Documents.Jupyter
public class InputCellMetadata
.ctor(System.String language = null)
.ctor(System.String kernelName = null, System.String language = null)
public System.String KernelName { get;}
public System.String Language { get;}
public static class InteractiveDocumentExtensions
public static Microsoft.DotNet.Interactive.Documents.InteractiveDocument WithJupyterMetadata(System.String language = C#)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,10 +231,12 @@ Microsoft.DotNet.Interactive
public System.Threading.Tasks.Task<Microsoft.DotNet.Interactive.Connection.ProxyKernel> ConnectProxyKernelOnDefaultConnectorAsync(System.String localName, System.Uri remoteKernelUri, System.String[] aliases = null)
public System.Void Dispose()
public class KernelInfo
.ctor(System.String localName, System.String languageName = null, System.String languageVersion = null, System.String[] aliases = null)
.ctor(System.String localName, System.String[] aliases = null)
.ctor(System.String localName, System.String languageName, System.String languageVersion, System.String[] aliases)
public System.String[] Aliases { get; set;}
public System.String LanguageName { get;}
public System.String LanguageVersion { get;}
public System.String DisplayName { get; set;}
public System.String LanguageName { get; set;}
public System.String LanguageVersion { get; set;}
public System.String LocalName { get;}
public System.Uri RemoteUri { get; set;}
public System.Collections.Generic.ICollection<KernelDirectiveInfo> SupportedDirectives { get; set;}
Expand Down Expand Up @@ -429,9 +431,9 @@ Microsoft.DotNet.Interactive.Commands
public class RequestValueInfos : KernelCommand
.ctor(System.String targetKernelName = null)
public class SendEditableCode : KernelCommand
.ctor(System.String language, System.String code, System.String targetKernelName = vscode)
.ctor(System.String kernelName, System.String code, System.String targetKernelName = vscode)
public System.String Code { get;}
public System.String Language { get;}
public System.String KernelName { get;}
public class SendValue : KernelCommand
.ctor(System.String name, System.Object value, Microsoft.DotNet.Interactive.FormattedValue formattedValue = null, System.String targetKernelName = null)
public Microsoft.DotNet.Interactive.FormattedValue FormattedValue { get;}
Expand Down
Loading