mirror of
https://github.com/clearml/clearml-web
synced 2025-06-26 18:27:02 +00:00
Pipeline compile and run API integration
This commit is contained in:
parent
6979ce795e
commit
c8e15e6f98
@ -44,6 +44,8 @@ import {
|
|||||||
PipelinesGetByIdResponse,
|
PipelinesGetByIdResponse,
|
||||||
PipelinesUpdateRequest,
|
PipelinesUpdateRequest,
|
||||||
PipelinesUpdateResponse,
|
PipelinesUpdateResponse,
|
||||||
|
PipelinesCompileRequest,
|
||||||
|
PipelinesRunRequest,
|
||||||
} from "../model/pipelines/models";
|
} from "../model/pipelines/models";
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@ -356,7 +358,7 @@ export class ApiPipelinesService {
|
|||||||
): Observable<any> {
|
): Observable<any> {
|
||||||
if (request === null || request === undefined) {
|
if (request === null || request === undefined) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"Required parameter request was null or undefined when calling projectsUpdate."
|
"Required parameter request was null or undefined when calling pipelinesUpdate."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -393,6 +395,98 @@ export class ApiPipelinesService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public pipelinesCompile(
|
||||||
|
request: PipelinesCompileRequest,
|
||||||
|
options?: any,
|
||||||
|
observe: any = "body",
|
||||||
|
reportProgress: boolean = false
|
||||||
|
): Observable<any> {
|
||||||
|
if (request === null || request === undefined) {
|
||||||
|
throw new Error(
|
||||||
|
"Required parameter request was null or undefined when calling pipelinesCompile."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let headers = this.defaultHeaders;
|
||||||
|
if (options && options.async_enable) {
|
||||||
|
headers = headers.set(this.configuration.asyncHeader, "1");
|
||||||
|
}
|
||||||
|
|
||||||
|
// to determine the Accept header
|
||||||
|
const httpHeaderAccepts: string[] = ["application/json"];
|
||||||
|
const httpHeaderAcceptSelected: string | undefined =
|
||||||
|
this.configuration.selectHeaderAccept(httpHeaderAccepts);
|
||||||
|
if (httpHeaderAcceptSelected != undefined) {
|
||||||
|
headers = headers.set("Accept", httpHeaderAcceptSelected);
|
||||||
|
}
|
||||||
|
|
||||||
|
// to determine the Content-Type header
|
||||||
|
const consumes: string[] = [];
|
||||||
|
const httpContentTypeSelected: string | undefined =
|
||||||
|
this.configuration.selectHeaderContentType(consumes);
|
||||||
|
if (httpContentTypeSelected != undefined) {
|
||||||
|
headers = headers.set("Content-Type", httpContentTypeSelected);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.apiRequest.post<unknown>(
|
||||||
|
`${this.basePath}/pipelines.compile`,
|
||||||
|
request,
|
||||||
|
{
|
||||||
|
withCredentials: this.configuration.withCredentials,
|
||||||
|
headers: headers,
|
||||||
|
observe: observe,
|
||||||
|
reportProgress: reportProgress,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public pipelinesRun(
|
||||||
|
request: PipelinesRunRequest,
|
||||||
|
options?: any,
|
||||||
|
observe: any = "body",
|
||||||
|
reportProgress: boolean = false
|
||||||
|
): Observable<any> {
|
||||||
|
if (request === null || request === undefined) {
|
||||||
|
throw new Error(
|
||||||
|
"Required parameter request was null or undefined when calling pipelinesRun."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let headers = this.defaultHeaders;
|
||||||
|
if (options && options.async_enable) {
|
||||||
|
headers = headers.set(this.configuration.asyncHeader, "1");
|
||||||
|
}
|
||||||
|
|
||||||
|
// to determine the Accept header
|
||||||
|
const httpHeaderAccepts: string[] = ["application/json"];
|
||||||
|
const httpHeaderAcceptSelected: string | undefined =
|
||||||
|
this.configuration.selectHeaderAccept(httpHeaderAccepts);
|
||||||
|
if (httpHeaderAcceptSelected != undefined) {
|
||||||
|
headers = headers.set("Accept", httpHeaderAcceptSelected);
|
||||||
|
}
|
||||||
|
|
||||||
|
// to determine the Content-Type header
|
||||||
|
const consumes: string[] = [];
|
||||||
|
const httpContentTypeSelected: string | undefined =
|
||||||
|
this.configuration.selectHeaderContentType(consumes);
|
||||||
|
if (httpContentTypeSelected != undefined) {
|
||||||
|
headers = headers.set("Content-Type", httpContentTypeSelected);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.apiRequest.post<unknown>(
|
||||||
|
`${this.basePath}/pipelines.run`,
|
||||||
|
request,
|
||||||
|
{
|
||||||
|
withCredentials: this.configuration.withCredentials,
|
||||||
|
headers: headers,
|
||||||
|
observe: observe,
|
||||||
|
reportProgress: reportProgress,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
|
@ -9,5 +9,7 @@ export * from '././pipelinesGetByIdRequest';
|
|||||||
export * from '././pipelinesGetByIdResponse';
|
export * from '././pipelinesGetByIdResponse';
|
||||||
export * from '././pipelinesUpdateRequest';
|
export * from '././pipelinesUpdateRequest';
|
||||||
export * from '././pipelinesUpdateResponse';
|
export * from '././pipelinesUpdateResponse';
|
||||||
|
export * from '././pipelinesCompileRequest';
|
||||||
|
export * from '././pipelinesRunRequest';
|
||||||
|
|
||||||
export * from "././pipeline";
|
export * from "././pipeline";
|
@ -15,10 +15,19 @@ import { PipelinesParameter } from './pipelinesParameter';
|
|||||||
* Do not edit the class manually.
|
* Do not edit the class manually.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
interface PipelineNode {
|
||||||
|
id?:string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PipelineEdge {
|
||||||
|
source?: string;
|
||||||
|
target?: string
|
||||||
|
}
|
||||||
|
|
||||||
interface FlowDisplay {
|
interface FlowDisplay {
|
||||||
|
|
||||||
nodes?: Array<unknown>;
|
nodes?: Array<PipelineNode>;
|
||||||
edges?: Array<unknown>
|
edges?: Array<PipelineEdge>
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Pipeline {
|
export interface Pipeline {
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
|
||||||
|
export interface PipelinesCompileRequest {
|
||||||
|
pipeline_id?: string;
|
||||||
|
steps?: Array<{nodeName:string}>;
|
||||||
|
connections?: Array<{startNodeName:string, endNodeName: string}>;
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
|
||||||
|
export interface PipelinesRunRequest {
|
||||||
|
pipeline_id: string;
|
||||||
|
}
|
@ -37,13 +37,13 @@
|
|||||||
<button class="btn btn-icon g-btn" smTooltip="Save pipeline" (click)="savePipelineClicked()">
|
<button class="btn btn-icon g-btn" smTooltip="Save pipeline" (click)="savePipelineClicked()">
|
||||||
<i class="icon i-pipeline-save lm"></i>
|
<i class="icon i-pipeline-save lm"></i>
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-icon g-btn" smTooltip="Compile pipeline">
|
<button class="btn btn-icon g-btn" smTooltip="Compile pipeline" (click)="compile()">
|
||||||
<i class="icon i-pipeline-compile lm"></i>
|
<i class="icon i-pipeline-compile lm"></i>
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-icon g-btn" smTooltip="Add new step to pipeline" (click)="addNewStep()">
|
<button class="btn btn-icon g-btn" smTooltip="Add new step to pipeline" (click)="addNewStep()">
|
||||||
<i class="icon i-pipeline-add-new-step lm"></i>
|
<i class="icon i-pipeline-add-new-step lm"></i>
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-icon g-btn" smTooltip="Run pipeline">
|
<button class="btn btn-icon g-btn" smTooltip="Run pipeline" (click)="run()">
|
||||||
<i class="icon i-play lm"></i>
|
<i class="icon i-play lm"></i>
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-icon g-btn" smTooltip="Pipeline settings" (click)="settings()">
|
<button class="btn btn-icon g-btn" smTooltip="Pipeline settings" (click)="settings()">
|
||||||
|
@ -30,8 +30,8 @@ export class EditPipelineHeaderComponent extends BaseEntityHeaderComponent imple
|
|||||||
@Output() createPipelineStep = new EventEmitter();
|
@Output() createPipelineStep = new EventEmitter();
|
||||||
@Output() settingsPipelineAction = new EventEmitter();
|
@Output() settingsPipelineAction = new EventEmitter();
|
||||||
@Output() savePipeline = new EventEmitter();
|
@Output() savePipeline = new EventEmitter();
|
||||||
// @Output() selectedTableColsChanged = new EventEmitter<ISmCol>();
|
@Output() compilePipeline = new EventEmitter();
|
||||||
// @Output() removeColFromList = new EventEmitter<ISmCol['id']>();
|
@Output() runPipeline = new EventEmitter();
|
||||||
// @Output() getMetricsToDisplay = new EventEmitter();
|
// @Output() getMetricsToDisplay = new EventEmitter();
|
||||||
// @Output() selectedMetricToShow = new EventEmitter<SelectionEvent>();
|
// @Output() selectedMetricToShow = new EventEmitter<SelectionEvent>();
|
||||||
// @Output() selectedHyperParamToShow = new EventEmitter<{param: string; addCol: boolean}>();
|
// @Output() selectedHyperParamToShow = new EventEmitter<{param: string; addCol: boolean}>();
|
||||||
@ -61,4 +61,10 @@ export class EditPipelineHeaderComponent extends BaseEntityHeaderComponent imple
|
|||||||
savePipelineClicked() {
|
savePipelineClicked() {
|
||||||
this.savePipeline.emit();
|
this.savePipeline.emit();
|
||||||
}
|
}
|
||||||
|
compile() {
|
||||||
|
this.compilePipeline.emit();
|
||||||
|
}
|
||||||
|
run() {
|
||||||
|
this.runPipeline.emit()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
(settingsPipelineAction)="settings()"
|
(settingsPipelineAction)="settings()"
|
||||||
(createPipelineStep)="createPipelineStep()"
|
(createPipelineStep)="createPipelineStep()"
|
||||||
(savePipeline)="savePipeline()"
|
(savePipeline)="savePipeline()"
|
||||||
|
(compilePipeline)="compilePipeline()"
|
||||||
|
(runPipeline)="runPipeline()"
|
||||||
[pipelineData]="selectedPipeline"
|
[pipelineData]="selectedPipeline"
|
||||||
>
|
>
|
||||||
</sm-edit-pipeline-header>
|
</sm-edit-pipeline-header>
|
||||||
|
@ -3,12 +3,12 @@ import { PipelineAddStepDialogComponent } from '../pipeline-add-step-dialog/pipe
|
|||||||
import { PipelineSettingComponent } from '../pipeline-setting/pipeline-setting.component';
|
import { PipelineSettingComponent } from '../pipeline-setting/pipeline-setting.component';
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
import { Store } from '@ngrx/store';
|
import { Store } from '@ngrx/store';
|
||||||
import { createPipelineStep, settingsPipelineAction, getPipelineById, resetPipelines, resetPipelinesSearchQuery, updatePipeline } from '../pipelines.actions';
|
import { createPipelineStep, settingsPipelineAction, getPipelineById, resetPipelines, resetPipelinesSearchQuery, updatePipeline, compilePipeline, runPipeline } from '../pipelines.actions';
|
||||||
import { selectRouterParams } from '@common/core/reducers/router-reducer';
|
import { selectRouterParams } from '@common/core/reducers/router-reducer';
|
||||||
import { Observable, Subscription, map } from 'rxjs';
|
import { Observable, Subscription, map } from 'rxjs';
|
||||||
import { Params } from '@angular/router';
|
import { Params } from '@angular/router';
|
||||||
import { selectSelectedPipeline } from '../pipelines.reducer';
|
import { selectSelectedPipeline } from '../pipelines.reducer';
|
||||||
import { Pipeline } from '~/business-logic/model/pipelines/models';
|
import { Pipeline, PipelinesCompileRequest } from '~/business-logic/model/pipelines/models';
|
||||||
import { cloneDeep } from 'lodash-es';
|
import { cloneDeep } from 'lodash-es';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -67,6 +67,32 @@ export class EditPipelinePageComponent implements OnInit, OnDestroy {
|
|||||||
pipelineState.flow_display.edges = this.reactFlowState.edges;
|
pipelineState.flow_display.edges = this.reactFlowState.edges;
|
||||||
this.store.dispatch(updatePipeline({changes: {...pipelineState}}));
|
this.store.dispatch(updatePipeline({changes: {...pipelineState}}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
compilePipeline () {
|
||||||
|
let requestPayload: PipelinesCompileRequest = {
|
||||||
|
pipeline_id: this.selectedPipeline.id,
|
||||||
|
steps: this.selectedPipeline.flow_display.nodes.map((nodeItem) => {
|
||||||
|
return {
|
||||||
|
nodeName: nodeItem?.id
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
connections: this.selectedPipeline.flow_display.edges.map((edgeItem) => {
|
||||||
|
return {
|
||||||
|
startNodeName: edgeItem.source,
|
||||||
|
endNodeName: edgeItem.target,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
this.store.dispatch(compilePipeline({data: requestPayload}))
|
||||||
|
}
|
||||||
|
|
||||||
|
runPipeline () {
|
||||||
|
this.store.dispatch(runPipeline({data: {
|
||||||
|
pipeline_id: this.selectedPipeline.id
|
||||||
|
}}))
|
||||||
|
}
|
||||||
|
|
||||||
createPipelineStep() {
|
createPipelineStep() {
|
||||||
|
|
||||||
this.dialog.open(PipelineAddStepDialogComponent, {
|
this.dialog.open(PipelineAddStepDialogComponent, {
|
||||||
@ -89,6 +115,7 @@ export class EditPipelinePageComponent implements OnInit, OnDestroy {
|
|||||||
// });
|
// });
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
settings() {
|
settings() {
|
||||||
this.dialog.open(PipelineSettingComponent, {
|
this.dialog.open(PipelineSettingComponent, {
|
||||||
data: {defaultExperimentId: ''},
|
data: {defaultExperimentId: ''},
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import {createAction, props} from '@ngrx/store';
|
import {createAction, props} from '@ngrx/store';
|
||||||
// import {ReportsGetAllExResponse} from '~/business-logic/model/reports/reportsGetAllExResponse';
|
// import {ReportsGetAllExResponse} from '~/business-logic/model/reports/reportsGetAllExResponse';
|
||||||
// import {IReport} from './reports.consts';
|
// import {IReport} from './reports.consts';
|
||||||
import { Pipeline, PipelinesCreateRequest, PipelinesUpdateRequest, PipelinesUpdateResponse, pipelinesSettingsModel } from '~/business-logic/model/pipelines/models';
|
import { Pipeline, PipelinesCompileRequest, PipelinesCreateRequest, PipelinesRunRequest, PipelinesUpdateRequest, PipelinesUpdateResponse, pipelinesSettingsModel } from '~/business-logic/model/pipelines/models';
|
||||||
import { PipelinesCreateStepsRequest } from '~/business-logic/model/pipelines/pipelinesCreateStepsRequest';
|
import { PipelinesCreateStepsRequest } from '~/business-logic/model/pipelines/pipelinesCreateStepsRequest';
|
||||||
import { TasksGetByIdRequest } from '~/business-logic/model/tasks/models';
|
import { TasksGetByIdRequest } from '~/business-logic/model/tasks/models';
|
||||||
import { Task } from '~/business-logic/model/tasks/task';
|
import { Task } from '~/business-logic/model/tasks/task';
|
||||||
@ -42,6 +42,17 @@ export const updatePipelineSuccess = createAction(
|
|||||||
props<{changes: Partial<PipelinesUpdateResponse>}>()
|
props<{changes: Partial<PipelinesUpdateResponse>}>()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
export const compilePipeline = createAction(
|
||||||
|
PIPELINES_PREFIX + 'COMPILE_PIPELINE',
|
||||||
|
props<{data: Partial<PipelinesCompileRequest>}>()
|
||||||
|
);
|
||||||
|
|
||||||
|
export const runPipeline = createAction(
|
||||||
|
PIPELINES_PREFIX + 'RUN_PIPELINE',
|
||||||
|
props<{data: PipelinesRunRequest}>()
|
||||||
|
);
|
||||||
|
|
||||||
export const getExperimentById = createAction(
|
export const getExperimentById = createAction(
|
||||||
PIPELINES_PREFIX + 'GET_EXPERIMENTS_BY_ID',
|
PIPELINES_PREFIX + 'GET_EXPERIMENTS_BY_ID',
|
||||||
props<{ getExperimentByIdRequest: TasksGetByIdRequest }>()
|
props<{ getExperimentByIdRequest: TasksGetByIdRequest }>()
|
||||||
|
@ -6,7 +6,7 @@ import {catchError, filter, map, mergeMap, switchMap, /* tap */} from 'rxjs/oper
|
|||||||
import {activeLoader, addMessage, /* addMessage, */ deactivateLoader, setServerError} from '../core/actions/layout.actions';
|
import {activeLoader, addMessage, /* addMessage, */ deactivateLoader, setServerError} from '../core/actions/layout.actions';
|
||||||
import {requestFailed} from '../core/actions/http.actions';
|
import {requestFailed} from '../core/actions/http.actions';
|
||||||
import {settingsPipelineAction,
|
import {settingsPipelineAction,
|
||||||
createPipeline, createPipelineStep, getAllExperiments, getExperimentById, getPipelineById, setExperimentsResults, setSelectedPipeline, updatePipeline, updatePipelineSuccess
|
createPipeline, createPipelineStep, getAllExperiments, getExperimentById, getPipelineById, setExperimentsResults, setSelectedPipeline, updatePipeline, updatePipelineSuccess, compilePipeline, runPipeline
|
||||||
} from './pipelines.actions';
|
} from './pipelines.actions';
|
||||||
// import {ApiReportsService} from '~/business-logic/api-services/reports.service';
|
// import {ApiReportsService} from '~/business-logic/api-services/reports.service';
|
||||||
/* import {IReport, PAGE_SIZE} from './reports.consts';
|
/* import {IReport, PAGE_SIZE} from './reports.consts';
|
||||||
@ -288,6 +288,45 @@ export class PipelinesEffects {
|
|||||||
)
|
)
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
||||||
|
compilePipeline = createEffect(() => this.actions.pipe(
|
||||||
|
ofType(compilePipeline),
|
||||||
|
mergeMap(action => this.pipelinesApiService.pipelinesCompile({...action.data})
|
||||||
|
.pipe(
|
||||||
|
// eslint-disable-next-line @ngrx/no-multiple-actions-in-effects
|
||||||
|
mergeMap(() => [
|
||||||
|
deactivateLoader(action.type),
|
||||||
|
addMessage(MESSAGES_SEVERITY.SUCCESS, 'Pipeline compiled successfully')
|
||||||
|
]),
|
||||||
|
catchError(error => [deactivateLoader(action.type), requestFailed(error),
|
||||||
|
/* setServerError(error, undefined, error?.error?.meta?.result_subcode === 800 ?
|
||||||
|
'Name should be 3 characters long' : error?.error?.meta?.result_subcode === 801 ? 'Name' +
|
||||||
|
' already' +
|
||||||
|
' exists in this pipeline' : undefined) */])
|
||||||
|
)
|
||||||
|
)
|
||||||
|
));
|
||||||
|
|
||||||
|
|
||||||
|
runPipeline = createEffect(() => this.actions.pipe(
|
||||||
|
ofType(runPipeline),
|
||||||
|
mergeMap(action => this.pipelinesApiService.pipelinesRun({...action.data})
|
||||||
|
.pipe(
|
||||||
|
// eslint-disable-next-line @ngrx/no-multiple-actions-in-effects
|
||||||
|
mergeMap(() => [
|
||||||
|
deactivateLoader(action.type),
|
||||||
|
addMessage(MESSAGES_SEVERITY.SUCCESS, 'Started running pipeline.')
|
||||||
|
]),
|
||||||
|
catchError(error => [deactivateLoader(action.type), requestFailed(error),
|
||||||
|
/* setServerError(error, undefined, error?.error?.meta?.result_subcode === 800 ?
|
||||||
|
'Name should be 3 characters long' : error?.error?.meta?.result_subcode === 801 ? 'Name' +
|
||||||
|
' already' +
|
||||||
|
' exists in this pipeline' : undefined) */])
|
||||||
|
)
|
||||||
|
)
|
||||||
|
));
|
||||||
|
|
||||||
|
|
||||||
getPipelineById$ = createEffect(() => this.actions.pipe(
|
getPipelineById$ = createEffect(() => this.actions.pipe(
|
||||||
ofType(getPipelineById),
|
ofType(getPipelineById),
|
||||||
switchMap((action) => this.pipelinesApiService.pipelinesGetById({
|
switchMap((action) => this.pipelinesApiService.pipelinesGetById({
|
||||||
|
Loading…
Reference in New Issue
Block a user