mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-03-18 19:11:36 -04:00
Add dialog to notebooks for managing Pip packages (#5944)
This commit is contained in:
@@ -24,6 +24,7 @@ import { NotebookCompletionItemProvider } from '../intellisense/completionItemPr
|
||||
import { JupyterNotebookProvider } from './jupyterNotebookProvider';
|
||||
import { ConfigurePythonDialog } from '../dialog/configurePythonDialog';
|
||||
import CodeAdapter from '../prompts/adapter';
|
||||
import { ManagePackagesDialog } from '../dialog/managePackages/managePackagesDialog';
|
||||
|
||||
let untitledCounter = 0;
|
||||
|
||||
@@ -73,7 +74,7 @@ export class JupyterController implements vscode.Disposable {
|
||||
});
|
||||
|
||||
this.apiWrapper.registerCommand(constants.jupyterReinstallDependenciesCommand, () => { return this.handleDependenciesReinstallation(); });
|
||||
this.apiWrapper.registerCommand(constants.jupyterInstallPackages, () => { return this.doManagePackages(); });
|
||||
this.apiWrapper.registerCommand(constants.jupyterManagePackages, () => { return this.doManagePackages(); });
|
||||
this.apiWrapper.registerCommand(constants.jupyterConfigurePython, () => { return this.doConfigurePython(this._jupyterInstallation); });
|
||||
|
||||
let supportedFileFilter: vscode.DocumentFilter[] = [
|
||||
@@ -194,10 +195,8 @@ export class JupyterController implements vscode.Disposable {
|
||||
|
||||
public doManagePackages(): void {
|
||||
try {
|
||||
let terminal = this.apiWrapper.createTerminalWithOptions({ cwd: this.getPythonBinDir() });
|
||||
terminal.show(true);
|
||||
let shellType = this.apiWrapper.getConfiguration().get('terminal.integrated.shell.windows');
|
||||
terminal.sendText(this.getTextToSendToTerminal(shellType), true);
|
||||
let packagesDialog = new ManagePackagesDialog(this._jupyterInstallation);
|
||||
packagesDialog.showDialog();
|
||||
} catch (error) {
|
||||
let message = utils.getErrorMessage(error);
|
||||
this.apiWrapper.showErrorMessage(message);
|
||||
@@ -225,10 +224,6 @@ export class JupyterController implements vscode.Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
private getPythonBinDir(): string {
|
||||
return JupyterServerInstallation.getPythonBinPath(this.apiWrapper);
|
||||
}
|
||||
|
||||
public get jupyterInstallation() {
|
||||
return this._jupyterInstallation;
|
||||
}
|
||||
|
||||
@@ -347,6 +347,28 @@ export default class JupyterServerInstallation {
|
||||
}
|
||||
}
|
||||
|
||||
public async getInstalledPipPackages(): Promise<PythonPkgDetails[]> {
|
||||
let cmd = `"${this.pythonExecutable}" -m pip list --format=json`;
|
||||
let packagesInfo = await this.executeBufferedCommand(cmd);
|
||||
|
||||
let packagesResult: PythonPkgDetails[] = [];
|
||||
if (packagesInfo) {
|
||||
packagesResult = <PythonPkgDetails[]>JSON.parse(packagesInfo);
|
||||
}
|
||||
return packagesResult;
|
||||
}
|
||||
|
||||
public installPipPackage(packageName: string, version: string): Promise<void> {
|
||||
let cmd = `"${this.pythonExecutable}" -m pip install ${packageName}==${version}`;
|
||||
return this.executeStreamedCommand(cmd);
|
||||
}
|
||||
|
||||
public uninstallPipPackages(packages: PythonPkgDetails[]): Promise<void> {
|
||||
let packagesStr = packages.map(pkg => `${pkg.name}==${pkg.version}`).join(' ');
|
||||
let cmd = `"${this.pythonExecutable}" -m pip uninstall -y ${packagesStr}`;
|
||||
return this.executeStreamedCommand(cmd);
|
||||
}
|
||||
|
||||
private async installOfflinePipPackages(): Promise<void> {
|
||||
let installJupyterCommand: string;
|
||||
if (process.platform === constants.winPlatform) {
|
||||
@@ -357,7 +379,7 @@ export default class JupyterServerInstallation {
|
||||
if (installJupyterCommand) {
|
||||
this.outputChannel.show(true);
|
||||
this.outputChannel.appendLine(localize('msgInstallStart', "Installing required packages to run Notebooks..."));
|
||||
await this.executeCommand(installJupyterCommand);
|
||||
await this.executeStreamedCommand(installJupyterCommand);
|
||||
this.outputChannel.appendLine(localize('msgJupyterInstallDone', "... Jupyter installation complete."));
|
||||
} else {
|
||||
return Promise.resolve();
|
||||
@@ -378,7 +400,7 @@ export default class JupyterServerInstallation {
|
||||
if (installSparkMagic) {
|
||||
this.outputChannel.show(true);
|
||||
this.outputChannel.appendLine(localize('msgInstallingSpark', "Installing SparkMagic..."));
|
||||
await this.executeCommand(installSparkMagic);
|
||||
await this.executeStreamedCommand(installSparkMagic);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -387,10 +409,10 @@ export default class JupyterServerInstallation {
|
||||
this.outputChannel.appendLine(localize('msgInstallStart', "Installing required packages to run Notebooks..."));
|
||||
|
||||
let installCommand = `"${this._pythonExecutable}" -m pip install jupyter==1.0.0 pandas==0.24.2`;
|
||||
await this.executeCommand(installCommand);
|
||||
await this.executeStreamedCommand(installCommand);
|
||||
|
||||
installCommand = `"${this._pythonExecutable}" -m pip install prose-codeaccelerator==1.3.0 --extra-index-url https://prose-python-packages.azurewebsites.net`;
|
||||
await this.executeCommand(installCommand);
|
||||
await this.executeStreamedCommand(installCommand);
|
||||
|
||||
this.outputChannel.appendLine(localize('msgJupyterInstallDone', "... Jupyter installation complete."));
|
||||
}
|
||||
@@ -403,18 +425,22 @@ export default class JupyterServerInstallation {
|
||||
if (process.platform !== constants.winPlatform) {
|
||||
installCommand = `${installCommand} pykerberos==1.2.1`;
|
||||
}
|
||||
await this.executeCommand(installCommand);
|
||||
await this.executeStreamedCommand(installCommand);
|
||||
|
||||
installCommand = `"${this._pythonExecutable}" -m pip install prose-codeaccelerator==1.3.0 --extra-index-url https://prose-python-packages.azurewebsites.net`;
|
||||
await this.executeCommand(installCommand);
|
||||
await this.executeStreamedCommand(installCommand);
|
||||
|
||||
this.outputChannel.appendLine(localize('msgJupyterInstallDone', "... Jupyter installation complete."));
|
||||
}
|
||||
|
||||
private async executeCommand(command: string): Promise<void> {
|
||||
private async executeStreamedCommand(command: string): Promise<void> {
|
||||
await utils.executeStreamedCommand(command, { env: this.execOptions.env }, this.outputChannel);
|
||||
}
|
||||
|
||||
private async executeBufferedCommand(command: string): Promise<string> {
|
||||
return await utils.executeBufferedCommand(command, { env: this.execOptions.env });
|
||||
}
|
||||
|
||||
public get pythonExecutable(): string {
|
||||
return this._pythonExecutable;
|
||||
}
|
||||
@@ -500,10 +526,20 @@ export default class JupyterServerInstallation {
|
||||
pythonBinPathSuffix);
|
||||
}
|
||||
|
||||
public async getPythonPackagesPath(): Promise<string> {
|
||||
let cmd = `"${this.pythonExecutable}" -c "import site; print(site.getsitepackages()[0])"`;
|
||||
return await this.executeBufferedCommand(cmd);
|
||||
}
|
||||
|
||||
public static getPythonExePath(pythonInstallPath: string, useExistingInstall: boolean): string {
|
||||
return path.join(
|
||||
pythonInstallPath,
|
||||
useExistingInstall ? '' : constants.pythonBundleVersion,
|
||||
process.platform === constants.winPlatform ? 'python.exe' : 'bin/python3');
|
||||
}
|
||||
}
|
||||
|
||||
export interface PythonPkgDetails {
|
||||
name: string;
|
||||
version: string;
|
||||
}
|
||||
Reference in New Issue
Block a user