Machine Learning Extension - Model details (#9377)

* Machine Learning Services Extension - adding model details
This commit is contained in:
Leila Lali
2020-03-02 12:47:09 -08:00
committed by GitHub
parent c1f6a67829
commit b5b65117a7
30 changed files with 852 additions and 224 deletions

View File

@@ -20,8 +20,6 @@ import { PackageConfigModel } from '../configurations/packageConfigModel';
export class PackageManager {
private _pythonExecutable: string = '';
private _rExecutable: string = '';
private _sqlPythonPackagePackageManager: SqlPythonPackageManageProvider;
private _sqlRPackageManager: SqlRPackageManageProvider;
public dependenciesInstalled: boolean = false;
@@ -45,10 +43,15 @@ export class PackageManager {
* Initializes the instance and resister SQL package manager with manage package dialog
*/
public init(): void {
this._pythonExecutable = this._config.pythonExecutable;
this._rExecutable = this._config.rExecutable;
}
private get pythonExecutable(): string {
return this._config.pythonExecutable;
}
private get _rExecutable(): string {
return this._config.rExecutable;
}
/**
* Returns packageManageProviders
*/
@@ -70,9 +73,9 @@ export class PackageManager {
let isPythonInstalled = await this._queryRunner.isPythonInstalled(connection);
let isRInstalled = await this._queryRunner.isRInstalled(connection);
let defaultProvider: SqlRPackageManageProvider | SqlPythonPackageManageProvider | undefined;
if (connection && isPythonInstalled) {
if (connection && isPythonInstalled && this._sqlPythonPackagePackageManager.canUseProvider) {
defaultProvider = this._sqlPythonPackagePackageManager;
} else if (connection && isRInstalled) {
} else if (connection && isRInstalled && this._sqlRPackageManager.canUseProvider) {
defaultProvider = this._sqlRPackageManager;
}
if (connection && defaultProvider) {
@@ -104,34 +107,12 @@ export class PackageManager {
* Installs dependencies for the extension
*/
public async installDependencies(): Promise<void> {
return new Promise<void>((resolve, reject) => {
let msgTaskName = constants.installDependenciesMsgTaskName;
this._apiWrapper.startBackgroundOperation({
displayName: msgTaskName,
description: msgTaskName,
isCancelable: false,
operation: async op => {
try {
await utils.createFolder(utils.getRPackagesFolderPath(this._rootFolder));
// Install required packages
//
await Promise.all([
this.installRequiredPythonPackages(),
this.installRequiredRPackages(op)]);
op.updateStatus(azdata.TaskStatus.Succeeded);
resolve();
} catch (error) {
let errorMsg = constants.installDependenciesError(error ? error.message : '');
op.updateStatus(azdata.TaskStatus.Failed, errorMsg);
reject(errorMsg);
}
}
});
});
await utils.executeTasks(this._apiWrapper, constants.installDependenciesMsgTaskName, [
this.installRequiredPythonPackages(this._config.requiredSqlPythonPackages),
this.installRequiredRPackages()], true);
}
private async installRequiredRPackages(startBackgroundOperation: azdata.BackgroundOperation): Promise<void> {
private async installRequiredRPackages(): Promise<void> {
if (!this._config.rEnabled) {
return;
}
@@ -139,22 +120,27 @@ export class PackageManager {
throw new Error(constants.rConfigError);
}
await Promise.all(this._config.requiredRPackages.map(x => this.installRPackage(x, startBackgroundOperation)));
await utils.createFolder(utils.getRPackagesFolderPath(this._rootFolder));
await Promise.all(this._config.requiredSqlPythonPackages.map(x => this.installRPackage(x)));
}
/**
* Installs required python packages
*/
private async installRequiredPythonPackages(): Promise<void> {
public async installRequiredPythonPackages(requiredPackages: PackageConfigModel[]): Promise<void> {
if (!this._config.pythonEnabled) {
return;
}
if (!this._pythonExecutable) {
if (!this.pythonExecutable) {
throw new Error(constants.pythonConfigError);
}
if (!requiredPackages || requiredPackages.length === 0) {
return;
}
let installedPackages = await this.getInstalledPipPackages();
let fileContent = '';
this._config.requiredPythonPackages.forEach(packageDetails => {
requiredPackages.forEach(packageDetails => {
let hasVersion = ('version' in packageDetails) && !isNullOrUndefined(packageDetails['version']) && packageDetails['version'].length > 0;
if (!installedPackages.find(x => x.name === packageDetails['name'] && (!hasVersion || packageDetails['version'] === x.version))) {
let packageNameDetail = hasVersion ? `${packageDetails.name}==${packageDetails.version}` : `${packageDetails.name}`;
@@ -163,11 +149,17 @@ export class PackageManager {
});
if (fileContent) {
this._outputChannel.appendLine(constants.installDependenciesPackages);
let result = await utils.execCommandOnTempFile<string>(fileContent, async (tempFilePath) => {
return await this.installPipPackage(tempFilePath);
});
this._outputChannel.appendLine(result);
let confirmed = await utils.promptConfirm(constants.confirmInstallPythonPackages(fileContent), this._apiWrapper);
if (confirmed) {
this._outputChannel.appendLine(constants.installDependenciesPackages);
let result = await utils.execCommandOnTempFile<string>(fileContent, async (tempFilePath) => {
return await this.installPipPackage(tempFilePath);
});
this._outputChannel.appendLine(result);
} else {
throw Error(constants.requiredPackagesNotInstalled);
}
} else {
this._outputChannel.appendLine(constants.installDependenciesPackagesAlreadyInstalled);
}
@@ -175,7 +167,7 @@ export class PackageManager {
private async getInstalledPipPackages(): Promise<nbExtensionApis.IPackageDetails[]> {
try {
let cmd = `"${this._pythonExecutable}" -m pip list --format=json`;
let cmd = `"${this.pythonExecutable}" -m pip list --format=json`;
let packagesInfo = await this._processService.executeBufferedCommand(cmd, this._outputChannel);
let packagesResult: nbExtensionApis.IPackageDetails[] = [];
if (packagesInfo) {
@@ -194,18 +186,18 @@ export class PackageManager {
}
private async installPipPackage(requirementFilePath: string): Promise<string> {
let cmd = `"${this._pythonExecutable}" -m pip install -r "${requirementFilePath}"`;
let cmd = `"${this.pythonExecutable}" -m pip install -r "${requirementFilePath}"`;
return await this._processService.executeBufferedCommand(cmd, this._outputChannel);
}
private async installRPackage(model: PackageConfigModel, startBackgroundOperation: azdata.BackgroundOperation): Promise<string> {
private async installRPackage(model: PackageConfigModel): Promise<string> {
let output = '';
let cmd = '';
if (model.downloadUrl) {
const packageFile = utils.getPackageFilePath(this._rootFolder, model.fileName || model.name);
const packageExist = await utils.exists(packageFile);
if (!packageExist) {
await this._httpClient.download(model.downloadUrl, packageFile, startBackgroundOperation, this._outputChannel);
await this._httpClient.download(model.downloadUrl, packageFile, this._outputChannel);
}
cmd = `"${this._rExecutable}" CMD INSTALL ${packageFile}`;
output = await this._processService.executeBufferedCommand(cmd, this._outputChannel);