Add sample Notebook provider (#17988)

This commit is contained in:
Charles Gagnon
2022-01-05 09:14:54 -08:00
committed by GitHub
parent 4a2b31f3ba
commit b2c919e054
14 changed files with 286 additions and 0 deletions

25
.vscode/launch.json vendored
View File

@@ -294,6 +294,31 @@
"group": "5_samples"
},
"timeout": 30000
},
{
"name": "Run Sample Notebook Provider Extension",
"type": "sqlopsExtensionHost",
"request": "launch",
"windows": {
"runtimeExecutable": "${workspaceFolder}/scripts/sql.bat"
},
"osx": {
"runtimeExecutable": "${workspaceFolder}/scripts/sql.sh"
},
"linux": {
"runtimeExecutable": "${workspaceFolder}/scripts/sql.sh"
},
"args": [
"--extensionDevelopmentPath=${workspaceRoot}/samples/sample-notebook-provider"
],
"outFiles": [
"${workspaceRoot}/samples/sample-notebook-provider/out/**/*.js"
],
"preLaunchTask": "Watch sample-notebook-provider",
"presentation": {
"group": "5_samples"
},
"timeout": 30000
}
],
"compounds": [

12
.vscode/tasks.json vendored
View File

@@ -243,6 +243,18 @@
"reveal": "never"
},
"group": "build"
},
{
"type": "npm",
"script": "watch",
"label": "Watch sample-notebook-provider",
"path": "./samples/sample-notebook-provider/package.json",
"problemMatcher": "$tsc-watch",
"isBackground": true,
"presentation": {
"reveal": "never"
},
"group": "build"
}
]
}

View File

@@ -0,0 +1 @@
out

View File

@@ -0,0 +1 @@
--ignore-engines true

View File

@@ -0,0 +1,3 @@
# Notebook Provider Samples
This extension provides examples of how to provide a new Notebook serializer and controller for handling loading and running a custom Notebook.

Binary file not shown.

After

Width:  |  Height:  |  Size: 889 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

View File

@@ -0,0 +1,54 @@
{
"name": "sample-notebook-provider",
"displayName": "%extension-display-name%",
"description": "%extension-description%",
"version": "0.0.1",
"publisher": "Microsoft",
"preview": true,
"license": "https://raw.githubusercontent.com/Microsoft/azuredatastudio/main/LICENSE.txt",
"icon": "images/sqlserver.png",
"engines": {
"vscode": "*",
"azdata": ">=1.34.0"
},
"categories": [
"Other"
],
"activationEvents": [
"*"
],
"repository": {
"type": "git",
"url": "https://github.com/Microsoft/azuredatastudio.git"
},
"extensionDependencies": [
"microsoft.notebook"
],
"main": "./out/extension",
"scripts": {
"compile": "node node_modules/typescript/bin/tsc -p ./tsconfig.json",
"watch": "node node_modules/typescript/bin/tsc --watch -p ./tsconfig.json"
},
"contributes": {
"notebooks": [
{
"id": "my-notebook",
"type": "my-notebook",
"displayName": "My Custom Notebook",
"selector": [
{
"filenamePattern": "*.mynotebook"
}
]
}
]
},
"dependencies": {
},
"devDependencies": {
"@types/azdata": "^1.34.0",
"@types/vscode": "^1.61.0",
"@types/node": "14.x",
"typescript": "^4.4.0-dev.20210607"
}
}

View File

@@ -0,0 +1,4 @@
{
"extension-display-name": "Sample Notebook provider extension for Azure Data Studio",
"extension-description": "Demonstrates contributing a custom Notebook provider which allows users to contribute their own custom Notebooks."
}

View File

@@ -0,0 +1,18 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import { SampleController } from './sampleController';
import { SampleSerializer } from './sampleSerializer';
export function activate(context: vscode.ExtensionContext) {
// Create and register the serializer and controller with Azure Data Studio
context.subscriptions.push(
vscode.workspace.registerNotebookSerializer('my-notebook', new SampleSerializer())
);
context.subscriptions.push(new SampleController(context));
}
export function deactivate() { }

View File

@@ -0,0 +1,93 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import * as fs from 'fs/promises';
import * as path from 'path';
/**
* A sample Notebook controller which handles creating a new controller and registering it with Azure Data Studio
*/
export class SampleController {
// The unique ID of the controller
readonly controllerId = 'my-notebook-controller-id';
// The type of the notebook, must be the same as defined in the package.json contribution
readonly notebookType = 'my-notebook';
// Label to display in the UI when choosing a Notebook provider
readonly label = 'My Notebook';
// The languages this Notebook supports for code cells
readonly supportedLanguages = ['python'];
private readonly _controller: vscode.NotebookController;
private _executionOrder = 0;
constructor(private context: vscode.ExtensionContext) {
this._controller = vscode.notebooks.createNotebookController(
this.controllerId,
this.notebookType,
this.label
);
this._controller.supportedLanguages = this.supportedLanguages;
this._controller.supportsExecutionOrder = true;
this._controller.executeHandler = this._execute.bind(this);
}
dispose() { }
private async _execute(
cells: vscode.NotebookCell[],
_notebook: vscode.NotebookDocument,
_controller: vscode.NotebookController
): Promise<void> {
for (let cell of cells) {
await this._doExecution(cell);
}
}
private async _doExecution(cell: vscode.NotebookCell): Promise<void> {
// First we create an execution object for the cell and start it
const execution = this._controller.createNotebookCellExecution(cell);
execution.executionOrder = ++this._executionOrder;
execution.start();
// This logic can be whatever you want - typically you would use the contents of the cell and do something
// with that (such as executing a query) but you can also run whatever code you want to and send outputs
// to be displayed.
const image = await fs.readFile(path.join(this.context.extensionPath, 'images', 'computer-cat.gif'));
// Header output that includes the original text of the cell, formatted as markdown
const outputHeader = new vscode.NotebookCellOutput([
vscode.NotebookCellOutputItem.text(`**Running code: ${cell.document.getText()}**`, 'text/markdown'),
]);
// Simple text output
const output = new vscode.NotebookCellOutput([
vscode.NotebookCellOutputItem.text('Finding the cat'),
]);
// Initial set of messages
await execution.replaceOutput([
outputHeader,
output
]);
// Show replacing the output items to incrementally update a specific output
for (let i = 1; i < 8; i++) {
await new Promise(resolve => setTimeout(resolve, 500));
await execution.replaceOutputItems([
vscode.NotebookCellOutputItem.text('Finding the cat' + '.'.repeat(i))
], output);
}
// End by replacing the text with a gif
await execution.replaceOutputItems([
vscode.NotebookCellOutputItem.text(image.toString('base64'), 'image/gif')
], output);
// And finally append a new output to the existing ones
await execution.appendOutput(new vscode.NotebookCellOutput([vscode.NotebookCellOutputItem.text('Cat found!')]), cell);
// Signal execution end
execution.end(true);
}
}

View File

@@ -0,0 +1,35 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
/**
* Sample hardcoded contents for the Notebook.
*/
const presetNotebookData: vscode.NotebookData = {
cells: [{
kind: vscode.NotebookCellKind.Markup,
value: 'Sample markup cell',
languageId: 'Markup'
}, {
kind: vscode.NotebookCellKind.Code,
value: '1+1',
languageId: 'Python'
}]
};
const presetNotebookBytes = new TextEncoder().encode(JSON.stringify(presetNotebookData));
/**
* A sample Notebook serializer which handles serializing/deserializing the Notebook from/into a byte array for storage.
*/
export class SampleSerializer implements vscode.NotebookSerializer {
deserializeNotebook(content: Uint8Array, token: vscode.CancellationToken): vscode.NotebookData | Thenable<vscode.NotebookData> {
return presetNotebookData;
}
serializeNotebook(data: vscode.NotebookData, token: vscode.CancellationToken): Uint8Array | Thenable<Uint8Array> {
return presetNotebookBytes;
}
}

View File

@@ -0,0 +1,15 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es6",
"outDir": "out",
"sourceMap": true,
"rootDir": "src",
"strict": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true
},
"exclude": [
"node_modules"
]
}

View File

@@ -0,0 +1,25 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@types/azdata@^1.34.0":
version "1.34.0"
resolved "https://registry.yarnpkg.com/@types/azdata/-/azdata-1.34.0.tgz#8e48249e5ccb5e2b927e1176cb578822391e04e3"
integrity sha512-0vSuYYnUhHd7D68uL6/prQAdAMBEnG6i5Nu3Dt9LOFsURgW365EbDBqmGtZ96Q3x87F+DVC14hI+15J7Mtx/Yw==
dependencies:
"@types/vscode" "*"
"@types/node@14.x":
version "14.17.32"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.17.32.tgz#2ca61c9ef8c77f6fa1733be9e623ceb0d372ad96"
integrity sha512-JcII3D5/OapPGx+eJ+Ik1SQGyt6WvuqdRfh9jUwL6/iHGjmyOriBDciBUu7lEIBTL2ijxwrR70WUnw5AEDmFvQ==
"@types/vscode@*", "@types/vscode@^1.61.0":
version "1.61.0"
resolved "https://registry.yarnpkg.com/@types/vscode/-/vscode-1.61.0.tgz#c54335b6f84c19c69b1435b17cc0ce3b2cecfeec"
integrity sha512-9k5Nwq45hkRwdfCFY+eKXeQQSbPoA114mF7U/4uJXRBJeGIO7MuJdhF1PnaDN+lllL9iKGQtd6FFXShBXMNaFg==
typescript@^4.4.0-dev.20210607:
version "4.4.4"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.4.4.tgz#2cd01a1a1f160704d3101fd5a58ff0f9fcb8030c"
integrity sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==