Skip to content

Commit 7b3b541

Browse files
authored
Extension api for DataScience (#13923)
* Extension API * Api for DS
1 parent 016cce8 commit 7b3b541

File tree

2 files changed

+112
-0
lines changed

2 files changed

+112
-0
lines changed

src/client/api.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { NotebookCell } from 'vscode-proposed';
88
import { isTestExecution } from './common/constants';
99
import { traceError } from './common/logger';
1010
import { IConfigurationService, Resource } from './common/types';
11+
import { JupyterExtensionIntegration } from './datascience/api/jupyterIntegration';
1112
import { IDataViewerDataProvider, IDataViewerFactory } from './datascience/data-viewing/types';
1213
import { IJupyterUriProvider, IJupyterUriProviderRegistration, INotebookExtensibility } from './datascience/types';
1314
import { getDebugpyLauncherArgs, getDebugpyPackagePath } from './debugger/extension/adapter/remoteLaunchers';
@@ -26,6 +27,9 @@ export interface IExtensionApi {
2627
* @memberof IExtensionApi
2728
*/
2829
ready: Promise<void>;
30+
jupyter: {
31+
registerHooks(): void;
32+
};
2933
debug: {
3034
/**
3135
* Generate an array of strings for commands to pass to the Python executable to launch the debugger for remote debugging.
@@ -103,12 +107,17 @@ export function buildApi(
103107
const configurationService = serviceContainer.get<IConfigurationService>(IConfigurationService);
104108
const interpreterService = serviceContainer.get<IInterpreterService>(IInterpreterService);
105109
const notebookExtensibility = serviceContainer.get<INotebookExtensibility>(INotebookExtensibility);
110+
serviceManager.addSingleton<JupyterExtensionIntegration>(JupyterExtensionIntegration, JupyterExtensionIntegration);
111+
const jupyterIntegration = serviceContainer.get<JupyterExtensionIntegration>(JupyterExtensionIntegration);
106112
const api: IExtensionApi = {
107113
// 'ready' will propagate the exception, but we must log it here first.
108114
ready: ready.catch((ex) => {
109115
traceError('Failure during activation.', ex);
110116
return Promise.reject(ex);
111117
}),
118+
jupyter: {
119+
registerHooks: () => jupyterIntegration.integrateWithJupyterExtension()
120+
},
112121
debug: {
113122
async getRemoteLauncherCommand(
114123
host: string,
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
// tslint:disable-next-line: no-single-line-block-comment
2+
/* eslint-disable comma-dangle */
3+
// tslint:disable-next-line: no-single-line-block-comment
4+
/* eslint-disable implicit-arrow-linebreak */
5+
// Copyright (c) Microsoft Corporation. All rights reserved.
6+
// Licensed under the MIT License.
7+
8+
import { inject, injectable } from 'inversify';
9+
import { CancellationToken, Event, Uri } from 'vscode';
10+
import { InterpreterUri } from '../../common/installer/types';
11+
import { IExtensions, IInstaller, InstallerResponse, Product, Resource } from '../../common/types';
12+
import { IEnvironmentActivationService } from '../../interpreter/activation/types';
13+
import { IInterpreterQuickPickItem, IInterpreterSelector } from '../../interpreter/configuration/types';
14+
import { IInterpreterService } from '../../interpreter/contracts';
15+
import { IWindowsStoreInterpreter } from '../../interpreter/locators/types';
16+
import { WindowsStoreInterpreter } from '../../pythonEnvironments/discovery/locators/services/windowsStoreInterpreter';
17+
import { PythonEnvironment } from '../../pythonEnvironments/info';
18+
19+
type PythonApiForJupyterExtension = {
20+
/**
21+
* IInterpreterService
22+
*/
23+
onDidChangeInterpreter: Event<void>;
24+
/**
25+
* IInterpreterService
26+
*/
27+
getInterpreters(resource?: Uri): Promise<PythonEnvironment[]>;
28+
/**
29+
* IInterpreterService
30+
*/
31+
getActiveInterpreter(resource?: Uri): Promise<PythonEnvironment | undefined>;
32+
/**
33+
* IInterpreterService
34+
*/
35+
getInterpreterDetails(pythonPath: string, resource?: Uri): Promise<undefined | PythonEnvironment>;
36+
37+
/**
38+
* IEnvironmentActivationService
39+
*/
40+
getActivatedEnvironmentVariables(
41+
resource: Resource,
42+
interpreter?: PythonEnvironment,
43+
allowExceptions?: boolean
44+
): Promise<NodeJS.ProcessEnv | undefined>;
45+
isWindowsStoreInterpreter(pythonPath: string): Promise<boolean>;
46+
/**
47+
* IWindowsStoreInterpreter
48+
*/
49+
getSuggestions(resource: Resource): Promise<IInterpreterQuickPickItem[]>;
50+
/**
51+
* IInstaller
52+
*/
53+
install(product: Product, resource?: InterpreterUri, cancel?: CancellationToken): Promise<InstallerResponse>;
54+
};
55+
56+
type JupyterExtensionApi = {
57+
registerPythonApi(interpreterService: PythonApiForJupyterExtension): void;
58+
};
59+
60+
@injectable()
61+
export class JupyterExtensionIntegration {
62+
constructor(
63+
@inject(IExtensions) private readonly extensions: IExtensions,
64+
@inject(IInterpreterService) private readonly interpreterService: IInterpreterService,
65+
@inject(IInterpreterSelector) private readonly interpreterSelector: IInterpreterSelector,
66+
@inject(WindowsStoreInterpreter) private readonly windowsStoreInterpreter: IWindowsStoreInterpreter,
67+
@inject(IInstaller) private readonly installer: IInstaller,
68+
@inject(IEnvironmentActivationService) private readonly envActivation: IEnvironmentActivationService
69+
) {}
70+
71+
public async integrateWithJupyterExtension(): Promise<void> {
72+
const jupyterExtension = this.extensions.getExtension<JupyterExtensionApi>('ms-ai-tools.jupyter');
73+
if (!jupyterExtension) {
74+
return;
75+
}
76+
await jupyterExtension.activate();
77+
if (!jupyterExtension.isActive) {
78+
return;
79+
}
80+
const jupyterExtensionApi = jupyterExtension.exports;
81+
jupyterExtensionApi.registerPythonApi({
82+
onDidChangeInterpreter: this.interpreterService.onDidChangeInterpreter,
83+
getActiveInterpreter: async (resource?: Uri) => this.interpreterService.getActiveInterpreter(resource),
84+
getInterpreterDetails: async (pythonPath: string) =>
85+
this.interpreterService.getInterpreterDetails(pythonPath),
86+
getInterpreters: async (resource: Uri | undefined) => this.interpreterService.getInterpreters(resource),
87+
getActivatedEnvironmentVariables: async (
88+
resource: Resource,
89+
interpreter?: PythonEnvironment,
90+
allowExceptions?: boolean
91+
) => this.envActivation.getActivatedEnvironmentVariables(resource, interpreter, allowExceptions),
92+
isWindowsStoreInterpreter: async (pythonPath: string): Promise<boolean> =>
93+
this.windowsStoreInterpreter.isWindowsStoreInterpreter(pythonPath),
94+
getSuggestions: async (resource: Resource): Promise<IInterpreterQuickPickItem[]> =>
95+
this.interpreterSelector.getSuggestions(resource),
96+
install: async (
97+
product: Product,
98+
resource?: InterpreterUri,
99+
cancel?: CancellationToken
100+
): Promise<InstallerResponse> => this.installer.install(product, resource, cancel)
101+
});
102+
}
103+
}

0 commit comments

Comments
 (0)