Skip to content

Commit

Permalink
Adds spp model get command closes #6105
Browse files Browse the repository at this point in the history
  • Loading branch information
mkm17 committed Nov 21, 2024
1 parent 6c6be23 commit 7d3db71
Show file tree
Hide file tree
Showing 6 changed files with 846 additions and 3 deletions.
306 changes: 306 additions & 0 deletions docs/docs/cmd/spp/model/model-get.mdx

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions docs/src/config/sidebars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3989,6 +3989,11 @@ const sidebars: SidebarsConfig = {
},
{
model: [
{
type: 'doc',
label: 'model get',
id: 'cmd/spp/model/model-get'
},
{
type: 'doc',
label: 'model list',
Expand Down
1 change: 1 addition & 0 deletions src/m365/spp/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ const prefix: string = 'spp';

export default {
CONTENTCENTER_LIST: `${prefix} contentcenter list`,
MODEL_GET: `${prefix} model get`,
MODEL_LIST: `${prefix} model list`
};
375 changes: 375 additions & 0 deletions src/m365/spp/commands/model/model-get.spec.ts

Large diffs are not rendered by default.

146 changes: 146 additions & 0 deletions src/m365/spp/commands/model/model-get.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
import { Logger } from '../../../../cli/Logger.js';
import GlobalOptions from '../../../../GlobalOptions.js';
import request, { CliRequestOptions } from '../../../../request.js';
import { formatting } from '../../../../utils/formatting.js';
import { odata } from '../../../../utils/odata.js';
import { spp, SppModel } from '../../../../utils/spp.js';
import { urlUtil } from '../../../../utils/urlUtil.js';
import { validation } from '../../../../utils/validation.js';
import SpoCommand from '../../../base/SpoCommand.js';
import commands from '../../commands.js';

interface CommandArgs {
options: Options;
}

interface Options extends GlobalOptions {
siteUrl: string;
id?: string;
title?: string;
withPublications?: boolean;
}

class SppModelGetCommand extends SpoCommand {
public get name(): string {
return commands.MODEL_GET;
}

public get description(): string {
return 'Retrieves information about a document understanding model';
}

constructor() {
super();

this.#initTelemetry();
this.#initOptions();
this.#initValidators();
this.#initOptionSets();
this.#initTypes();
}

#initTelemetry(): void {
this.telemetry.push((args: CommandArgs) => {
Object.assign(this.telemetryProperties, {
id: typeof args.options.id !== 'undefined',
title: typeof args.options.title !== 'undefined',
withPublications: !!args.options.withPublications
});
});
}

#initOptions(): void {
this.options.unshift(
{
option: '-u, --siteUrl <siteUrl>'
},
{
option: '-i, --id [id]'
},
{
option: '-t, --title [title]'
},
{
option: '--withPublications'
}
);
}

#initValidators(): void {
this.validators.push(
async (args: CommandArgs) => {
if (args.options.id && !validation.isValidGuid(args.options.id)) {
return `${args.options.id} is not a valid GUID for option 'id'.`;
}

return validation.isValidSharePointUrl(args.options.siteUrl);
}
);
}

#initOptionSets(): void {
this.optionSets.push({ options: ['id', 'title'] });
}

#initTypes(): void {
this.types.string.push('siteUrl', 'id', 'title');
this.types.boolean.push('withPublications');
}

public async commandAction(logger: Logger, args: CommandArgs): Promise<void> {
try {
if (this.verbose) {
await logger.log(`Retrieving model information from ${args.options.siteUrl}...`);
}

const siteUrl = urlUtil.removeTrailingSlashes(args.options.siteUrl);
await spp.assertSiteIsContentCenter(siteUrl);

let requestUrl = `${siteUrl}/_api/machinelearning/models/`;

if (args.options.title) {
let requestTitle = args.options.title.toLowerCase();

if (!requestTitle.endsWith('.classifier')) {
requestTitle += '.classifier';
}

requestUrl += `getbytitle('${formatting.encodeQueryParameter(requestTitle)}')`;
}
else {
requestUrl += `getbyuniqueid('${args.options.id}')`;
}

const requestOptions: CliRequestOptions = {
url: requestUrl,
headers: {
accept: 'application/json;odata=nometadata'
},
responseType: 'json'
};

const result = await request.get<SppModel>(requestOptions);

if (result?.['odata.null'] === true) {
throw 'Model not found.';
}

if (args.options.withPublications) {
result.Publications = await odata.getAllItems<any>(`${siteUrl}/_api/machinelearning/publications/getbymodeluniqueid('${result.UniqueId}')`);
}

await logger.log({
...result,
ConfidenceScore: result.ConfidenceScore ? JSON.parse(result.ConfidenceScore) : undefined,
Explanations: result.Explanations ? JSON.parse(result.Explanations) : undefined,
Schemas: result.Schemas ? JSON.parse(result.Schemas) : undefined,
ModelSettings: result.ModelSettings ? JSON.parse(result.ModelSettings) : undefined
});
}
catch (err: any) {
this.handleRejectedODataJsonPromise(err);
}
}
}

export default new SppModelGetCommand();
16 changes: 13 additions & 3 deletions src/utils/spp.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
import request, { CliRequestOptions } from '../request.js';

export interface SppModel {
ConfidenceScore?: string;
Explanations?: string;
Schemas?: string;
UniqueId: string;
Publications?: any[];
ModelSettings?: string;
'odata.null'?: boolean;
}

export const spp = {
/**
* Asserts whether the specified site is a content center.
* @param siteUrl The URL of the site to check.
* @throws Error when the site is not a content center.
* Asserts whether the specified site is a content center
* @param siteUrl The URL of the site to check
* @throws error when site is not a content center.
*/
async assertSiteIsContentCenter(siteUrl: string): Promise<void> {
const requestOptions: CliRequestOptions = {
Expand Down

0 comments on commit 7d3db71

Please sign in to comment.