/*
* Copyright (C) 2018 Intel Corporation
* SPDX-License-Identifier: MIT
*/
/* global
require:false
*/
/**
* External API which should be used by for development
* @module API
*/
(() => {
const PluginRegistry = require('./plugins');
const User = require('./user');
const ObjectState = require('./object-state');
const Statistics = require('./statistics');
const { Job, Task } = require('./session');
const { Attribute, Label } = require('./labels');
const {
ShareFileType,
TaskStatus,
TaskMode,
AttributeType,
ObjectType,
ObjectShape,
LogType,
EventType,
} = require('./enums');
const {
Exception,
ArgumentError,
DataError,
ScriptingError,
PluginError,
ServerError,
} = require('./exceptions');
const pjson = require('../package.json');
const clientID = +Date.now().toString().substr(-6);
/**
* API entrypoint
* @namespace cvat
* @memberof module:API
*/
const cvat = {
/**
* Namespace is used for an interaction with a server
* @namespace server
* @package
* @memberof module:API.cvat
*/
server: {
/**
* @typedef {Object} ServerInfo
* @property {string} name A name of the tool
* @property {string} description A description of the tool
* @property {string} version A version of the tool
* @global
*/
/**
* Method returns some information about the annotation tool
* @method about
* @async
* @memberof module:API.cvat.server
* @return {ServerInfo}
* @throws {module:API.cvat.exceptions.ServerError}
* @throws {module:API.cvat.exceptions.PluginError}
*/
async about() {
const result = await PluginRegistry
.apiWrapper(cvat.server.about);
return result;
},
/**
* @typedef {Object} FileInfo
* @property {string} name A name of a file
* @property {module:API.cvat.enums.ShareFileType} type
* A type of a file
* @global
*/
/**
* Method returns a list of files in a specified directory on a share
* @method share
* @async
* @memberof module:API.cvat.server
* @param {string} [directory=/] - Share directory path
* @returns {FileInfo[]}
* @throws {module:API.cvat.exceptions.PluginError}
* @throws {module:API.cvat.exceptions.ServerError}
*/
async share(directory = '/') {
const result = await PluginRegistry
.apiWrapper(cvat.server.share, directory);
return result;
},
/**
* Method allows to login on a server
* @method login
* @async
* @memberof module:API.cvat.server
* @param {string} username An username of an account
* @param {string} password A password of an account
* @throws {module:API.cvat.exceptions.ScriptingError}
* @throws {module:API.cvat.exceptions.PluginError}
* @throws {module:API.cvat.exceptions.ServerError}
*/
async login(username, password) {
const result = await PluginRegistry
.apiWrapper(cvat.server.login, username, password);
return result;
},
/**
* Method allows to logout from the server
* @method logout
* @async
* @memberof module:API.cvat.server
* @throws {module:API.cvat.exceptions.PluginError}
* @throws {module:API.cvat.exceptions.ServerError}
*/
async logout() {
const result = await PluginRegistry
.apiWrapper(cvat.server.logout);
return result;
},
},
/**
* Namespace is used for getting tasks
* @namespace tasks
* @memberof module:API.cvat
*/
tasks: {
/**
* @typedef {Object} TaskFilter
* @property {string} name Check if name contains this value
* @property {module:API.cvat.enums.TaskStatus} status
* Check if status contains this value
* @property {module:API.cvat.enums.TaskMode} mode
* Check if mode contains this value
* @property {integer} id Check if id equals this value
* @property {integer} page Get specific page
* (default REST API returns 20 tasks per request.
* In order to get more, it is need to specify next page)
* @property {string} owner Check if owner user contains this value
* @property {string} assignee Check if assigneed contains this value
* @property {string} search Combined search of contains among all fields
* @global
*/
/**
* Method returns list of tasks corresponding to a filter
* @method get
* @async
* @memberof module:API.cvat.tasks
* @param {TaskFilter} [filter={}] task filter
* @returns {module:API.cvat.classes.Task[]}
* @throws {module:API.cvat.exceptions.PluginError}
* @throws {module:API.cvat.exceptions.ServerError}
*/
async get(filter = {}) {
const result = await PluginRegistry
.apiWrapper(cvat.tasks.get, filter);
return result;
},
},
/**
* Namespace is used for getting jobs
* @namespace jobs
* @memberof module:API.cvat
*/
jobs: {
/**
* @typedef {Object} JobFilter
* Only one of fields is allowed simultaneously
* @property {integer} taskID filter all jobs of specific task
* @property {integer} jobID filter job with a specific id
* @global
*/
/**
* Method returns list of jobs corresponding to a filter
* @method get
* @async
* @memberof module:API.cvat.jobs
* @param {JobFilter} filter job filter
* @returns {module:API.cvat.classes.Job[]}
* @throws {module:API.cvat.exceptions.PluginError}
* @throws {module:API.cvat.exceptions.ServerError}
*/
async get(filter = {}) {
const result = await PluginRegistry
.apiWrapper(cvat.jobs.get, filter);
return result;
},
},
/**
* Namespace is used for getting users
* @namespace users
* @memberof module:API.cvat
*/
users: {
/**
* @typedef {Object} UserFilter
* @property {boolean} self get only self
* @global
*/
/**
* Method returns list of users corresponding to a filter
* @method get
* @async
* @memberof module:API.cvat.users
* @param {UserFilter} [filter={}] user filter
* @returns {User[]}
* @throws {module:API.cvat.exceptions.PluginError}
* @throws {module:API.cvat.exceptions.ServerError}
*/
async get(filter = {}) {
const result = await PluginRegistry
.apiWrapper(cvat.users.get, filter);
return result;
},
},
/**
* Namespace is used for plugin management
* @namespace plugins
* @memberof module:API.cvat
*/
plugins: {
/**
* @typedef {Object} Plugin
* A plugin is a Javascript object. It must have properties are listed below.
* It also mustn't have property 'functions' which is used internally.
* You can expand any API method including class methods.
* In order to expand class method just use a class name
* in a cvat space (example is listed below).
*
* @property {string} name A name of a plugin
* @property {string} description A description of a plugin
* Example plugin implementation listed below:
* @example
* plugin = {
* name: 'Example Plugin',
* description: 'This example plugin demonstrates how plugin system in CVAT works',
* cvat: {
* server: {
* about: {
* // Plugin adds some actions after executing the cvat.server.about()
* // For example it adds a field with installed plugins to a result
* // An argument "self" is a plugin itself
* // An argument "result" is a return value of cvat.server.about()
* // All next arguments are arguments of a wrapped function
* // (in this case the wrapped function doesn't have any arguments)
* async leave(self, result) {
* result.plugins = await self.internal.getPlugins();
* // Note that a method leave must return "result" (changed or not)
* // Otherwise API won't work as expected
* return result;
* },
* },
* },
* // In this example plugin also wraps a class method
* classes: {
* Job: {
* prototype: {
* annotations: {
* put: {
* // The first argument "self" is a plugin, like in a case above
* // The second argument is an argument of the
* // cvat.Job.annotations.put()
* // It contains an array of objects to put
* // In this sample we round objects coordinates and save them
* enter(self, objects) {
* for (const obj of objects) {
* if (obj.type != 'tag') {
* const points = obj.position.map((point) => {
* const roundPoint = {
* x: Math.round(point.x),
* y: Math.round(point.y),
* };
* return roundPoint;
* });
* }
* }
* },
* },
* },
* },
* },
* },
* },
* // In general you can add any others members to your plugin
* // Members below are only examples
* internal: {
* async getPlugins() {
* // Collect information about installed plugins
* const plugins = await window.cvat.plugins.list();
* return plugins.map((el) => {
* return {
* name: el.name,
* description: el.description,
* };
* });
* },
* },
* };
* @global
*/
/**
* Method returns list of installed plugins
* @method list
* @async
* @memberof module:API.cvat.plugins
* @returns {Plugin[]}
* @throws {module:API.cvat.exceptions.PluginError}
*/
async list() {
const result = await PluginRegistry
.apiWrapper(cvat.plugins.list);
return result;
},
/**
* Install plugin to CVAT
* @method register
* @async
* @memberof module:API.cvat.plugins
* @param {Plugin} [plugin] plugin for registration
* @throws {module:API.cvat.exceptions.PluginError}
*/
async register(plugin) {
const result = await PluginRegistry
.apiWrapper(cvat.plugins.register, plugin);
return result;
},
},
/**
* Namespace contains some changeable configurations
* @namespace config
* @memberof module:API.cvat
*/
config: {
/**
* @memberof module:API.cvat.config
* @property {string} backendAPI host with a backend api
* @memberof module:API.cvat.config
* @property {string} proxy Axios proxy settings.
* For more details please read here
* @memberof module:API.cvat.config
* @property {integer} taskID this value is displayed in a logs if available
* @memberof module:API.cvat.config
* @property {integer} jobID this value is displayed in a logs if available
* @memberof module:API.cvat.config
* @property {integer} clientID read only auto-generated
* value which is displayed in a logs
* @memberof module:API.cvat.config
*/
backendAPI: 'http://localhost:7000/api/v1',
proxy: false,
taskID: undefined,
jobID: undefined,
clientID: {
get: () => clientID,
},
},
/**
* Namespace contains some library information e.g. api version
* @namespace client
* @memberof module:API.cvat
*/
client: {
/**
* @property {string} version Client version.
* Format: {major}.{minor}.{patch}
*