Skip to content

Commit 34cc09c

Browse files
committed
updates for Microsoft.DotNet.Interactive.Documents API stabilization
1 parent 82cadfa commit 34cc09c

File tree

12 files changed

+56
-77
lines changed

12 files changed

+56
-77
lines changed

src/Microsoft.DotNet.Interactive.ApiCompatibility.Tests/ApiCompatibilityTests.Document_api_is_not_changed.approved.txt

+3-10
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ Microsoft.DotNet.Interactive.Documents
3131
public System.Collections.Generic.IAsyncEnumerable<InteractiveDocument> GetImportsAsync(System.Boolean recursive = False)
3232
public System.Collections.Generic.IEnumerable<InputField> GetInputFields()
3333
public System.Collections.Generic.IEnumerable<System.String> GetMagicCommandLines()
34+
public System.Boolean TryGetKernelInfosFromMetadata(ref KernelInfoCollection& kernelInfos)
3435
public class InteractiveDocumentElement
3536
.ctor()
3637
.ctor(System.String contents = null, System.String kernelName = null, System.Collections.Generic.IEnumerable<InteractiveDocumentOutputElement> outputs = null)
@@ -60,30 +61,22 @@ Microsoft.DotNet.Interactive.Documents
6061
public System.Boolean Contains(System.String nameOrAlias)
6162
public System.Void CopyTo(KernelInfo[] array, System.Int32 arrayIndex)
6263
public System.Boolean Remove(KernelInfo item)
63-
public System.Boolean TryGetByAlias(System.String alias, ref KernelInfo& info)
6464
public class ReturnValueElement : InteractiveDocumentOutputElement, IDataElement
65-
.ctor(System.Collections.Generic.IDictionary<System.String,System.Object> data)
65+
.ctor()
6666
public System.Collections.Generic.IDictionary<System.String,System.Object> Data { get;}
6767
public System.Int32 ExecutionOrder { get; set;}
6868
public System.Collections.Generic.IDictionary<System.String,System.Object> Metadata { get;}
6969
public class TextElement : InteractiveDocumentOutputElement
70-
.ctor(System.String text, System.String name)
70+
.ctor(System.String text, System.String name = stdout)
7171
public System.String Name { get;}
7272
public System.String Text { get;}
7373
Microsoft.DotNet.Interactive.Documents.Jupyter
7474
public class InputCellMetadata
7575
.ctor(System.String kernelName = null, System.String language = null)
7676
public System.String KernelName { get;}
7777
public System.String Language { get;}
78-
public static class InteractiveDocumentExtensions
79-
public static Microsoft.DotNet.Interactive.Documents.InteractiveDocument WithJupyterMetadata(System.String language = C#)
8078
public static class Notebook
81-
public static System.Text.Encoding Encoding { get;}
82-
public static System.Text.Json.JsonSerializerOptions JsonSerializerOptions { get;}
8379
public static Microsoft.DotNet.Interactive.Documents.InteractiveDocument Parse(System.String json, Microsoft.DotNet.Interactive.Documents.KernelInfoCollection kernelInfos = null)
8480
public static Microsoft.DotNet.Interactive.Documents.InteractiveDocument Read(System.IO.Stream stream, Microsoft.DotNet.Interactive.Documents.KernelInfoCollection kernelInfos)
8581
public static System.String ToJupyterJson(System.String defaultLanguage = null)
86-
public static System.Void Write(Microsoft.DotNet.Interactive.Documents.InteractiveDocument document, System.IO.Stream stream)
8782
public static System.Void Write(Microsoft.DotNet.Interactive.Documents.InteractiveDocument document, System.IO.Stream stream, Microsoft.DotNet.Interactive.Documents.KernelInfoCollection kernelInfos)
88-
public static System.Void Write(Microsoft.DotNet.Interactive.Documents.InteractiveDocument document, System.IO.TextWriter writer)
89-
public static System.Void Write(Microsoft.DotNet.Interactive.Documents.InteractiveDocument document, System.IO.TextWriter writer, Microsoft.DotNet.Interactive.Documents.KernelInfoCollection kernelInfos)

src/Microsoft.DotNet.Interactive.Documents.Tests/JupyterFormatTests.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ public void notebook_metadata_default_language_is_honored_in_cells_without_langu
8888
[InlineData("PowerShell", "powershell")]
8989
public void Metadata_default_kernel_name_is_based_on_specified_language(string languageName, string kernelName)
9090
{
91-
var document = new InteractiveDocument().WithJupyterMetadata(languageName);
91+
var document = Notebook.Parse(new InteractiveDocument().ToJupyterJson(languageName));
9292

9393
document.GetDefaultKernelName()
9494
.Should()
@@ -102,7 +102,7 @@ public void Metadata_default_kernel_name_is_based_on_specified_language(string l
102102
[InlineData("PowerShell", "powershell")]
103103
public void Metadata_default_kernel_name_is_based_on_specified_language_when_serialized_and_deserialized(string languageName, string kernelName)
104104
{
105-
var originalDoc = new InteractiveDocument().WithJupyterMetadata(languageName);
105+
var originalDoc = Notebook.Parse(new InteractiveDocument().ToJupyterJson(languageName));
106106

107107
var parsedDoc = Notebook.Parse(originalDoc.ToJupyterJson());
108108

src/Microsoft.DotNet.Interactive.Documents/CodeSubmission.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ public static InteractiveDocument Parse(
5353

5454
metadata = JsonSerializer.Deserialize<Dictionary<string, object>>(metadataString, InteractiveDocument.JsonSerializerOptions);
5555

56-
if (InteractiveDocument.TryGetKernelInfoFromMetadata(metadata, out var kernelInfoFromMetadata))
56+
if (InteractiveDocument.TryGetKernelInfosFromMetadata(metadata, out var kernelInfoFromMetadata))
5757
{
5858
InteractiveDocument.MergeKernelInfos(kernelInfos, kernelInfoFromMetadata);
5959
document.Metadata["kernelInfo"] = kernelInfoFromMetadata;

src/Microsoft.DotNet.Interactive.Documents/InteractiveDocument.cs

+19-20
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public async IAsyncEnumerable<InteractiveDocument> GetImportsAsync(bool recursiv
6565
{
6666
EnsureImportFieldParserIsInitialized();
6767

68-
if (!TryGetKernelInfoFromMetadata(Metadata, out var kernelInfos))
68+
if (!TryGetKernelInfosFromMetadata(out var kernelInfos))
6969
{
7070
kernelInfos = new();
7171
}
@@ -198,7 +198,7 @@ public static async Task<InteractiveDocument> LoadAsync(
198198

199199
public string? GetDefaultKernelName()
200200
{
201-
if (TryGetKernelInfoFromMetadata(Metadata, out var kernelInfo))
201+
if (TryGetKernelInfosFromMetadata(Metadata, out var kernelInfo))
202202
{
203203
return kernelInfo.DefaultKernelName;
204204
}
@@ -208,16 +208,11 @@ public static async Task<InteractiveDocument> LoadAsync(
208208

209209
internal string? GetDefaultKernelName(KernelInfoCollection kernelInfos)
210210
{
211-
if (TryGetKernelInfoFromMetadata(Metadata, out var kernelInfoCollection))
211+
if (TryGetKernelInfosFromMetadata(Metadata, out var kernelInfoCollection))
212212
{
213213
return kernelInfoCollection.DefaultKernelName;
214214
}
215215

216-
if (Metadata is null)
217-
{
218-
return null;
219-
}
220-
221216
if (Metadata.TryGetValue("kernelspec", out var kernelspecObj))
222217
{
223218
if (kernelspecObj is IDictionary<string, object> kernelspecDict)
@@ -243,7 +238,7 @@ public static async Task<InteractiveDocument> LoadAsync(
243238

244239
internal static void MergeKernelInfos(InteractiveDocument document, KernelInfoCollection kernelInfos)
245240
{
246-
if (TryGetKernelInfoFromMetadata(document.Metadata, out var kernelInfoCollection))
241+
if (TryGetKernelInfosFromMetadata(document.Metadata, out var kernelInfoCollection))
247242
{
248243
MergeKernelInfos(kernelInfoCollection, kernelInfos);
249244
}
@@ -264,19 +259,23 @@ internal static void MergeKernelInfos(KernelInfoCollection destination, KernelIn
264259
destination.AddRange(source.Where(ki => added.Add(ki.Name)));
265260
}
266261

267-
internal static bool TryGetKernelInfoFromMetadata(
262+
public bool TryGetKernelInfosFromMetadata(
263+
[NotNullWhen(true)] out KernelInfoCollection? kernelInfos) =>
264+
TryGetKernelInfosFromMetadata(Metadata, out kernelInfos);
265+
266+
internal static bool TryGetKernelInfosFromMetadata(
268267
IDictionary<string, object>? metadata,
269-
[NotNullWhen(true)] out KernelInfoCollection? kernelInfo)
268+
[NotNullWhen(true)] out KernelInfoCollection? kernelInfos)
270269
{
271270
if (metadata is not null)
272271
{
273272
if (metadata.TryGetValue("kernelInfo", out var kernelInfoObj))
274273
{
275274
if (kernelInfoObj is JsonElement kernelInfoJson &&
276-
JsonSerializer.Deserialize<KernelInfoCollection>(kernelInfoJson, JsonSerializerOptions) is
275+
kernelInfoJson.Deserialize<KernelInfoCollection>(JsonSerializerOptions) is
277276
{ } kernelInfoDeserialized)
278277
{
279-
kernelInfo = kernelInfoDeserialized;
278+
kernelInfos = kernelInfoDeserialized;
280279
return true;
281280
}
282281

@@ -319,15 +318,15 @@ internal static bool TryGetKernelInfoFromMetadata(
319318
deserializedKernelInfo.Add(new KernelInfo(name, language, aliases));
320319
}
321320
}
322-
kernelInfo = deserializedKernelInfo;
321+
kernelInfos = deserializedKernelInfo;
323322
return true;
324323
}
325324
}
326325
}
327326

328327
if (kernelInfoObj is KernelInfoCollection kernelInfoCollection)
329328
{
330-
kernelInfo = kernelInfoCollection;
329+
kernelInfos = kernelInfoCollection;
331330
return true;
332331
}
333332
}
@@ -338,17 +337,17 @@ internal static bool TryGetKernelInfoFromMetadata(
338337
{
339338
case KernelInfoCollection kernelInfoCollection:
340339

341-
kernelInfo = kernelInfoCollection;
340+
kernelInfos = kernelInfoCollection;
342341
return true;
343342

344343
case IDictionary<string, object> dotnetInteractiveDict:
345344
{
346-
kernelInfo = new();
345+
kernelInfos = new();
347346

348347
if (dotnetInteractiveDict.TryGetValue("defaultKernelName", out var nameObj) &&
349348
nameObj is string name)
350349
{
351-
kernelInfo.DefaultKernelName = name;
350+
kernelInfos.DefaultKernelName = name;
352351
}
353352

354353
return true;
@@ -364,7 +363,7 @@ internal static bool TryGetKernelInfoFromMetadata(
364363
if (kernelspecDict.TryGetValue("language", out var languageObj) &&
365364
languageObj is string defaultLanguage)
366365
{
367-
kernelInfo = new KernelInfoCollection
366+
kernelInfos = new KernelInfoCollection
368367
{
369368
DefaultKernelName = defaultLanguage
370369
};
@@ -375,7 +374,7 @@ internal static bool TryGetKernelInfoFromMetadata(
375374
}
376375

377376
// check if a KernelInfoCollection was directly serialized into the metadata
378-
kernelInfo = default;
377+
kernelInfos = default;
379378
return false;
380379
}
381380

src/Microsoft.DotNet.Interactive.Documents/Jupyter/InputCellMetadata.cs

+6-3
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,15 @@ namespace Microsoft.DotNet.Interactive.Documents.Jupyter;
77

88
public class InputCellMetadata
99
{
10-
public InputCellMetadata(string? kernelName = null, string ? language = null)
10+
public InputCellMetadata(string? kernelName = null, string? language = null)
1111
{
1212
KernelName = kernelName;
1313
Language = language;
1414
}
1515

16-
[JsonPropertyName("kernelName")] public string? KernelName { get; }
17-
[JsonPropertyName("language")] public string? Language { get; }
16+
[JsonPropertyName("kernelName")]
17+
public string? KernelName { get; }
18+
19+
[JsonPropertyName("language")]
20+
public string? Language { get; }
1821
}

src/Microsoft.DotNet.Interactive.Documents/Jupyter/InteractiveDocumentExtensions.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
namespace Microsoft.DotNet.Interactive.Documents.Jupyter;
99

10-
public static class InteractiveDocumentExtensions
10+
internal static class InteractiveDocumentExtensions
1111
{
1212
public static InteractiveDocument WithJupyterMetadata(
1313
this InteractiveDocument document,

src/Microsoft.DotNet.Interactive.Documents/Jupyter/InteractiveDocumentOutputElementConverter.cs

+7-2
Original file line numberDiff line numberDiff line change
@@ -97,11 +97,16 @@ public override InteractiveDocumentOutputElement Read(
9797
break;
9898

9999
case "execute_result":
100-
var returnValueElement = new ReturnValueElement(data ?? new Dictionary<string, object>())
100+
var returnValueElement = new ReturnValueElement
101101
{
102102
ExecutionOrder = executionCount ?? 0
103103
};
104-
104+
105+
if (data is not null)
106+
{
107+
returnValueElement.Data.MergeWith(data);
108+
}
109+
105110
if (metadata is not null)
106111
{
107112
returnValueElement.Metadata.MergeWith(metadata);

src/Microsoft.DotNet.Interactive.Documents/Jupyter/Notebook.cs

+8-27
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ namespace Microsoft.DotNet.Interactive.Documents.Jupyter;
1313

1414
public static class Notebook
1515
{
16+
private static readonly Encoding _encoding = new UTF8Encoding(false);
17+
1618
static Notebook()
1719
{
1820
JsonSerializerOptions = new JsonSerializerOptions
@@ -33,12 +35,7 @@ static Notebook()
3335
};
3436
}
3537

36-
public static JsonSerializerOptions JsonSerializerOptions { get; }
37-
38-
public const string MetadataNamespace = "dotnet_interactive";
39-
public const string PolyglotMetadataNamespace = "polyglot_notebook";
40-
41-
public static Encoding Encoding => new UTF8Encoding(false);
38+
internal static JsonSerializerOptions JsonSerializerOptions { get; }
4239

4340
public static InteractiveDocument Parse(
4441
string json,
@@ -59,24 +56,11 @@ public static InteractiveDocument Read(
5956
Stream stream,
6057
KernelInfoCollection kernelInfos)
6158
{
62-
using var reader = new StreamReader(stream, Encoding);
59+
using var reader = new StreamReader(stream, _encoding);
6360
var content = reader.ReadToEnd();
6461
return Parse(content, kernelInfos);
6562
}
6663

67-
public static void Write(InteractiveDocument document, Stream stream)
68-
{
69-
using var writer = new StreamWriter(stream, Encoding, 1024, true);
70-
Write(document, writer);
71-
writer.Flush();
72-
}
73-
74-
public static void Write(InteractiveDocument document, Stream stream, KernelInfoCollection kernelInfos)
75-
{
76-
InteractiveDocument.MergeKernelInfos(document, kernelInfos);
77-
Write(document, stream);
78-
}
79-
8064
public static string ToJupyterJson(
8165
this InteractiveDocument document,
8266
string? defaultLanguage = null)
@@ -97,15 +81,12 @@ public static string ToJupyterJson(
9781
return singleSpaceIndentedJson;
9882
}
9983

100-
public static void Write(InteractiveDocument document, TextWriter writer)
84+
public static void Write(InteractiveDocument document, Stream stream, KernelInfoCollection kernelInfos)
10185
{
86+
InteractiveDocument.MergeKernelInfos(document, kernelInfos);
87+
using var writer = new StreamWriter(stream, _encoding, 1024, true);
10288
var content = document.ToJupyterJson();
10389
writer.Write(content);
90+
writer.Flush();
10491
}
105-
public static void Write(InteractiveDocument document, TextWriter writer, KernelInfoCollection kernelInfos)
106-
{
107-
InteractiveDocument.MergeKernelInfos(document, kernelInfos);
108-
Write(document, writer);
109-
}
110-
11192
}

src/Microsoft.DotNet.Interactive.Documents/KernelInfoCollection.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ public KernelInfoCollection Clone()
9999
return clone;
100100
}
101101

102-
public bool TryGetByAlias(string alias, out KernelInfo info)
102+
internal bool TryGetByAlias(string alias, out KernelInfo info)
103103
{
104104
return _kernelInfoByNameOrAlias!.TryGetValue(alias, out info);
105105
}

src/Microsoft.DotNet.Interactive.Documents/ReturnValueElement.cs

+1-7
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,14 @@
11
// Copyright (c) .NET Foundation and contributors. All rights reserved.
22
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
33

4-
using System;
54
using System.Collections.Generic;
65

76
namespace Microsoft.DotNet.Interactive.Documents;
87

98
public class ReturnValueElement : InteractiveDocumentOutputElement, IDataElement
109
{
11-
public ReturnValueElement(IDictionary<string, object>? data)
12-
{
13-
Data = data ?? throw new ArgumentNullException(nameof(data));
14-
}
10+
public IDictionary<string, object> Data { get; } = new Dictionary<string, object>();
1511

16-
public IDictionary<string, object> Data { get; }
17-
1812
public int ExecutionOrder { get; set; }
1913

2014
public IDictionary<string, object> Metadata { get; } = new Dictionary<string, object>();

src/Microsoft.DotNet.Interactive.Documents/TextElement.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ namespace Microsoft.DotNet.Interactive.Documents;
55

66
public class TextElement : InteractiveDocumentOutputElement
77
{
8-
public TextElement(string? text, string? name)
8+
public TextElement(string? text, string? name = "stdout")
99
{
1010
Text = text ?? "";
1111
Name = name ?? "stdout";

src/Microsoft.DotNet.Interactive.Jupyter/JupyterRequestContextExtensions.cs

+6-2
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,17 @@ public static class JupyterRequestContextExtensions
1010
public static string GetKernelName(this JupyterRequestContext context)
1111
{
1212
string kernelName = null;
13-
if (context.JupyterRequestMessageEnvelope.MetaData.TryGetValue(Notebook.MetadataNamespace, out var candidateDotnetMetadata) &&
13+
if (context.JupyterRequestMessageEnvelope.MetaData.TryGetValue(
14+
"dotnet_interactive",
15+
out var candidateDotnetMetadata) &&
1416
candidateDotnetMetadata is InputCellMetadata dotnetMetadata)
1517
{
1618
kernelName = dotnetMetadata.Language;
1719
}
1820

19-
if (context.JupyterRequestMessageEnvelope.MetaData.TryGetValue(Notebook.PolyglotMetadataNamespace, out var candidatePolyglotMetadata) &&
21+
if (context.JupyterRequestMessageEnvelope.MetaData.TryGetValue(
22+
"polyglot_notebook",
23+
out var candidatePolyglotMetadata) &&
2024
candidatePolyglotMetadata is InputCellMetadata polyglotMetadata)
2125
{
2226
kernelName = polyglotMetadata.KernelName;

0 commit comments

Comments
 (0)