Skip to content

Commit

Permalink
Requests page (#8095)
Browse files Browse the repository at this point in the history
This PR introduces new page with information about data
processing(status and progress). For now it will support: task creation,
import/export.

For previous discussions refer to: #7537

Co-authored-by: Maria Khrustaleva <maria@cvat.ai>
Co-authored-by: Boris Sekachev <sekachev.bs@gmail.com>
  • Loading branch information
3 people authored Jul 4, 2024
1 parent b17d293 commit c9f1cff
Show file tree
Hide file tree
Showing 116 changed files with 5,295 additions and 1,917 deletions.
6 changes: 6 additions & 0 deletions changelog.d/20240515_100610_kirill.9992_data_processing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
### Added

- Set of features to track background activities: importing/exporting datasets, annotations or backups, creating tasks.
Now you may find these processes on Requests page, it allows a user to understand current status of these activities
and enhances user experience, not losing progress when the browser tab is closed
(<https://github.com/cvat-ai/cvat/pull/7537>)
2 changes: 1 addition & 1 deletion cvat-core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "cvat-core",
"version": "15.0.7",
"version": "15.1.0",
"type": "module",
"description": "Part of Computer Vision Tool which presents an interface for client-side integration",
"main": "src/api.ts",
Expand Down
6 changes: 3 additions & 3 deletions cvat-core/src/annotations.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (C) 2019-2022 Intel Corporation
// Copyright (C) 2022-2023 CVAT.ai Corporation
// Copyright (C) 2022-2024 CVAT.ai Corporation
//
// SPDX-License-Identifier: MIT

Expand Down Expand Up @@ -168,9 +168,9 @@ export function importDataset(
file: File | string,
options: {
convMaskToPoly?: boolean,
updateStatusCallback?: (s: string, n: number) => void,
updateStatusCallback?: (message: string, progress: number) => void,
} = {},
): Promise<void> {
): Promise<string> {
const updateStatusCallback = options.updateStatusCallback || (() => {});
const convMaskToPoly = 'convMaskToPoly' in options ? options.convMaskToPoly : true;
const adjustedOptions = {
Expand Down
5 changes: 5 additions & 0 deletions cvat-core/src/api-implementation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import config from './config';
import PluginRegistry from './plugins';
import serverProxy from './server-proxy';
import lambdaManager from './lambda-manager';
import requestsManager from './requests-manager';
import {
isBoolean,
isInteger,
Expand Down Expand Up @@ -61,6 +62,10 @@ export default function implementAPI(cvat: CVATCore): CVATCore {
implementationMixin(cvat.lambda.listen, lambdaManager.listen.bind(lambdaManager));
implementationMixin(cvat.lambda.requests, lambdaManager.requests.bind(lambdaManager));

implementationMixin(cvat.requests.list, requestsManager.list.bind(requestsManager));
implementationMixin(cvat.requests.listen, requestsManager.listen.bind(requestsManager));
implementationMixin(cvat.requests.cancel, requestsManager.cancel.bind(requestsManager));

implementationMixin(cvat.server.about, async () => {
const result = await serverProxy.server.about();
return result;
Expand Down
27 changes: 27 additions & 0 deletions cvat-core/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import Organization from './organization';
import Webhook from './webhook';
import AnnotationGuide from './guide';
import BaseSingleFrameAction from './annotations-actions';
import { Request } from './request';

import * as enums from './enums';

Expand Down Expand Up @@ -286,6 +287,12 @@ function build(): CVATCore {
set globalObjectsCounter(value: number) {
config.globalObjectsCounter = value;
},
get requestsStatusDelay() {
return config.requestsStatusDelay;
},
set requestsStatusDelay(value) {
config.requestsStatusDelay = value;
},
},
client: {
version: `${pjson.version}`,
Expand Down Expand Up @@ -374,6 +381,26 @@ function build(): CVATCore {
},
},
},
requests: {
async list() {
const result = await PluginRegistry.apiWrapper(cvat.requests.list);
return result;
},
async cancel(rqID: string) {
const result = await PluginRegistry.apiWrapper(cvat.requests.cancel, rqID);
return result;
},
async listen(
rqID: string,
options: {
callback: (request: Request) => void,
initialRequest?: Request,
},
) {
const result = await PluginRegistry.apiWrapper(cvat.requests.listen, rqID, options);
return result;
},
},
classes: {
User,
Project: implementProject(Project),
Expand Down
2 changes: 2 additions & 0 deletions cvat-core/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ const config = {
},
onOrganizationChange: null,
globalObjectsCounter: 0,

requestsStatusDelay: null,
};

export default config;
4 changes: 3 additions & 1 deletion cvat-core/src/exceptions.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (C) 2019-2022 Intel Corporation
// Copyright (C) 2022 CVAT.ai Corporation
// Copyright (C) 2022-2024 CVAT.ai Corporation
//
// SPDX-License-Identifier: MIT

Expand Down Expand Up @@ -99,6 +99,8 @@ export class DataError extends Exception {}

export class ScriptingError extends Exception {}

export class RequestError extends Exception {}

export class ServerError extends Exception {
public code: number;
constructor(message, code) {
Expand Down
13 changes: 13 additions & 0 deletions cvat-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import QualityConflict from './quality-conflict';
import QualitySettings from './quality-settings';
import AnalyticsReport from './analytics-report';
import AnnotationGuide from './guide';
import { Request } from './request';
import BaseSingleFrameAction, { listActions, registerAction, runActions } from './annotations-actions';
import {
ArgumentError, DataError, Exception, ScriptingError, ServerError,
Expand Down Expand Up @@ -150,6 +151,17 @@ export default interface CVATCore {
frames: {
getMeta: any;
};
requests: {
list: () => Promise<PaginatedResource<Request>>;
listen: (
rqID: string,
options: {
callback: (request: Request) => void,
initialRequest?: Request,
}
) => Promise<Request>;
cancel: (rqID: string) => Promise<void>;
};
actions: {
list: typeof listActions;
register: typeof registerAction;
Expand All @@ -166,6 +178,7 @@ export default interface CVATCore {
};
onOrganizationChange: (newOrgId: number | null) => void | null;
globalObjectsCounter: typeof config.globalObjectsCounter;
requestsStatusDelay: typeof config.requestsStatusDelay;
},
client: {
version: string;
Expand Down
20 changes: 11 additions & 9 deletions cvat-core/src/project-implementation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,39 +107,42 @@ export default function implementProject(Project: typeof ProjectClass): typeof P
});

Object.defineProperty(Project.prototype.annotations.exportDataset, 'implementation', {
value: function exportDatasetImplementation(
value: async function exportDatasetImplementation(
this: ProjectClass,
format: Parameters<typeof ProjectClass.prototype.annotations.exportDataset>[0],
saveImages: Parameters<typeof ProjectClass.prototype.annotations.exportDataset>[1],
useDefaultSettings: Parameters<typeof ProjectClass.prototype.annotations.exportDataset>[2],
targetStorage: Parameters<typeof ProjectClass.prototype.annotations.exportDataset>[3],
customName: Parameters<typeof ProjectClass.prototype.annotations.exportDataset>[4],
): ReturnType<typeof ProjectClass.prototype.annotations.exportDataset> {
return exportDataset(this, format, saveImages, useDefaultSettings, targetStorage, customName);
const rqID = await exportDataset(this, format, saveImages, useDefaultSettings, targetStorage, customName);
return rqID;
},
});

Object.defineProperty(Project.prototype.annotations.importDataset, 'implementation', {
value: function importDatasetImplementation(
value: async function importDatasetImplementation(
this: ProjectClass,
format: Parameters<typeof ProjectClass.prototype.annotations.importDataset>[0],
useDefaultSettings: Parameters<typeof ProjectClass.prototype.annotations.importDataset>[1],
sourceStorage: Parameters<typeof ProjectClass.prototype.annotations.importDataset>[2],
file: Parameters<typeof ProjectClass.prototype.annotations.importDataset>[3],
options: Parameters<typeof ProjectClass.prototype.annotations.importDataset>[4],
): ReturnType<typeof ProjectClass.prototype.annotations.importDataset> {
return importDataset(this, format, useDefaultSettings, sourceStorage, file, options);
const rqID = await importDataset(this, format, useDefaultSettings, sourceStorage, file, options);
return rqID;
},
});

Object.defineProperty(Project.prototype.backup, 'implementation', {
value: function backupImplementation(
value: async function backupImplementation(
this: ProjectClass,
targetStorage: Parameters<typeof ProjectClass.prototype.backup>[0],
useDefaultSettings: Parameters<typeof ProjectClass.prototype.backup>[1],
fileName: Parameters<typeof ProjectClass.prototype.backup>[2],
): ReturnType<typeof ProjectClass.prototype.backup> {
return serverProxy.projects.backup(this.id, targetStorage, useDefaultSettings, fileName);
const rqID = await serverProxy.projects.backup(this.id, targetStorage, useDefaultSettings, fileName);
return rqID;
},
});

Expand All @@ -149,9 +152,8 @@ export default function implementProject(Project: typeof ProjectClass): typeof P
storage: Parameters<typeof ProjectClass.restore>[0],
file: Parameters<typeof ProjectClass.restore>[1],
): ReturnType<typeof ProjectClass.restore> {
const serializedProject = await serverProxy.projects.restore(storage, file);
const labels = await serverProxy.labels.get({ project_id: serializedProject.id });
return new Project({ ...serializedProject, labels: labels.results });
const rqID = await serverProxy.projects.restore(storage, file);
return rqID;
},
});

Expand Down
4 changes: 2 additions & 2 deletions cvat-core/src/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export default class Project {
convMaskToPoly?: boolean,
updateStatusCallback?: (s: string, n: number) => void,
},
) => Promise<void>;
) => Promise<string>;
};

constructor(initialData: Readonly<SerializedProject & { labels?: SerializedLabel[] }>) {
Expand Down Expand Up @@ -246,7 +246,7 @@ export default class Project {
return result;
}

static async restore(storage: Storage, file: File | string): Promise<Project> {
static async restore(storage: Storage, file: File | string): Promise<string> {
const result = await PluginRegistry.apiWrapper.call(this, Project.restore, storage, file);
return result;
}
Expand Down
105 changes: 105 additions & 0 deletions cvat-core/src/request.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
// Copyright (C) 2024 CVAT.ai Corporation
//
// SPDX-License-Identifier: MIT

import { RQStatus } from './enums';
import User from './user';
import { SerializedRequest } from './server-response-types';

type Operation = {
target: string;
type: string;
format: string;
jobID: number | null;
taskID: number | null;
projectID: number | null;
};

export class Request {
#id: string;
#status: RQStatus;
#operation: Partial<SerializedRequest['operation']>;
#message: string;
#progress: number;
#resultUrl: string;
#resultID: number;
#createdDate: string;
#startedDate: string;
#finishedDate: string;
#expiryDate: string;
#owner: User;

constructor(initialData: SerializedRequest) {
this.#id = initialData.id;
this.#status = initialData.status as RQStatus;
this.#operation = initialData.operation;
this.#progress = initialData.progress;
this.#message = initialData.message;
this.#resultUrl = initialData.result_url;
this.#resultID = initialData.result_id;

this.#createdDate = initialData.created_date;
this.#startedDate = initialData.started_date;
this.#finishedDate = initialData.finished_date;
this.#expiryDate = initialData.expiry_date;

if (initialData.owner) {
this.#owner = new User(initialData.owner);
}
}

get id(): string {
return this.#id;
}

get status(): RQStatus {
return this.#status.toLowerCase() as RQStatus;
}

get progress(): number {
return this.#progress;
}

get message(): string {
return this.#message;
}

get operation(): Operation {
return {
target: this.#operation.target,
type: this.#operation.type,
format: this.#operation.format,
jobID: this.#operation.job_id,
taskID: this.#operation.task_id,
projectID: this.#operation.project_id,
};
}

get url(): string {
return this.#resultUrl;
}

get resultID(): number {
return this.#resultID;
}

get createdDate(): string {
return this.#createdDate;
}

get startedDate(): string {
return this.#startedDate;
}

get finishedDate(): string {
return this.#finishedDate;
}

get expiryDate(): string {
return this.#expiryDate;
}

get owner(): User {
return this.#owner;
}
}
Loading

0 comments on commit c9f1cff

Please sign in to comment.