Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release v2.21.2 #8591

Merged
merged 18 commits into from
Oct 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,22 @@
"env": {},
"console": "internalConsole"
},
{
"name": "server: sync periodic jobs",
"type": "debugpy",
"request": "launch",
"justMyCode": false,
"stopOnEntry": false,
"python": "${command:python.interpreterPath}",
"program": "${workspaceFolder}/manage.py",
"args": [
"syncperiodicjobs"
],
"django": true,
"cwd": "${workspaceFolder}",
"env": {},
"console": "internalConsole"
},
{
"name": "server: tests",
"type": "debugpy",
Expand Down
34 changes: 34 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,40 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

<!-- scriv-insert-here -->

<a id='changelog-2.21.2'></a>
## \[2.21.2\] - 2024-10-24

### Added

- Access to /analytics can now be granted
(<https://github.com/cvat-ai/cvat/pull/8509>)

### Fixed

- Expired sessions are now cleared from the database daily
(<https://github.com/cvat-ai/cvat/pull/8552>)

- Fixed export/import errors for tracks with duplicated shapes.
Fixed a bug which caused shape duplication on track import.
(<https://github.com/cvat-ai/cvat/pull/8553>)

- Fix Grafana container restart policy
(<https://github.com/cvat-ai/cvat/pull/8577>)

- Fixed some interface tooltips having 'undefined' shortcuts
(<https://github.com/cvat-ai/cvat/pull/8578>)

- Memory consumption during preparation of image chunks
(<https://github.com/cvat-ai/cvat/pull/8581>)

- Fixed a bug where an export RQ job being retried may break scheduling
of new jobs
(<https://github.com/cvat-ai/cvat/pull/8584>)

- UI now allows the user to start automatic annotation again
if the previous request fails
(<https://github.com/cvat-ai/cvat/pull/8587>)

<a id='changelog-2.21.1'></a>
## \[2.21.1\] - 2024-10-18

Expand Down
3 changes: 2 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@

ARG http_proxy
ARG https_proxy
ARG no_proxy="nuclio,${no_proxy}"

Check warning on line 96 in Dockerfile

View workflow job for this annotation

GitHub Actions / build

Variables should be defined before their use

UndefinedVar: Usage of undefined variable '$no_proxy' More info: https://docs.docker.com/go/dockerfile/rule/undefined-var/
ARG socks_proxy
ARG TZ="Etc/UTC"

Expand Down Expand Up @@ -134,6 +134,7 @@
supervisor \
tzdata \
unrar \
wait-for-it \
&& ln -fs /usr/share/zoneinfo/${TZ} /etc/localtime && \
dpkg-reconfigure -f noninteractive tzdata && \
rm -rf /var/lib/apt/lists/* && \
Expand All @@ -144,7 +145,7 @@

# Add a non-root user
ENV USER=${USER}
ENV HOME /home/${USER}

Check warning on line 148 in Dockerfile

View workflow job for this annotation

GitHub Actions / build

Legacy key/value format with whitespace separator should not be used

LegacyKeyValueFormat: "ENV key=value" should be used instead of legacy "ENV key value" format More info: https://docs.docker.com/go/dockerfile/rule/legacy-key-value-format/
RUN adduser --shell /bin/bash --disabled-password --gecos "" ${USER}

ARG CLAM_AV="no"
Expand Down Expand Up @@ -192,7 +193,7 @@
COPY cvat/nginx.conf /etc/nginx/nginx.conf
COPY --chown=${USER} components /tmp/components
COPY --chown=${USER} supervisord/ ${HOME}/supervisord
COPY --chown=${USER} wait-for-it.sh manage.py backend_entrypoint.sh wait_for_deps.sh ${HOME}/
COPY --chown=${USER} manage.py backend_entrypoint.sh wait_for_deps.sh ${HOME}/
COPY --chown=${USER} utils/ ${HOME}/utils
COPY --chown=${USER} cvat/ ${HOME}/cvat
COPY --chown=${USER} rqscheduler.py ${HOME}
Expand Down
5 changes: 4 additions & 1 deletion backend_entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ fail() {
}

wait_for_db() {
~/wait-for-it.sh "${CVAT_POSTGRES_HOST}:${CVAT_POSTGRES_PORT:-5432}" -t 0
wait-for-it "${CVAT_POSTGRES_HOST}:${CVAT_POSTGRES_PORT:-5432}" -t 0
}

cmd_bash() {
Expand All @@ -18,6 +18,9 @@ cmd_bash() {
cmd_init() {
wait_for_db
~/manage.py migrate

wait-for-it "${CVAT_REDIS_INMEM_HOST}:${CVAT_REDIS_INMEM_PORT:-6379}" -t 0
~/manage.py syncperiodicjobs
}

cmd_run() {
Expand Down
2 changes: 1 addition & 1 deletion cvat-cli/requirements/base.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
cvat-sdk~=2.21.1
cvat-sdk~=2.21.2
Pillow>=10.3.0
setuptools>=70.0.0 # not directly required, pinned by Snyk to avoid a vulnerability
2 changes: 1 addition & 1 deletion cvat-cli/src/cvat_cli/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
VERSION = "2.21.1"
VERSION = "2.21.2"
2 changes: 1 addition & 1 deletion cvat-core/src/annotations-collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1295,7 +1295,7 @@ export default class Collection {
const predicate = sign > 0 ? (frame) => frame <= frameTo : (frame) => frame >= frameTo;
const update = sign > 0 ? (frame) => frame + 1 : (frame) => frame - 1;

// if not looking for an emty frame nor frame with annotations, return the next frame
// if not looking for an empty frame nor frame with annotations, return the next frame
// check if deleted frames are allowed additionally
if (!annotationsFilters) {
let frame = frameFrom;
Expand Down
5 changes: 3 additions & 2 deletions cvat-core/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import QualityReport from './quality-report';
import QualityConflict from './quality-conflict';
import QualitySettings from './quality-settings';
import AnalyticsReport from './analytics-report';
import ValidationLayout from './validation-layout';
import { JobValidationLayout, TaskValidationLayout } from './validation-layout';
import { Request } from './request';

import * as enums from './enums';
Expand Down Expand Up @@ -427,7 +427,8 @@ function build(): CVATCore {
QualityReport,
Request,
FramesMetaData,
ValidationLayout,
JobValidationLayout,
TaskValidationLayout,
},
utils: {
mask2Rle,
Expand Down
2 changes: 1 addition & 1 deletion cvat-core/src/cloud-storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ Object.defineProperties(CloudStorage.prototype.save, {
}
// update
if (typeof this.id !== 'undefined') {
// provider_type and recource should not change;
// provider_type and resource should not change;
// send to the server only the values that have changed
const initialData: SerializedCloudStorage = {};
if (this.displayName) {
Expand Down
4 changes: 2 additions & 2 deletions cvat-core/src/frames.ts
Original file line number Diff line number Diff line change
Expand Up @@ -683,7 +683,7 @@ export function getContextImage(jobID: number, frame: number): Promise<Record<st
// it might raise multiple server requests for context images
// if the promise was pending before and several requests came for the same frame
// all these requests will stuck on "finally"
// and when the promise fullfilled, it will run all the microtasks
// and when the promise is fulfilled, it will run all the microtasks
// since they all have the same request id, all they will perform in executor()
frameData.activeContextRequest.finally(() => setTimeout(checkAndExecute));
} else {
Expand Down Expand Up @@ -775,7 +775,7 @@ export async function getFrame(
// - getContextImage
// - getCachedChunks
// And from this idea we should call refreshJobCacheIfOutdated from each one
// Hovewer, following from the order, these methods are usually called
// However, following from the order, these methods are usually called
// it may lead to even more confusing behaviour
//
// Usually user first receives frame, then user receives ranges and finally user receives context images
Expand Down
5 changes: 3 additions & 2 deletions cvat-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import QualityConflict from './quality-conflict';
import QualitySettings from './quality-settings';
import AnalyticsReport from './analytics-report';
import AnnotationGuide from './guide';
import ValidationLayout from './validation-layout';
import { JobValidationLayout, TaskValidationLayout } from './validation-layout';
import { Request } from './request';
import BaseSingleFrameAction, { listActions, registerAction, runActions } from './annotations-actions';
import {
Expand Down Expand Up @@ -216,7 +216,8 @@ export default interface CVATCore {
AnalyticsReport: typeof AnalyticsReport;
Request: typeof Request;
FramesMetaData: typeof FramesMetaData;
ValidationLayout: typeof ValidationLayout;
JobValidationLayout: typeof JobValidationLayout;
TaskValidationLayout: typeof TaskValidationLayout;
};
utils: {
mask2Rle: typeof mask2Rle;
Expand Down
2 changes: 1 addition & 1 deletion cvat-core/src/object-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export function findAngleDiff(rightAngle: number, leftAngle: number): number {
angleDiff = ((angleDiff + 180) % 360) - 180;
if (Math.abs(angleDiff) >= 180) {
// if the main arc is bigger than 180, go another arc
// to find it, just substract absolute value from 360 and inverse sign
// to find it, just subtract absolute value from 360 and inverse sign
angleDiff = 360 - Math.abs(angleDiff) * Math.sign(angleDiff) * -1;
}
return angleDiff;
Expand Down
2 changes: 1 addition & 1 deletion cvat-core/src/requests-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ class RequestsManager {
const promise = new Promise<Request>((resolve, reject) => {
const timeoutCallback = async (): Promise<void> => {
// We make sure that no more than REQUESTS_COUNT requests are sent simultaneously
// If thats the case, we re-schedule the timeout
// If that's the case, we re-schedule the timeout
const timestamp = Date.now();
if (this.requestStack.length >= REQUESTS_COUNT) {
const timestampToCheck = this.requestStack[this.requestStack.length - 1];
Expand Down
6 changes: 3 additions & 3 deletions cvat-core/src/server-proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
SerializedInvitationData, SerializedCloudStorage, SerializedFramesMetaData, SerializedCollection,
SerializedQualitySettingsData, APIQualitySettingsFilter, SerializedQualityConflictData, APIQualityConflictsFilter,
SerializedQualityReportData, APIQualityReportsFilter, SerializedAnalyticsReport, APIAnalyticsReportFilter,
SerializedRequest, SerializedValidationLayout,
SerializedRequest, SerializedJobValidationLayout, SerializedTaskValidationLayout,
} from './server-response-types';
import { PaginatedResource } from './core-types';
import { Request } from './request';
Expand Down Expand Up @@ -102,7 +102,7 @@
}
});

// removing possible dublicates
// removing possible duplicates
const obj = result.results.reduce((acc: Record<string, any>, item: any) => {
acc[item.id] = item;
return acc;
Expand Down Expand Up @@ -244,7 +244,7 @@
return new ServerError(message, 0);
}

function prepareData(details) {

Check warning on line 247 in cvat-core/src/server-proxy.ts

View workflow job for this annotation

GitHub Actions / Linter

Missing return type on function
const data = new FormData();
for (const [key, value] of Object.entries(details)) {
if (Array.isArray(value)) {
Expand Down Expand Up @@ -286,7 +286,7 @@
return requestId++;
}

async function get(url: string, requestConfig) {

Check warning on line 289 in cvat-core/src/server-proxy.ts

View workflow job for this annotation

GitHub Actions / Linter

Missing return type on function
return new Promise((resolve, reject) => {
const newRequestId = getRequestId();
requests[newRequestId] = { resolve, reject };
Expand Down Expand Up @@ -819,7 +819,7 @@
save_images: saveImages,
};
return new Promise<string | void>((resolve, reject) => {
async function request() {

Check warning on line 822 in cvat-core/src/server-proxy.ts

View workflow job for this annotation

GitHub Actions / Linter

Missing return type on function
Axios.post(baseURL, {}, {
params,
})
Expand Down Expand Up @@ -914,7 +914,7 @@
const url = `${backendAPI}/tasks/${id}/backup/export`;

return new Promise<string | void>((resolve, reject) => {
async function request() {

Check warning on line 917 in cvat-core/src/server-proxy.ts

View workflow job for this annotation

GitHub Actions / Linter

Missing return type on function
try {
const response = await Axios.post(url, {}, {
params,
Expand Down Expand Up @@ -996,7 +996,7 @@
const url = `${backendAPI}/projects/${id}/backup/export`;

return new Promise<string | void>((resolve, reject) => {
async function request() {

Check warning on line 999 in cvat-core/src/server-proxy.ts

View workflow job for this annotation

GitHub Actions / Linter

Missing return type on function
try {
const response = await Axios.post(url, {}, {
params,
Expand Down Expand Up @@ -1124,7 +1124,7 @@
message: 'CVAT is uploading task data to the server',
}));

async function bulkUpload(taskId, files) {

Check warning on line 1127 in cvat-core/src/server-proxy.ts

View workflow job for this annotation

GitHub Actions / Linter

Missing return type on function
const fileBulks = files.reduce((fileGroups, file) => {
const lastBulk = fileGroups[fileGroups.length - 1];
if (chunkSize - lastBulk.size >= file.size) {
Expand Down Expand Up @@ -1384,7 +1384,7 @@

const validationLayout = (instance: 'tasks' | 'jobs') => async (
id: number,
): Promise<SerializedValidationLayout | null> => {
): Promise<SerializedJobValidationLayout | SerializedTaskValidationLayout> => {
const { backendAPI } = config;

try {
Expand Down
9 changes: 8 additions & 1 deletion cvat-core/src/server-response-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ export interface SerializedUser {
last_login?: string;
date_joined?: string;
email_verification_required: boolean;
has_analytics_access: boolean;
}

interface SerializedStorage {
Expand Down Expand Up @@ -524,8 +525,14 @@ export interface SerializedRequest {
owner?: any;
}

export interface SerializedValidationLayout {
export interface SerializedJobValidationLayout {
honeypot_count?: number;
honeypot_frames?: number[];
honeypot_real_frames?: number[];
}

export interface SerializedTaskValidationLayout extends SerializedJobValidationLayout {
mode: 'gt' | 'gt_pool' | null;
validation_frames?: number[];
disabled_frames?: number[];
}
19 changes: 11 additions & 8 deletions cvat-core/src/session-implementation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ import {
decodePreview,
} from './frames';
import Issue from './issue';
import { SerializedLabel, SerializedTask, SerializedValidationLayout } from './server-response-types';
import {
SerializedLabel, SerializedTask, SerializedJobValidationLayout,
SerializedTaskValidationLayout,
} from './server-response-types';
import { checkInEnum, checkObjectType } from './common';
import {
getCollection, getSaver, clearAnnotations, getAnnotations,
Expand All @@ -37,7 +40,7 @@ import AnnotationGuide from './guide';
import requestsManager from './requests-manager';
import { Request } from './request';
import User from './user';
import ValidationLayout from './validation-layout';
import { JobValidationLayout, TaskValidationLayout } from './validation-layout';

// must be called with task/job context
async function deleteFrameWrapper(jobID, frame): Promise<void> {
Expand Down Expand Up @@ -171,7 +174,7 @@ export function implementJob(Job: typeof JobClass): typeof JobClass {
): ReturnType<typeof JobClass.prototype.validationLayout> {
const result = await serverProxy.jobs.validationLayout(this.id);
if (Object.keys(result).length) {
return new ValidationLayout(result as Required<SerializedValidationLayout>);
return new JobValidationLayout(result as SerializedJobValidationLayout);
}

return null;
Expand Down Expand Up @@ -374,7 +377,7 @@ export function implementJob(Job: typeof JobClass): typeof JobClass {
}

if ('annotationsFilters' in searchParameters && 'generalFilters' in searchParameters) {
throw new ArgumentError('Both annotations filters and general fiters could not be used together');
throw new ArgumentError('Both annotations filters and general filters could not be used together');
}

if (!Number.isInteger(frameFrom) || !Number.isInteger(frameTo)) {
Expand Down Expand Up @@ -641,9 +644,9 @@ export function implementTask(Task: typeof TaskClass): typeof TaskClass {
value: async function validationLayoutImplementation(
this: TaskClass,
): ReturnType<typeof TaskClass.prototype.validationLayout> {
const result = await serverProxy.tasks.validationLayout(this.id);
if (Object.keys(result).length) {
return new ValidationLayout(result as Required<SerializedValidationLayout>);
const result = await serverProxy.tasks.validationLayout(this.id) as SerializedTaskValidationLayout;
if (result.mode !== null) {
return new TaskValidationLayout(result);
}

return null;
Expand Down Expand Up @@ -1043,7 +1046,7 @@ export function implementTask(Task: typeof TaskClass): typeof TaskClass {
}

if ('annotationsFilters' in searchParameters && 'generalFilters' in searchParameters) {
throw new ArgumentError('Both annotations filters and general fiters could not be used together');
throw new ArgumentError('Both annotations filters and general filters could not be used together');
}

if (!Number.isInteger(frameFrom) || !Number.isInteger(frameTo)) {
Expand Down
6 changes: 3 additions & 3 deletions cvat-core/src/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import { Request } from './request';
import logger from './logger';
import Issue from './issue';
import ObjectState from './object-state';
import ValidationLayout from './validation-layout';
import { JobValidationLayout, TaskValidationLayout } from './validation-layout';

function buildDuplicatedAPI(prototype) {
Object.defineProperties(prototype, {
Expand Down Expand Up @@ -686,7 +686,7 @@ export class Job extends Session {
return result;
}

async validationLayout(): Promise<ValidationLayout | null> {
async validationLayout(): Promise<JobValidationLayout | null> {
const result = await PluginRegistry.apiWrapper.call(this, Job.prototype.validationLayout);
return result;
}
Expand Down Expand Up @@ -1186,7 +1186,7 @@ export class Task extends Session {
return result;
}

async validationLayout(): Promise<ValidationLayout | null> {
async validationLayout(): Promise<TaskValidationLayout | null> {
const result = await PluginRegistry.apiWrapper.call(this, Task.prototype.validationLayout);
return result;
}
Expand Down
8 changes: 7 additions & 1 deletion cvat-core/src/user.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 All @@ -18,6 +18,7 @@ export default class User {
public readonly isSuperuser: boolean;
public readonly isActive: boolean;
public readonly isVerified: boolean;
public readonly hasAnalyticsAccess: boolean;

constructor(initialData: SerializedUser) {
const data = {
Expand All @@ -33,6 +34,7 @@ export default class User {
is_superuser: null,
is_active: null,
email_verification_required: null,
has_analytics_access: null,
};

for (const property in data) {
Expand Down Expand Up @@ -80,6 +82,9 @@ export default class User {
isVerified: {
get: () => !data.email_verification_required,
},
hasAnalyticsAccess: {
get: () => data.has_analytics_access,
},
}),
);
}
Expand All @@ -98,6 +103,7 @@ export default class User {
is_superuser: this.isSuperuser,
is_active: this.isActive,
email_verification_required: this.isVerified,
has_analytics_access: this.hasAnalyticsAccess,
};
}
}
Loading
Loading