From 2b433e80c3d2414ae80a371d7c49ac984b72d0b0 Mon Sep 17 00:00:00 2001 From: Maya Date: Tue, 25 Jan 2022 12:35:49 +0300 Subject: [PATCH 01/20] init --- .github/workflows/main.yml | 4 +- .github/workflows/publish_docker_images.yml | 2 +- .github/workflows/schedule.yml | 2 +- cvat-core/src/config.js | 4 +- cvat-core/src/download.worker.js | 3 +- cvat-core/src/server-proxy.js | 4 +- cvat-core/tests/mocks/dummy-data.mock.js | 92 +++++------ cvat-core/tests/mocks/server-proxy.mock.js | 6 +- cvat-ui/src/cvat-core-wrapper.ts | 4 +- .../dataset_manager/tests/test_formats.py | 10 +- .../tests/test_rest_api_formats.py | 34 ++-- cvat/apps/dataset_repo/tests.py | 10 +- cvat/apps/engine/backup.py | 6 +- cvat/apps/engine/renderers.py | 8 + cvat/apps/engine/task.py | 2 +- cvat/apps/engine/tests/test_rest_api.py | 156 +++++++++--------- cvat/apps/engine/tests/test_rest_api_3D.py | 30 ++-- cvat/apps/engine/urls.py | 6 +- cvat/apps/engine/views.py | 20 +-- cvat/apps/lambda_manager/tests/test_lambda.py | 8 +- cvat/apps/lambda_manager/urls.py | 14 +- cvat/apps/restrictions/tests.py | 4 +- cvat/settings/base.py | 7 +- cvat/urls.py | 2 +- site/config.toml | 2 +- .../en/docs/contributing/rest-api-design.md | 4 +- .../content/en/docs/manual/advanced/backup.md | 2 +- .../manual/advanced/serverless-tutorial.md | 4 +- .../case_52_dump_upload_annotation.js | 4 +- ..._import_annotations_frames_dots_in_name.js | 6 +- .../case_35_search_task_feature.js | 4 +- .../case_97_export_import_task.js | 4 +- .../case_109_dummy_cloud_storage.js | 8 +- ...44_changing_default_value_for_attribute.js | 6 +- .../actions_users/issue_1810_login_logout.js | 4 +- .../case_28_review_pipeline_feature.js | 2 +- .../case_4_assign_taks_job_users.js | 4 +- ...mp_upload_annotation_point_cloud_format.js | 4 +- ...pload_annotation_velodyne_points_format.js | 4 +- .../check_email_verification_system.js | 4 +- ...rror_cannot_read_property_at_saving_job.js | 4 +- ...move_users_tasks_projects_organizations.js | 18 +- tests/cypress/support/commands.js | 18 +- .../cypress/support/commands_organizations.js | 6 +- tests/cypress/support/commands_projects.js | 6 +- .../support/commands_review_pipeline.js | 12 +- tests/cypress/support/dummy-data.js | 6 +- tests/rest_api/README.md | 2 +- tests/rest_api/assets/invitations.json | 28 ++-- tests/rest_api/assets/jobs.json | 16 +- tests/rest_api/assets/memberships.json | 18 +- tests/rest_api/assets/organizations.json | 4 +- tests/rest_api/assets/projects.json | 10 +- tests/rest_api/assets/tasks.json | 32 ++-- tests/rest_api/assets/users.json | 36 ++-- tests/rest_api/utils/config.py | 2 +- tests/rest_api/utils/dump_objects.py | 2 +- utils/cli/core/core.py | 2 +- 58 files changed, 370 insertions(+), 356 deletions(-) create mode 100644 cvat/apps/engine/renderers.py diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 59484c6b7cb6..ea7e6ace638e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -73,7 +73,7 @@ jobs: ./opa test cvat/apps/iam/rules - name: Running REST API tests env: - API_ABOUT_PAGE: "localhost:8080/api/v1/server/about" + API_ABOUT_PAGE: "localhost:8080/api/server/about" run: | docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f components/serverless/docker-compose.serverless.yml up -d /bin/bash -c 'while [[ "$(curl -s -o /dev/null -w ''%{http_code}'' ${API_ABOUT_PAGE})" != "401" ]]; do sleep 5; done' @@ -184,7 +184,7 @@ jobs: DJANGO_SU_NAME: 'admin' DJANGO_SU_EMAIL: 'admin@localhost.company' DJANGO_SU_PASSWORD: '12qwaszx' - API_ABOUT_PAGE: "localhost:8080/api/v1/server/about" + API_ABOUT_PAGE: "localhost:8080/api/server/about" run: | docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f components/serverless/docker-compose.serverless.yml -f tests/docker-compose.file_share.yml up -d /bin/bash -c 'while [[ "$(curl -s -o /dev/null -w ''%{http_code}'' ${API_ABOUT_PAGE})" != "401" ]]; do sleep 5; done' diff --git a/.github/workflows/publish_docker_images.yml b/.github/workflows/publish_docker_images.yml index b997b99d3cbd..4cb9bd1656e0 100644 --- a/.github/workflows/publish_docker_images.yml +++ b/.github/workflows/publish_docker_images.yml @@ -28,7 +28,7 @@ jobs: DJANGO_SU_NAME: 'admin' DJANGO_SU_EMAIL: 'admin@localhost.company' DJANGO_SU_PASSWORD: '12qwaszx' - API_ABOUT_PAGE: "localhost:8080/api/v1/server/about" + API_ABOUT_PAGE: "localhost:8080/api/server/about" run: | docker-compose -f docker-compose.yml -f docker-compose.dev.yml build docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f components/serverless/docker-compose.serverless.yml -f tests/docker-compose.file_share.yml up -d diff --git a/.github/workflows/schedule.yml b/.github/workflows/schedule.yml index 7b496999223e..af81875e599f 100644 --- a/.github/workflows/schedule.yml +++ b/.github/workflows/schedule.yml @@ -16,7 +16,7 @@ jobs: DJANGO_SU_NAME: "admin" DJANGO_SU_EMAIL: "admin@localhost.company" DJANGO_SU_PASSWORD: "12qwaszx" - API_ABOUT_PAGE: "localhost:8080/api/v1/server/about" + API_ABOUT_PAGE: "localhost:8080/api/server/about" run: | docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f ./tests/docker-compose.email.yml -f tests/docker-compose.file_share.yml -f components/serverless/docker-compose.serverless.yml up -d --build /bin/bash -c 'while [[ "$(curl -s -o /dev/null -w ''%{http_code}'' ${API_ABOUT_PAGE})" != "401" ]]; do sleep 5; done' diff --git a/cvat-core/src/config.js b/cvat-core/src/config.js index 8c7b32242b17..1fbcbf9d39ca 100644 --- a/cvat-core/src/config.js +++ b/cvat-core/src/config.js @@ -1,9 +1,9 @@ -// Copyright (C) 2019-2021 Intel Corporation +// Copyright (C) 2019-2022 Intel Corporation // // SPDX-License-Identifier: MIT module.exports = { - backendAPI: '/api/v1', + backendAPI: '/api', proxy: false, organizationID: null, origin: '', diff --git a/cvat-core/src/download.worker.js b/cvat-core/src/download.worker.js index db3ed5f68471..be0ddc947e67 100644 --- a/cvat-core/src/download.worker.js +++ b/cvat-core/src/download.worker.js @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2021 Intel Corporation +// Copyright (C) 2019-2022 Intel Corporation // // SPDX-License-Identifier: MIT @@ -7,6 +7,7 @@ const Axios = require('axios'); Axios.defaults.withCredentials = true; Axios.defaults.xsrfHeaderName = 'X-CSRFTOKEN'; Axios.defaults.xsrfCookieName = 'csrftoken'; +Axios.defaults.headers.common.Accept = 'application/vnd.cvat+json; version=1.0'; onmessage = (e) => { Axios.get(e.data.url, e.data.config) diff --git a/cvat-core/src/server-proxy.js b/cvat-core/src/server-proxy.js index 40786a634ebc..79611f564c60 100644 --- a/cvat-core/src/server-proxy.js +++ b/cvat-core/src/server-proxy.js @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2021 Intel Corporation +// Copyright (C) 2019-2022 Intel Corporation // // SPDX-License-Identifier: MIT @@ -136,6 +136,7 @@ Axios.defaults.withCredentials = true; Axios.defaults.xsrfHeaderName = 'X-CSRFTOKEN'; Axios.defaults.xsrfCookieName = 'csrftoken'; + Axios.defaults.headers.common.Accept = 'application/vnd.cvat+json; version=1.0'; const workerAxios = new WorkerWrappedAxios(); Axios.interceptors.request.use((reqConfig) => { if ('params' in reqConfig && 'org' in reqConfig.params) { @@ -826,6 +827,7 @@ }, headers: { Authorization: `Token ${store.get('token')}`, + Accept: 'application/vnd.cvat+json; version=1.0', }, chunkSize, retryDelays: null, diff --git a/cvat-core/tests/mocks/dummy-data.mock.js b/cvat-core/tests/mocks/dummy-data.mock.js index 753b0aff814e..3e5944c5956b 100644 --- a/cvat-core/tests/mocks/dummy-data.mock.js +++ b/cvat-core/tests/mocks/dummy-data.mock.js @@ -55,7 +55,7 @@ const usersDummyData = { previous: null, results: [ { - url: 'http://localhost:7000/api/v1/users/1', + url: 'http://localhost:7000/api/users/1', id: 1, username: 'admin', first_name: '', @@ -69,7 +69,7 @@ const usersDummyData = { date_joined: '2019-05-13T15:33:17.833200+03:00', }, { - url: 'http://localhost:7000/api/v1/users/2', + url: 'http://localhost:7000/api/users/2', id: 2, username: 'bsekache', first_name: '', @@ -149,18 +149,18 @@ const projectsDummyData = { previous: null, results: [ { - url: 'http://192.168.0.139:7000/api/v1/projects/6', + url: 'http://192.168.0.139:7000/api/projects/6', id: 6, name: 'Some empty project', labels: [], tasks: [], owner: { - url: 'http://localhost:7000/api/v1/users/2', + url: 'http://localhost:7000/api/users/2', id: 2, username: 'bsekache', }, assignee: { - url: 'http://localhost:7000/api/v1/users/2', + url: 'http://localhost:7000/api/users/2', id: 2, username: 'bsekache', }, @@ -170,7 +170,7 @@ const projectsDummyData = { status: 'annotation', }, { - url: 'http://192.168.0.139:7000/api/v1/projects/1', + url: 'http://192.168.0.139:7000/api/projects/1', id: 2, name: 'Test project with roads', labels: [ @@ -198,13 +198,13 @@ const projectsDummyData = { ], tasks: [ { - url: 'http://192.168.0.139:7000/api/v1/tasks/2', + url: 'http://192.168.0.139:7000/api/tasks/2', id: 2, name: 'road 1', project_id: 1, mode: 'interpolation', owner: { - url: 'http://localhost:7000/api/v1/users/1', + url: 'http://localhost:7000/api/users/1', id: 1, username: 'admin', }, @@ -239,7 +239,7 @@ const projectsDummyData = { stop_frame: 99, jobs: [ { - url: 'http://192.168.0.139:7000/api/v1/jobs/1', + url: 'http://192.168.0.139:7000/api/jobs/1', id: 1, assignee: null, status: 'completed', @@ -253,7 +253,7 @@ const projectsDummyData = { stop_frame: 194, jobs: [ { - url: 'http://192.168.0.139:7000/api/v1/jobs/2', + url: 'http://192.168.0.139:7000/api/jobs/2', id: 2, assignee: null, status: 'completed', @@ -267,7 +267,7 @@ const projectsDummyData = { stop_frame: 289, jobs: [ { - url: 'http://192.168.0.139:7000/api/v1/jobs/3', + url: 'http://192.168.0.139:7000/api/jobs/3', id: 3, assignee: null, status: 'completed', @@ -281,7 +281,7 @@ const projectsDummyData = { stop_frame: 384, jobs: [ { - url: 'http://192.168.0.139:7000/api/v1/jobs/4', + url: 'http://192.168.0.139:7000/api/jobs/4', id: 4, assignee: null, status: 'completed', @@ -295,7 +295,7 @@ const projectsDummyData = { stop_frame: 431, jobs: [ { - url: 'http://192.168.0.139:7000/api/v1/jobs/5', + url: 'http://192.168.0.139:7000/api/jobs/5', id: 5, assignee: null, status: 'completed', @@ -314,7 +314,7 @@ const projectsDummyData = { }, ], owner: { - url: 'http://localhost:7000/api/v1/users/1', + url: 'http://localhost:7000/api/users/1', id: 1, username: 'admin', }, @@ -333,13 +333,13 @@ const tasksDummyData = { previous: null, results: [ { - url: 'http://localhost:7000/api/v1/tasks/102', + url: 'http://localhost:7000/api/tasks/102', id: 102, name: 'Test', size: 1, mode: 'annotation', owner: { - url: 'http://localhost:7000/api/v1/users/1', + url: 'http://localhost:7000/api/users/1', id: 1, username: 'admin', }, @@ -366,7 +366,7 @@ const tasksDummyData = { stop_frame: 0, jobs: [ { - url: 'http://localhost:7000/api/v1/jobs/112', + url: 'http://localhost:7000/api/jobs/112', id: 112, assignee: null, status: 'annotation', @@ -382,13 +382,13 @@ const tasksDummyData = { frame_filter: '', }, { - url: 'http://localhost:7000/api/v1/tasks/100', + url: 'http://localhost:7000/api/tasks/100', id: 100, name: 'Image Task', size: 9, mode: 'annotation', owner: { - url: 'http://localhost:7000/api/v1/users/1', + url: 'http://localhost:7000/api/users/1', id: 1, username: 'admin', }, @@ -420,7 +420,7 @@ const tasksDummyData = { stop_frame: 8, jobs: [ { - url: 'http://localhost:7000/api/v1/jobs/100', + url: 'http://localhost:7000/api/jobs/100', id: 100, assignee: null, status: 'annotation', @@ -436,13 +436,13 @@ const tasksDummyData = { frame_filter: '', }, { - url: 'http://localhost:7000/api/v1/tasks/10', + url: 'http://localhost:7000/api/tasks/10', id: 101, name: 'Video Task', size: 5002, mode: 'interpolation', owner: { - url: 'http://localhost:7000/api/v1/users/1', + url: 'http://localhost:7000/api/users/1', id: 1, username: 'admin', }, @@ -628,7 +628,7 @@ const tasksDummyData = { stop_frame: 499, jobs: [ { - url: 'http://localhost:7000/api/v1/jobs/10', + url: 'http://localhost:7000/api/jobs/10', id: 101, assignee: null, status: 'annotation', @@ -642,7 +642,7 @@ const tasksDummyData = { stop_frame: 994, jobs: [ { - url: 'http://localhost:7000/api/v1/jobs/11', + url: 'http://localhost:7000/api/jobs/11', id: 102, assignee: null, status: 'annotation', @@ -656,7 +656,7 @@ const tasksDummyData = { stop_frame: 1489, jobs: [ { - url: 'http://localhost:7000/api/v1/jobs/12', + url: 'http://localhost:7000/api/jobs/12', id: 103, assignee: null, status: 'annotation', @@ -670,7 +670,7 @@ const tasksDummyData = { stop_frame: 1984, jobs: [ { - url: 'http://localhost:7000/api/v1/jobs/13', + url: 'http://localhost:7000/api/jobs/13', id: 104, assignee: null, status: 'annotation', @@ -684,7 +684,7 @@ const tasksDummyData = { stop_frame: 2479, jobs: [ { - url: 'http://localhost:7000/api/v1/jobs/14', + url: 'http://localhost:7000/api/jobs/14', id: 105, assignee: null, status: 'annotation', @@ -698,7 +698,7 @@ const tasksDummyData = { stop_frame: 2974, jobs: [ { - url: 'http://localhost:7000/api/v1/jobs/15', + url: 'http://localhost:7000/api/jobs/15', id: 106, assignee: null, status: 'annotation', @@ -712,7 +712,7 @@ const tasksDummyData = { stop_frame: 3469, jobs: [ { - url: 'http://localhost:7000/api/v1/jobs/16', + url: 'http://localhost:7000/api/jobs/16', id: 107, assignee: null, status: 'annotation', @@ -726,7 +726,7 @@ const tasksDummyData = { stop_frame: 3964, jobs: [ { - url: 'http://localhost:7000/api/v1/jobs/17', + url: 'http://localhost:7000/api/jobs/17', id: 108, assignee: null, status: 'annotation', @@ -740,7 +740,7 @@ const tasksDummyData = { stop_frame: 4459, jobs: [ { - url: 'http://localhost:7000/api/v1/jobs/18', + url: 'http://localhost:7000/api/jobs/18', id: 109, assignee: null, status: 'annotation', @@ -754,7 +754,7 @@ const tasksDummyData = { stop_frame: 4954, jobs: [ { - url: 'http://localhost:7000/api/v1/jobs/19', + url: 'http://localhost:7000/api/jobs/19', id: 110, assignee: null, status: 'annotation', @@ -768,7 +768,7 @@ const tasksDummyData = { stop_frame: 5001, jobs: [ { - url: 'http://localhost:7000/api/v1/jobs/20', + url: 'http://localhost:7000/api/jobs/20', id: 111, assignee: null, status: 'annotation', @@ -784,13 +784,13 @@ const tasksDummyData = { frame_filter: '', }, { - url: 'http://localhost:7000/api/v1/tasks/3', + url: 'http://localhost:7000/api/tasks/3', id: 3, name: 'Test Task', size: 5002, mode: 'interpolation', owner: { - url: 'http://localhost:7000/api/v1/users/2', + url: 'http://localhost:7000/api/users/2', id: 2, username: 'bsekache', }, @@ -976,7 +976,7 @@ const tasksDummyData = { stop_frame: 4999, jobs: [ { - url: 'http://localhost:7000/api/v1/jobs/3', + url: 'http://localhost:7000/api/jobs/3', id: 3, assignee: null, status: 'annotation', @@ -990,7 +990,7 @@ const tasksDummyData = { stop_frame: 5001, jobs: [ { - url: 'http://localhost:7000/api/v1/jobs/4', + url: 'http://localhost:7000/api/jobs/4', id: 4, assignee: null, status: 'annotation', @@ -1003,13 +1003,13 @@ const tasksDummyData = { image_quality: 50, }, { - url: 'http://localhost:7000/api/v1/tasks/2', + url: 'http://localhost:7000/api/tasks/2', id: 2, name: 'Video', size: 75, mode: 'interpolation', owner: { - url: 'http://localhost:7000/api/v1/users/1', + url: 'http://localhost:7000/api/users/1', id: 1, username: 'admin', }, @@ -1196,7 +1196,7 @@ const tasksDummyData = { stop_frame: 74, jobs: [ { - url: 'http://localhost:7000/api/v1/jobs/2', + url: 'http://localhost:7000/api/jobs/2', id: 2, assignee: null, status: 'annotation', @@ -1209,13 +1209,13 @@ const tasksDummyData = { image_quality: 50, }, { - url: 'http://localhost:7000/api/v1/tasks/1', + url: 'http://localhost:7000/api/tasks/1', id: 1, name: 'Labels Set', size: 9, mode: 'annotation', owner: { - url: 'http://localhost:7000/api/v1/users/1', + url: 'http://localhost:7000/api/users/1', id: 1, username: 'admin', }, @@ -1401,7 +1401,7 @@ const tasksDummyData = { stop_frame: 8, jobs: [ { - url: 'http://localhost:7000/api/v1/jobs/1', + url: 'http://localhost:7000/api/jobs/1', id: 1, assignee: null, status: 'annotation', @@ -2695,7 +2695,7 @@ const cloudStoragesDummyData = { { id: 3, owner: { - url: 'http://localhost:7000/api/v1/users/1', + url: 'http://localhost:7000/api/users/1', id: 1, username: 'maya', first_name: '', @@ -2716,7 +2716,7 @@ const cloudStoragesDummyData = { { id: 2, owner: { - url: 'http://localhost:7000/api/v1/users/1', + url: 'http://localhost:7000/api/users/1', id: 1, username: 'maya', first_name: '', @@ -2737,7 +2737,7 @@ const cloudStoragesDummyData = { { id: 1, owner: { - url: 'http://localhost:7000/api/v1/users/1', + url: 'http://localhost:7000/api/users/1', id: 1, username: 'maya', first_name: '', diff --git a/cvat-core/tests/mocks/server-proxy.mock.js b/cvat-core/tests/mocks/server-proxy.mock.js index dbc1f91477b9..a4dbf5cef414 100644 --- a/cvat-core/tests/mocks/server-proxy.mock.js +++ b/cvat-core/tests/mocks/server-proxy.mock.js @@ -1,4 +1,4 @@ -// Copyright (C) 2020-2021 Intel Corporation +// Copyright (C) 2020-2022 Intel Corporation // // SPDX-License-Identifier: MIT @@ -113,7 +113,7 @@ class ServerProxy { const id = Math.max(...projectsDummyData.results.map((el) => el.id)) + 1; projectsDummyData.results.push({ id, - url: `http://localhost:7000/api/v1/projects/${id}`, + url: `http://localhost:7000/api/projects/${id}`, name: projectData.name, owner: 1, assignee: null, @@ -179,7 +179,7 @@ class ServerProxy { const id = Math.max(...tasksDummyData.results.map((el) => el.id)) + 1; tasksDummyData.results.push({ id, - url: `http://localhost:7000/api/v1/tasks/${id}`, + url: `http://localhost:7000/api/tasks/${id}`, name: taskData.name, project_id: taskData.project_id || null, size: 5000, diff --git a/cvat-ui/src/cvat-core-wrapper.ts b/cvat-ui/src/cvat-core-wrapper.ts index e0ea3b016497..981085769580 100644 --- a/cvat-ui/src/cvat-core-wrapper.ts +++ b/cvat-ui/src/cvat-core-wrapper.ts @@ -1,4 +1,4 @@ -// Copyright (C) 2020-2021 Intel Corporation +// Copyright (C) 2020-2022 Intel Corporation // // SPDX-License-Identifier: MIT @@ -6,7 +6,7 @@ import _cvat from 'cvat-core/src/api'; const cvat: any = _cvat; -cvat.config.backendAPI = '/api/v1'; +cvat.config.backendAPI = '/api'; cvat.config.origin = window.location.origin; cvat.config.uploadChunkSize = 100; (globalThis as any).cvat = cvat; diff --git a/cvat/apps/dataset_manager/tests/test_formats.py b/cvat/apps/dataset_manager/tests/test_formats.py index 977a319f7f99..a95d93cf9372 100644 --- a/cvat/apps/dataset_manager/tests/test_formats.py +++ b/cvat/apps/dataset_manager/tests/test_formats.py @@ -71,29 +71,29 @@ def create_db_users(cls): def _put_api_v1_task_id_annotations(self, tid, data): with ForceLogin(self.user, self.client): - response = self.client.put("/api/v1/tasks/%s/annotations" % tid, + response = self.client.put("/api/tasks/%s/annotations" % tid, data=data, format="json") return response def _put_api_v1_job_id_annotations(self, jid, data): with ForceLogin(self.user, self.client): - response = self.client.put("/api/v1/jobs/%s/annotations" % jid, + response = self.client.put("/api/jobs/%s/annotations" % jid, data=data, format="json") return response def _create_task(self, data, image_data): with ForceLogin(self.user, self.client): - response = self.client.post('/api/v1/tasks', data=data, format="json") + response = self.client.post('/api/tasks', data=data, format="json") assert response.status_code == status.HTTP_201_CREATED, response.status_code tid = response.data["id"] - response = self.client.post("/api/v1/tasks/%s/data" % tid, + response = self.client.post("/api/tasks/%s/data" % tid, data=image_data) assert response.status_code == status.HTTP_202_ACCEPTED, response.status_code - response = self.client.get("/api/v1/tasks/%s" % tid) + response = self.client.get("/api/tasks/%s" % tid) task = response.data return task diff --git a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py index e22e447160a4..07330c0237e7 100644 --- a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py +++ b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py @@ -124,14 +124,14 @@ def create_db_users(cls): def _put_api_v1_task_id_annotations(self, tid, data): with ForceLogin(self.admin, self.client): - response = self.client.put("/api/v1/tasks/%s/annotations" % tid, + response = self.client.put("/api/tasks/%s/annotations" % tid, data=data, format="json") return response def _put_api_v1_job_id_annotations(self, jid, data): with ForceLogin(self.admin, self.client): - response = self.client.put("/api/v1/jobs/%s/annotations" % jid, + response = self.client.put("/api/jobs/%s/annotations" % jid, data=data, format="json") return response @@ -150,22 +150,22 @@ def _generate_task_videos(count): # pylint: disable=no-self-use def _create_task(self, data, image_data): with ForceLogin(self.user, self.client): - response = self.client.post('/api/v1/tasks', data=data, format="json") + response = self.client.post('/api/tasks', data=data, format="json") assert response.status_code == status.HTTP_201_CREATED, response.status_code tid = response.data["id"] - response = self.client.post("/api/v1/tasks/%s/data" % tid, + response = self.client.post("/api/tasks/%s/data" % tid, data=image_data) assert response.status_code == status.HTTP_202_ACCEPTED, response.status_code - response = self.client.get("/api/v1/tasks/%s" % tid) + response = self.client.get("/api/tasks/%s" % tid) task = response.data return task def _create_project(self, data): with ForceLogin(self.user, self.client): - response = self.client.post('/api/v1/projects', data=data, format="json") + response = self.client.post('/api/projects', data=data, format="json") assert response.status_code == status.HTTP_201_CREATED, response.status_code project = response.data @@ -173,7 +173,7 @@ def _create_project(self, data): def _get_jobs(self, task_id): with ForceLogin(self.admin, self.client): - response = self.client.get("/api/v1/tasks/{}/jobs".format(task_id)) + response = self.client.get("/api/tasks/{}/jobs".format(task_id)) return response.data def _get_request(self, path, user): @@ -298,25 +298,25 @@ def _check_downloaded_file(self, file_name): raise FileNotFoundError(f"File '{file_name}' was not downloaded") def _generate_url_dump_tasks_annotations(self, task_id): - return f"/api/v1/tasks/{task_id}/annotations" + return f"/api/tasks/{task_id}/annotations" def _generate_url_upload_tasks_annotations(self, task_id, upload_format_name): - return f"/api/v1/tasks/{task_id}/annotations?format={upload_format_name}" + return f"/api/tasks/{task_id}/annotations?format={upload_format_name}" def _generate_url_dump_job_annotations(self, job_id): - return f"/api/v1/jobs/{job_id}/annotations" + return f"/api/jobs/{job_id}/annotations" def _generate_url_upload_job_annotations(self, job_id, upload_format_name): - return f"/api/v1/jobs/{job_id}/annotations?format={upload_format_name}" + return f"/api/jobs/{job_id}/annotations?format={upload_format_name}" def _generate_url_dump_task_dataset(self, task_id): - return f"/api/v1/tasks/{task_id}/dataset" + return f"/api/tasks/{task_id}/dataset" def _generate_url_dump_project_annotations(self, project_id, format_name): - return f"/api/v1/projects/{project_id}/annotations?format={format_name}" + return f"/api/projects/{project_id}/annotations?format={format_name}" def _generate_url_dump_project_dataset(self, project_id, format_name): - return f"/api/v1/projects/{project_id}/dataset?format={format_name}" + return f"/api/projects/{project_id}/dataset?format={format_name}" def _remove_annotations(self, url, user): response = self._delete_request(url, user) @@ -324,7 +324,7 @@ def _remove_annotations(self, url, user): return response def _delete_project(self, project_id, user): - response = self._delete_request(f'/api/v1/projects/{project_id}', user) + response = self._delete_request(f'/api/projects/{project_id}', user) self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) return response @@ -628,7 +628,7 @@ def test_api_v1_dump_and_upload_annotations_with_objects_are_different_images(se with open(file_zip_name, 'rb') as binary_file: self._upload_file(url_upload, binary_file, self.admin) - response = self._get_request(f"/api/v1/tasks/{task_id}/annotations", self.admin) + response = self._get_request(f"/api/tasks/{task_id}/annotations", self.admin) self.assertEqual(len(response.data["shapes"]), 2) self.assertEqual(len(response.data["tracks"]), 0) @@ -670,7 +670,7 @@ def test_api_v1_dump_and_upload_annotations_with_objects_are_different_video(sel self._upload_file(url_upload, binary_file, self.admin) self.assertEqual(osp.exists(file_zip_name), True) - response = self._get_request(f"/api/v1/tasks/{task_id}/annotations", self.admin) + response = self._get_request(f"/api/tasks/{task_id}/annotations", self.admin) self.assertEqual(len(response.data["shapes"]), 0) self.assertEqual(len(response.data["tracks"]), 2) diff --git a/cvat/apps/dataset_repo/tests.py b/cvat/apps/dataset_repo/tests.py index a2261a4c183c..e1aabb5eece8 100644 --- a/cvat/apps/dataset_repo/tests.py +++ b/cvat/apps/dataset_repo/tests.py @@ -193,14 +193,14 @@ def setUpTestData(cls): def _run_api_v1_job_id_annotation(self, jid, data, user): with ForceLogin(user, self.client): - response = self.client.patch('/api/v1/jobs/{}/annotations?action=create'.format(jid), + response = self.client.patch('/api/jobs/{}/annotations?action=create'.format(jid), data=data, format="json") return response def _get_jobs(self, task_id): with ForceLogin(self.admin, self.client): - response = self.client.get("/api/v1/tasks/{}/jobs".format(task_id)) + response = self.client.get("/api/tasks/{}/jobs".format(task_id)) return response.data def _create_task(self, init_repos=False): @@ -224,15 +224,15 @@ def _create_task(self, init_repos=False): images["image_quality"] = 75 with ForceLogin(self.user, self.client): - response = self.client.post('/api/v1/tasks', data=data, format="json") + response = self.client.post('/api/tasks', data=data, format="json") assert response.status_code == status.HTTP_201_CREATED, response.status_code tid = response.data["id"] - response = self.client.post("/api/v1/tasks/%s/data" % tid, + response = self.client.post("/api/tasks/%s/data" % tid, data=images) assert response.status_code == status.HTTP_202_ACCEPTED, response.status_code - response = self.client.get("/api/v1/tasks/%s" % tid) + response = self.client.get("/api/tasks/%s" % tid) task = response.data db_task = Task.objects.get(pk=task["id"]) diff --git a/cvat/apps/engine/backup.py b/cvat/apps/engine/backup.py index 50b47cbb536b..8c823f3feea1 100644 --- a/cvat/apps/engine/backup.py +++ b/cvat/apps/engine/backup.py @@ -708,7 +708,7 @@ def export(db_instance, request): "Unexpected type of db_isntance: {}".format(type(db_instance))) queue = django_rq.get_queue("default") - rq_id = "/api/v1/{}s/{}/backup".format(filename_prefix, db_instance.pk) + rq_id = "/api/{}s/{}/backup".format(filename_prefix, db_instance.pk) rq_job = queue.fetch_job(rq_id) if rq_job: last_project_update_time = timezone.localtime(db_instance.updated_date) @@ -801,7 +801,7 @@ def import_project(request): if 'rq_id' in request.data: rq_id = request.data['rq_id'] else: - rq_id = "{}@/api/v1/projects/{}/import".format(request.user, uuid.uuid4()) + rq_id = "{}@/api/projects/{}/import".format(request.user, uuid.uuid4()) Serializer = ProjectFileSerializer file_field_name = 'project_file' @@ -817,7 +817,7 @@ def import_task(request): if 'rq_id' in request.data: rq_id = request.data['rq_id'] else: - rq_id = "{}@/api/v1/tasks/{}/import".format(request.user, uuid.uuid4()) + rq_id = "{}@/api/tasks/{}/import".format(request.user, uuid.uuid4()) Serializer = TaskFileSerializer file_field_name = 'task_file' diff --git a/cvat/apps/engine/renderers.py b/cvat/apps/engine/renderers.py new file mode 100644 index 000000000000..578b7d7f4bdd --- /dev/null +++ b/cvat/apps/engine/renderers.py @@ -0,0 +1,8 @@ +# Copyright (C) 2022 Intel Corporation +# +# SPDX-License-Identifier: MIT + +from rest_framework.renderers import JSONRenderer + +class CVATAPIRenderer(JSONRenderer): + media_type = 'application/vnd.cvat+json; version=1.0' \ No newline at end of file diff --git a/cvat/apps/engine/task.py b/cvat/apps/engine/task.py index 5550dd230ae6..82dda7ad04d2 100644 --- a/cvat/apps/engine/task.py +++ b/cvat/apps/engine/task.py @@ -35,7 +35,7 @@ def create(tid, data): """Schedule the task""" q = django_rq.get_queue('default') q.enqueue_call(func=_create_thread, args=(tid, data), - job_id="/api/v1/tasks/{}".format(tid)) + job_id="/api/tasks/{}".format(tid)) @transaction.atomic def rq_handler(job, exc_type, exc_value, traceback): diff --git a/cvat/apps/engine/tests/test_rest_api.py b/cvat/apps/engine/tests/test_rest_api.py index 8afb69d87d24..61fc24b95e29 100644 --- a/cvat/apps/engine/tests/test_rest_api.py +++ b/cvat/apps/engine/tests/test_rest_api.py @@ -266,7 +266,7 @@ def setUpTestData(cls): def _run_api_v1_jobs_id(self, jid, user): with ForceLogin(user, self.client): - response = self.client.get('/api/v1/jobs/{}'.format(jid)) + response = self.client.get('/api/jobs/{}'.format(jid)) return response @@ -328,7 +328,7 @@ def setUpTestData(cls): def _run_api_v1_jobs_id(self, jid, user, data): with ForceLogin(user, self.client): - response = self.client.put('/api/v1/jobs/{}'.format(jid), data=data, format='json') + response = self.client.put('/api/jobs/{}'.format(jid), data=data, format='json') return response @@ -386,7 +386,7 @@ def test_api_v1_jobs_id_no_auth(self): class JobPartialUpdateAPITestCase(JobUpdateAPITestCase): def _run_api_v1_jobs_id(self, jid, user, data): with ForceLogin(user, self.client): - response = self.client.patch('/api/v1/jobs/{}'.format(jid), data=data, format='json') + response = self.client.patch('/api/jobs/{}'.format(jid), data=data, format='json') return response @@ -410,7 +410,7 @@ def setUpTestData(cls): def _run_api_v1_server_about(self, user): with ForceLogin(user, self.client): - response = self.client.get('/api/v1/server/about') + response = self.client.get('/api/server/about') return response @@ -458,7 +458,7 @@ def _run_api_v1_server_exception(self, user): with ForceLogin(user, self.client): #pylint: disable=unused-variable with mock.patch("cvat.apps.engine.views.clogger") as clogger: - response = self.client.post('/api/v1/server/exception', + response = self.client.post('/api/server/exception', self.data, format='json') return response @@ -506,7 +506,7 @@ def _run_api_v1_server_logs(self, user): with ForceLogin(user, self.client): #pylint: disable=unused-variable with mock.patch("cvat.apps.engine.views.clogger") as clogger: - response = self.client.post('/api/v1/server/logs', + response = self.client.post('/api/server/logs', self.data, format='json') return response @@ -550,7 +550,7 @@ def _check_data(self, user, data, is_full): class UserListAPITestCase(UserAPITestCase): def _run_api_v1_users(self, user): with ForceLogin(user, self.client): - response = self.client.get('/api/v1/users') + response = self.client.get('/api/users') return response @@ -583,7 +583,7 @@ def test_api_v1_users_no_auth(self): class UserSelfAPITestCase(UserAPITestCase): def _run_api_v1_users_self(self, user): with ForceLogin(user, self.client): - response = self.client.get('/api/v1/users/self') + response = self.client.get('/api/users/self') return response @@ -610,7 +610,7 @@ def test_api_v1_users_self_no_auth(self): class UserGetAPITestCase(UserAPITestCase): def _run_api_v1_users_id(self, user, user_id): with ForceLogin(user, self.client): - response = self.client.get('/api/v1/users/{}'.format(user_id)) + response = self.client.get('/api/users/{}'.format(user_id)) return response @@ -652,7 +652,7 @@ def test_api_v1_users_id_no_auth(self): class UserPartialUpdateAPITestCase(UserAPITestCase): def _run_api_v1_users_id(self, user, user_id, data): with ForceLogin(user, self.client): - response = self.client.patch('/api/v1/users/{}'.format(user_id), data=data) + response = self.client.patch('/api/users/{}'.format(user_id), data=data) return response @@ -698,7 +698,7 @@ def test_api_v1_users_id_no_auth_partial(self): class UserDeleteAPITestCase(UserAPITestCase): def _run_api_v1_users_id(self, user, user_id): with ForceLogin(user, self.client): - response = self.client.delete('/api/v1/users/{}'.format(user_id)) + response = self.client.delete('/api/users/{}'.format(user_id)) return response @@ -745,7 +745,7 @@ def setUpTestData(cls): def _run_api_v1_projects(self, user, params=""): with ForceLogin(user, self.client): - response = self.client.get('/api/v1/projects{}'.format(params)) + response = self.client.get('/api/projects{}'.format(params)) return response @@ -785,7 +785,7 @@ def setUpTestData(cls): def _run_api_v1_projects_id(self, pid, user): with ForceLogin(user, self.client): - response = self.client.get('/api/v1/projects/{}'.format(pid)) + response = self.client.get('/api/projects/{}'.format(pid)) return response @@ -834,7 +834,7 @@ def setUpTestData(cls): def _run_api_v1_projects_id(self, pid, user): with ForceLogin(user, self.client): - response = self.client.delete('/api/v1/projects/{}'.format(pid), format="json") + response = self.client.delete('/api/projects/{}'.format(pid), format="json") return response @@ -871,7 +871,7 @@ def setUpTestData(cls): def _run_api_v1_projects(self, user, data): with ForceLogin(user, self.client): - response = self.client.post('/api/v1/projects', data=data, format="json") + response = self.client.post('/api/projects', data=data, format="json") return response @@ -965,7 +965,7 @@ def setUpTestData(cls): def _run_api_v1_projects_id(self, pid, user, data): with ForceLogin(user, self.client): - response = self.client.patch('/api/v1/projects/{}'.format(pid), + response = self.client.patch('/api/projects/{}'.format(pid), data=data, format="json") return response @@ -1099,7 +1099,7 @@ def _check_api_v1_project(self, data): def _run_api_v1_project_id(self, pid, user, data): with ForceLogin(user, self.client): - response = self.client.patch('/api/v1/projects/{}'.format(pid), + response = self.client.patch('/api/projects/{}'.format(pid), data=data, format="json") return response @@ -1143,7 +1143,7 @@ def setUpTestData(cls): def _run_api_v1_projects_id_tasks(self, user, pid): with ForceLogin(user, self.client): - response = self.client.get('/api/v1/projects/{}/tasks'.format(pid)) + response = self.client.get('/api/projects/{}/tasks'.format(pid)) return response @@ -1319,16 +1319,16 @@ def _create_media(cls): @classmethod def _create_tasks(cls, project): def _create_task(task_data, media_data): - response = cls.client.post('/api/v1/tasks', data=task_data, format="json") + response = cls.client.post('/api/tasks', data=task_data, format="json") assert response.status_code == status.HTTP_201_CREATED tid = response.data["id"] for media in media_data.values(): if isinstance(media, io.BytesIO): media.seek(0) - response = cls.client.post("/api/v1/tasks/{}/data".format(tid), data=media_data) + response = cls.client.post("/api/tasks/{}/data".format(tid), data=media_data) assert response.status_code == status.HTTP_202_ACCEPTED - response = cls.client.get("/api/v1/tasks/{}".format(tid)) + response = cls.client.get("/api/tasks/{}".format(tid)) data_id = response.data["data"] cls.tasks.append({ "id": tid, @@ -1467,19 +1467,19 @@ def _create_projects(cls): def _run_api_v1_projects_id_export(self, pid, user, query_params=""): with ForceLogin(user, self.client): - response = self.client.get('/api/v1/projects/{}/backup?{}'.format(pid, query_params), format="json") + response = self.client.get('/api/projects/{}/backup?{}'.format(pid, query_params), format="json") return response def _run_api_v1_projects_import(self, user, data): with ForceLogin(user, self.client): - response = self.client.post('/api/v1/projects/backup', data=data, format="multipart") + response = self.client.post('/api/projects/backup', data=data, format="multipart") return response def _run_api_v1_projects_id(self, pid, user): with ForceLogin(user, self.client): - response = self.client.get('/api/v1/projects/{}'.format(pid), format="json") + response = self.client.get('/api/projects/{}'.format(pid), format="json") return response.data @@ -1577,13 +1577,13 @@ def setUpTestData(cls): def _run_api_v1_project_id_export(self, pid, user, annotation_format=""): with ForceLogin(user, self.client): response = self.client.get( - '/api/v1/projects/{}/annotations?format={}'.format(pid, annotation_format), + '/api/projects/{}/annotations?format={}'.format(pid, annotation_format), format="json") return response def _run_api_v1_tasks_id_delete(self, tid, user): with ForceLogin(user, self.client): - response = self.client.delete('/api/v1/tasks/{}'.format(tid), format="json") + response = self.client.delete('/api/tasks/{}'.format(tid), format="json") return response def _check_tasks_count(self, project, expected_result): @@ -1660,16 +1660,16 @@ def _create_tasks(self): self.tasks = [] def _create_task(task_data, media_data): - response = self.client.post('/api/v1/tasks', data=task_data, format="json") + response = self.client.post('/api/tasks', data=task_data, format="json") assert response.status_code == status.HTTP_201_CREATED tid = response.data["id"] for media in media_data.values(): if isinstance(media, io.BytesIO): media.seek(0) - response = self.client.post("/api/v1/tasks/{}/data".format(tid), data=media_data) + response = self.client.post("/api/tasks/{}/data".format(tid), data=media_data) assert response.status_code == status.HTTP_202_ACCEPTED - response = self.client.get("/api/v1/tasks/{}".format(tid)) + response = self.client.get("/api/tasks/{}".format(tid)) data_id = response.data["data"] self.tasks.append({ "id": tid, @@ -1701,7 +1701,7 @@ def _create_projects(self): self.projects = [] def _create_project(project_data): - response = self.client.post('/api/v1/projects', data=project_data, format="json") + response = self.client.post('/api/projects', data=project_data, format="json") assert response.status_code == status.HTTP_201_CREATED self.projects.append(response.data) @@ -1735,17 +1735,17 @@ def _create_project(project_data): def _run_api_v1_projects_id_dataset_export(self, pid, user, query_params=""): with ForceLogin(user, self.client): - response = self.client.get("/api/v1/projects/{}/dataset?{}".format(pid, query_params), format="json") + response = self.client.get("/api/projects/{}/dataset?{}".format(pid, query_params), format="json") return response def _run_api_v1_projects_id_dataset_import(self, pid, user, data, f): with ForceLogin(user, self.client): - response = self.client.post("/api/v1/projects/{}/dataset?format={}".format(pid, f), data=data, format="multipart") + response = self.client.post("/api/projects/{}/dataset?format={}".format(pid, f), data=data, format="multipart") return response def _run_api_v1_projects_id_dataset_import_status(self, pid, user): with ForceLogin(user, self.client): - response = self.client.get("/api/v1/projects/{}/dataset?action=import_status".format(pid), format="json") + response = self.client.get("/api/projects/{}/dataset?action=import_status".format(pid), format="json") return response def test_api_v1_projects_id_export_import(self): @@ -1795,7 +1795,7 @@ def setUpTestData(cls): def _run_api_v1_tasks(self, user, params=""): with ForceLogin(user, self.client): - response = self.client.get('/api/v1/tasks{}'.format(params)) + response = self.client.get('/api/tasks{}'.format(params)) return response @@ -1835,7 +1835,7 @@ def setUpTestData(cls): def _run_api_v1_tasks_id(self, tid, user): with ForceLogin(user, self.client): - response = self.client.get('/api/v1/tasks/{}'.format(tid)) + response = self.client.get('/api/tasks/{}'.format(tid)) return response @@ -1893,7 +1893,7 @@ def setUpTestData(cls): def _run_api_v1_tasks_id(self, tid, user): with ForceLogin(user, self.client): - response = self.client.delete('/api/v1/tasks/{}'.format(tid), format="json") + response = self.client.delete('/api/tasks/{}'.format(tid), format="json") return response @@ -1941,7 +1941,7 @@ def setUpTestData(cls): def _run_api_v1_tasks_id(self, tid, user, data): with ForceLogin(user, self.client): - response = self.client.put('/api/v1/tasks/{}'.format(tid), + response = self.client.put('/api/tasks/{}'.format(tid), data=data, format="json") return response @@ -2041,7 +2041,7 @@ def test_api_v1_tasks_id_no_auth(self): class TaskPartialUpdateAPITestCase(TaskUpdateAPITestCase): def _run_api_v1_tasks_id(self, tid, user, data): with ForceLogin(user, self.client): - response = self.client.patch('/api/v1/tasks/{}'.format(tid), + response = self.client.patch('/api/tasks/{}'.format(tid), data=data, format="json") return response @@ -2132,7 +2132,7 @@ def _check_api_v1_task(self, data): def _run_api_v1_task_id(self, tid, user, data): with ForceLogin(user, self.client): - response = self.client.patch('/api/v1/tasks/{}'.format(tid), + response = self.client.patch('/api/tasks/{}'.format(tid), data=data, format="json") return response @@ -2300,14 +2300,14 @@ def setUpTestData(cls): def _run_api_v1_tasks_id(self, tid, data): with ForceLogin(self.admin, self.client): - response = self.client.patch('/api/v1/tasks/{}'.format(tid), + response = self.client.patch('/api/tasks/{}'.format(tid), data=data, format="json") return response def _run_api_v1_job_id_annotation(self, jid, data): with ForceLogin(self.admin, self.client): - response = self.client.patch('/api/v1/jobs/{}/annotations?action=create'.format(jid), + response = self.client.patch('/api/jobs/{}/annotations?action=create'.format(jid), data=data, format="json") return response @@ -2369,7 +2369,7 @@ def setUpTestData(cls): def _run_api_v1_tasks(self, user, data): with ForceLogin(user, self.client): - response = self.client.post('/api/v1/tasks', data=data, format="json") + response = self.client.post('/api/tasks', data=data, format="json") return response @@ -2698,16 +2698,16 @@ def _create_tasks(self): self.tasks = [] def _create_task(task_data, media_data): - response = self.client.post('/api/v1/tasks', data=task_data, format="json") + response = self.client.post('/api/tasks', data=task_data, format="json") assert response.status_code == status.HTTP_201_CREATED tid = response.data["id"] for media in media_data.values(): if isinstance(media, io.BytesIO): media.seek(0) - response = self.client.post("/api/v1/tasks/{}/data".format(tid), data=media_data) + response = self.client.post("/api/tasks/{}/data".format(tid), data=media_data) assert response.status_code == status.HTTP_202_ACCEPTED - response = self.client.get("/api/v1/tasks/{}".format(tid)) + response = self.client.get("/api/tasks/{}".format(tid)) data_id = response.data["data"] self.tasks.append({ "id": tid, @@ -2764,19 +2764,19 @@ def _create_task(task_data, media_data): def _run_api_v1_tasks_id_export(self, tid, user, query_params=""): with ForceLogin(user, self.client): - response = self.client.get('/api/v1/tasks/{}/backup?{}'.format(tid, query_params), format="json") + response = self.client.get('/api/tasks/{}/backup?{}'.format(tid, query_params), format="json") return response def _run_api_v1_tasks_id_import(self, user, data): with ForceLogin(user, self.client): - response = self.client.post('/api/v1/tasks/backup', data=data, format="multipart") + response = self.client.post('/api/tasks/backup', data=data, format="multipart") return response def _run_api_v1_tasks_id(self, tid, user): with ForceLogin(user, self.client): - response = self.client.get('/api/v1/tasks/{}'.format(tid), format="json") + response = self.client.get('/api/tasks/{}'.format(tid), format="json") return response.data @@ -3136,22 +3136,22 @@ def tearDownClass(cls): def _run_api_v1_tasks_id_data_post(self, tid, user, data): with ForceLogin(user, self.client): - response = self.client.post('/api/v1/tasks/{}/data'.format(tid), + response = self.client.post('/api/tasks/{}/data'.format(tid), data=data) return response def _create_task(self, user, data): with ForceLogin(user, self.client): - response = self.client.post('/api/v1/tasks', data=data, format="json") + response = self.client.post('/api/tasks', data=data, format="json") return response def _get_task(self, user, tid): with ForceLogin(user, self.client): - return self.client.get("/api/v1/tasks/{}".format(tid)) + return self.client.get("/api/tasks/{}".format(tid)) def _run_api_v1_task_id_data_get(self, tid, user, data_type, data_quality=None, data_number=None): - url = '/api/v1/tasks/{}/data?type={}'.format(tid, data_type) + url = '/api/tasks/{}/data?type={}'.format(tid, data_type) if data_quality is not None: url += '&quality={}'.format(data_quality) if data_number is not None: @@ -4015,7 +4015,7 @@ def _create_task(self, owner, assignee, annotation_format=""): }] with ForceLogin(owner, self.client): - response = self.client.post('/api/v1/tasks', data=data, format="json") + response = self.client.post('/api/tasks', data=data, format="json") assert response.status_code == status.HTTP_201_CREATED tid = response.data["id"] @@ -4041,13 +4041,13 @@ def _create_task(self, owner, assignee, annotation_format=""): "image_quality": 100, } - response = self.client.post("/api/v1/tasks/{}/data".format(tid), data=images) + response = self.client.post("/api/tasks/{}/data".format(tid), data=images) assert response.status_code == status.HTTP_202_ACCEPTED - response = self.client.get("/api/v1/tasks/{}".format(tid)) + response = self.client.get("/api/tasks/{}".format(tid)) task = response.data - response = self.client.get("/api/v1/tasks/{}/jobs".format(tid)) + response = self.client.get("/api/tasks/{}/jobs".format(tid)) jobs = response.data return (task, jobs) @@ -4075,20 +4075,20 @@ def _get_default_attr_values(task): def _put_api_v1_jobs_id_data(self, jid, user, data): with ForceLogin(user, self.client): - response = self.client.put("/api/v1/jobs/{}/annotations".format(jid), + response = self.client.put("/api/jobs/{}/annotations".format(jid), data=data, format="json") return response def _get_api_v1_jobs_id_data(self, jid, user): with ForceLogin(user, self.client): - response = self.client.get("/api/v1/jobs/{}/annotations".format(jid)) + response = self.client.get("/api/jobs/{}/annotations".format(jid)) return response def _delete_api_v1_jobs_id_data(self, jid, user): with ForceLogin(user, self.client): - response = self.client.delete("/api/v1/jobs/{}/annotations".format(jid), + response = self.client.delete("/api/jobs/{}/annotations".format(jid), format="json") return response @@ -4096,7 +4096,7 @@ def _delete_api_v1_jobs_id_data(self, jid, user): def _patch_api_v1_jobs_id_data(self, jid, user, action, data): with ForceLogin(user, self.client): response = self.client.patch( - "/api/v1/jobs/{}/annotations?action={}".format(jid, action), + "/api/jobs/{}/annotations?action={}".format(jid, action), data=data, format="json") return response @@ -4535,20 +4535,20 @@ def test_api_v1_jobs_id_annotations_no_auth(self): class TaskAnnotationAPITestCase(JobAnnotationAPITestCase): def _put_api_v1_tasks_id_annotations(self, pk, user, data): with ForceLogin(user, self.client): - response = self.client.put("/api/v1/tasks/{}/annotations".format(pk), + response = self.client.put("/api/tasks/{}/annotations".format(pk), data=data, format="json") return response def _get_api_v1_tasks_id_annotations(self, pk, user): with ForceLogin(user, self.client): - response = self.client.get("/api/v1/tasks/{}/annotations".format(pk)) + response = self.client.get("/api/tasks/{}/annotations".format(pk)) return response def _delete_api_v1_tasks_id_annotations(self, pk, user): with ForceLogin(user, self.client): - response = self.client.delete("/api/v1/tasks/{}/annotations".format(pk), + response = self.client.delete("/api/tasks/{}/annotations".format(pk), format="json") return response @@ -4556,14 +4556,14 @@ def _delete_api_v1_tasks_id_annotations(self, pk, user): def _dump_api_v1_tasks_id_annotations(self, pk, user, query_params=""): with ForceLogin(user, self.client): response = self.client.get( - "/api/v1/tasks/{0}/annotations{1}".format(pk, query_params)) + "/api/tasks/{0}/annotations{1}".format(pk, query_params)) return response def _patch_api_v1_tasks_id_annotations(self, pk, user, action, data): with ForceLogin(user, self.client): response = self.client.patch( - "/api/v1/tasks/{}/annotations?action={}".format(pk, action), + "/api/tasks/{}/annotations?action={}".format(pk, action), data=data, format="json") return response @@ -4571,7 +4571,7 @@ def _patch_api_v1_tasks_id_annotations(self, pk, user, action, data): def _upload_api_v1_tasks_id_annotations(self, pk, user, data, query_params=""): with ForceLogin(user, self.client): response = self.client.put( - path="/api/v1/tasks/{0}/annotations?{1}".format(pk, query_params), + path="/api/tasks/{0}/annotations?{1}".format(pk, query_params), data=data, format="multipart", ) @@ -4581,7 +4581,7 @@ def _upload_api_v1_tasks_id_annotations(self, pk, user, data, query_params=""): def _get_formats(self, user): with ForceLogin(user, self.client): response = self.client.get( - path="/api/v1/server/annotation/formats" + path="/api/server/annotation/formats" ) return response @@ -5772,7 +5772,7 @@ def tearDownClass(cls): def _run_api_v1_server_share(self, user, directory): with ForceLogin(user, self.client): response = self.client.get( - '/api/v1/server/share?directory={}'.format(directory)) + '/api/server/share?directory={}'.format(directory)) return response @@ -5878,20 +5878,20 @@ def _get_request(self, path): def _run_api_v1_server_share(self, directory): with ForceLogin(self.user, self.client): response = self.client.get( - '/api/v1/server/share?directory={}'.format(directory)) + '/api/server/share?directory={}'.format(directory)) return response def _create_task(self, data, image_data): with ForceLogin(self.user, self.client): - response = self.client.post('/api/v1/tasks', data=data, format="json") + response = self.client.post('/api/tasks', data=data, format="json") self.assertEqual(response.status_code, status.HTTP_201_CREATED) tid = response.data["id"] - response = self.client.post("/api/v1/tasks/%s/data" % tid, + response = self.client.post("/api/tasks/%s/data" % tid, data=image_data) self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) - response = self.client.get("/api/v1/tasks/%s" % tid) + response = self.client.get("/api/tasks/%s" % tid) task = response.data return task @@ -5933,7 +5933,7 @@ def test_api_v1_combined_image_and_directory_extractors(self): image_data.update(remote_files) # create task with server task = self._create_task(task, image_data) - response = self._get_request("/api/v1/tasks/%s/data/meta" % task["id"]) + response = self._get_request("/api/tasks/%s/data/meta" % task["id"]) self.assertEqual(len(response.data["frames"]), images_count) @@ -5966,15 +5966,15 @@ def _get_request(self, path, user): def _create_task(self, data, image_data): with ForceLogin(self.user, self.client): - response = self.client.post('/api/v1/tasks', data=data, format="json") + response = self.client.post('/api/tasks', data=data, format="json") assert response.status_code == status.HTTP_201_CREATED, response.status_code tid = response.data["id"] - response = self.client.post("/api/v1/tasks/%s/data" % tid, + response = self.client.post("/api/tasks/%s/data" % tid, data=image_data) assert response.status_code == status.HTTP_202_ACCEPTED, response.status_code - response = self.client.get("/api/v1/tasks/%s" % tid) + response = self.client.get("/api/tasks/%s" % tid) task = response.data return task @@ -6008,7 +6008,7 @@ def test_check_flag_has_related_context(self): task = self._create_task(self.task, img_data) task_id = task["id"] - response = self._get_request("/api/v1/tasks/%s/data/meta" % task_id, self.admin) + response = self._get_request("/api/tasks/%s/data/meta" % task_id, self.admin) for frame in response.data["frames"]: self.assertEqual(context_img_data[frame["name"]], frame["has_related_context"]) @@ -6028,5 +6028,5 @@ def test_fetch_related_image_from_server(self): "type": "context_image", "number": 0 } - response = self._get_request_with_data("/api/v1/tasks/%s/data" % task_id, data, self.admin) + response = self._get_request_with_data("/api/tasks/%s/data" % task_id, data, self.admin) self.assertEqual(response.status_code, status.HTTP_200_OK) diff --git a/cvat/apps/engine/tests/test_rest_api_3D.py b/cvat/apps/engine/tests/test_rest_api_3D.py index 7547d9b12bb3..1f9cabba6f43 100644 --- a/cvat/apps/engine/tests/test_rest_api_3D.py +++ b/cvat/apps/engine/tests/test_rest_api_3D.py @@ -69,14 +69,14 @@ def create_db_users(cls): def _put_api_v1_task_id_annotations(self, tid, data): with ForceLogin(self.admin, self.client): - response = self.client.put("/api/v1/tasks/%s/annotations" % tid, + response = self.client.put("/api/tasks/%s/annotations" % tid, data=data, format="json") return response def _put_api_v1_job_id_annotations(self, jid, data): with ForceLogin(self.admin, self.client): - response = self.client.put("/api/v1/jobs/%s/annotations" % jid, + response = self.client.put("/api/jobs/%s/annotations" % jid, data=data, format="json") return response @@ -84,7 +84,7 @@ def _put_api_v1_job_id_annotations(self, jid, data): def _patch_api_v1_task_id_annotations(self, tid, data, action, user): with ForceLogin(user, self.client): response = self.client.patch( - "/api/v1/tasks/{}/annotations?action={}".format(tid, action), + "/api/tasks/{}/annotations?action={}".format(tid, action), data=data, format="json") return response @@ -92,22 +92,22 @@ def _patch_api_v1_task_id_annotations(self, tid, data, action, user): def _patch_api_v1_job_id_annotations(self, jid, data, action, user): with ForceLogin(user, self.client): response = self.client.patch( - "/api/v1/jobs/{}/annotations?action={}".format(jid, action), + "/api/jobs/{}/annotations?action={}".format(jid, action), data=data, format="json") return response def _create_task(self, data, image_data): with ForceLogin(self.user, self.client): - response = self.client.post('/api/v1/tasks', data=data, format="json") + response = self.client.post('/api/tasks', data=data, format="json") assert response.status_code == status.HTTP_201_CREATED, response.status_code tid = response.data["id"] - response = self.client.post("/api/v1/tasks/%s/data" % tid, + response = self.client.post("/api/tasks/%s/data" % tid, data=image_data) assert response.status_code == status.HTTP_202_ACCEPTED, response.status_code - response = self.client.get("/api/v1/tasks/%s" % tid) + response = self.client.get("/api/tasks/%s" % tid) task = response.data return task @@ -140,7 +140,7 @@ def _get_tmp_annotation(task, annotation): def _get_jobs(self, task_id): with ForceLogin(self.admin, self.client): - response = self.client.get("/api/v1/tasks/{}/jobs".format(task_id)) + response = self.client.get("/api/tasks/{}/jobs".format(task_id)) return response.data def _get_request(self, path, user): @@ -175,22 +175,22 @@ def _upload_file(self, url, data, user): self.assertEqual(response.status_code, status.HTTP_201_CREATED) def _generate_url_dump_tasks_annotations(self, task_id): - return f"/api/v1/tasks/{task_id}/annotations" + return f"/api/tasks/{task_id}/annotations" def _generate_url_upload_tasks_annotations(self, task_id, upload_format_name): - return f"/api/v1/tasks/{task_id}/annotations?format={upload_format_name}" + return f"/api/tasks/{task_id}/annotations?format={upload_format_name}" def _generate_url_dump_job_annotations(self, job_id): - return f"/api/v1/jobs/{job_id}/annotations" + return f"/api/jobs/{job_id}/annotations" def _generate_url_upload_job_annotations(self, job_id, upload_format_name): - return f"/api/v1/jobs/{job_id}/annotations?format={upload_format_name}" + return f"/api/jobs/{job_id}/annotations?format={upload_format_name}" def _generate_url_dump_dataset(self, task_id): - return f"/api/v1/tasks/{task_id}/dataset" + return f"/api/tasks/{task_id}/dataset" def _remove_annotations(self, tid): - response = self._delete_request(f"/api/v1/tasks/{tid}/annotations", self.admin) + response = self._delete_request(f"/api/tasks/{tid}/annotations", self.admin) self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) return response @@ -200,7 +200,7 @@ def _put_request_with_data(self, url, data, user): return response def _delete_task(self, tid): - response = self._delete_request('/api/v1/tasks/{}'.format(tid), self.admin) + response = self._delete_request('/api/tasks/{}'.format(tid), self.admin) self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) return response diff --git a/cvat/apps/engine/urls.py b/cvat/apps/engine/urls.py index 1fd820ac1477..57b6c3f600f2 100644 --- a/cvat/apps/engine/urls.py +++ b/cvat/apps/engine/urls.py @@ -70,7 +70,7 @@ def _map_format_to_schema(request, scheme=None): schema_view.with_ui('redoc', cache_timeout=0)), name='schema-redoc'), # entry point for API - path('api/v1/', include('cvat.apps.iam.urls')), - path('api/v1/', include('cvat.apps.organizations.urls')), - path('api/v1/', include(router.urls)), + path('api/', include('cvat.apps.iam.urls')), + path('api/', include('cvat.apps.organizations.urls')), + path('api/', include(router.urls)), ] diff --git a/cvat/apps/engine/views.py b/cvat/apps/engine/views.py index 50cf67cb4b0b..bf45cb2d9aa2 100644 --- a/cvat/apps/engine/views.py +++ b/cvat/apps/engine/views.py @@ -326,7 +326,7 @@ def dataset(self, request, pk): return _import_project_dataset( request=request, - rq_id=f"/api/v1/project/{pk}/dataset_import", + rq_id=f"/api/project/{pk}/dataset_import", rq_func=dm.project.import_dataset_as_project, pk=pk, format_name=format_name, @@ -335,7 +335,7 @@ def dataset(self, request, pk): action = request.query_params.get("action", "").lower() if action in ("import_status",): queue = django_rq.get_queue("default") - rq_job = queue.fetch_job(f"/api/v1/project/{pk}/dataset_import") + rq_job = queue.fetch_job(f"/api/project/{pk}/dataset_import") if rq_job is None: return Response(status=status.HTTP_404_NOT_FOUND) elif rq_job.is_finished: @@ -353,14 +353,14 @@ def dataset(self, request, pk): ) else: return Response( - data=self._get_rq_response('default', f'/api/v1/project/{pk}/dataset_import'), + data=self._get_rq_response('default', f'/api/project/{pk}/dataset_import'), status=status.HTTP_202_ACCEPTED ) else: format_name = request.query_params.get("format", "") return _export_annotations( db_instance=db_project, - rq_id="/api/v1/project/{}/dataset/{}".format(pk, format_name), + rq_id="/api/project/{}/dataset/{}".format(pk, format_name), request=request, action=action, callback=dm.views.export_project_as_dataset, @@ -395,7 +395,7 @@ def annotations(self, request, pk): format_name = request.query_params.get('format') if format_name: return _export_annotations(db_instance=db_project, - rq_id="/api/v1/projects/{}/annotations/{}".format(pk, format_name), + rq_id="/api/projects/{}/annotations/{}".format(pk, format_name), request=request, action=request.query_params.get("action", "").lower(), callback=dm.views.export_project_annotations, @@ -744,7 +744,7 @@ def annotations(self, request, pk): format_name = request.query_params.get('format') if format_name: return _export_annotations(db_instance=db_task, - rq_id="/api/v1/tasks/{}/annotations/{}".format(pk, format_name), + rq_id="/api/tasks/{}/annotations/{}".format(pk, format_name), request=request, action=request.query_params.get("action", "").lower(), callback=dm.views.export_task_annotations, @@ -761,7 +761,7 @@ def annotations(self, request, pk): if format_name: return _import_annotations( request=request, - rq_id="{}@/api/v1/tasks/{}/annotations/upload".format(request.user, pk), + rq_id="{}@/api/tasks/{}/annotations/upload".format(request.user, pk), rq_func=dm.task.import_task_annotations, pk=pk, format_name=format_name, @@ -791,7 +791,7 @@ def annotations(self, request, pk): @action(detail=True, methods=['GET'], serializer_class=RqStatusSerializer) def status(self, request, pk): self.get_object() # force to call check_object_permissions - response = self._get_rq_response(queue="default", job_id=f"/api/v1/tasks/{pk}") + response = self._get_rq_response(queue="default", job_id=f"/api/tasks/{pk}") serializer = RqStatusSerializer(data=response) if serializer.is_valid(raise_exception=True): @@ -871,7 +871,7 @@ def dataset_export(self, request, pk): format_name = request.query_params.get("format", "") return _export_annotations(db_instance=db_task, - rq_id="/api/v1/tasks/{}/dataset/{}".format(pk, format_name), + rq_id="/api/tasks/{}/dataset/{}".format(pk, format_name), request=request, action=request.query_params.get("action", "").lower(), callback=dm.views.export_task_as_dataset, @@ -921,7 +921,7 @@ def annotations(self, request, pk): if format_name: return _import_annotations( request=request, - rq_id="{}@/api/v1/jobs/{}/annotations/upload".format(request.user, pk), + rq_id="{}@/api/jobs/{}/annotations/upload".format(request.user, pk), rq_func=dm.task.import_job_annotations, pk=pk, format_name=format_name diff --git a/cvat/apps/lambda_manager/tests/test_lambda.py b/cvat/apps/lambda_manager/tests/test_lambda.py index e7a086be00f8..39c71606ebd6 100644 --- a/cvat/apps/lambda_manager/tests/test_lambda.py +++ b/cvat/apps/lambda_manager/tests/test_lambda.py @@ -16,7 +16,7 @@ from rest_framework import status from rest_framework.test import APIClient, APITestCase -LAMBDA_ROOT_PATH = '/api/v1/lambda' +LAMBDA_ROOT_PATH = '/api/lambda' LAMBDA_FUNCTIONS_PATH = f'{LAMBDA_ROOT_PATH}/functions' LAMBDA_REQUESTS_PATH = f'{LAMBDA_ROOT_PATH}/requests' @@ -154,15 +154,15 @@ def _create_db_users(cls): def _create_task(self, data, image_data): with ForceLogin(self.admin, self.client): - response = self.client.post('/api/v1/tasks', data=data, format="json") + response = self.client.post('/api/tasks', data=data, format="json") assert response.status_code == status.HTTP_201_CREATED, response.status_code tid = response.data["id"] - response = self.client.post("/api/v1/tasks/%s/data" % tid, + response = self.client.post("/api/tasks/%s/data" % tid, data=image_data) assert response.status_code == status.HTTP_202_ACCEPTED, response.status_code - response = self.client.get("/api/v1/tasks/%s" % tid) + response = self.client.get("/api/tasks/%s" % tid) task = response.data return task diff --git a/cvat/apps/lambda_manager/urls.py b/cvat/apps/lambda_manager/urls.py index f490f714db09..198cbe70e44c 100644 --- a/cvat/apps/lambda_manager/urls.py +++ b/cvat/apps/lambda_manager/urls.py @@ -16,14 +16,14 @@ router.register('functions', views.FunctionViewSet, basename='function') router.register('requests', views.RequestViewSet, basename='request') -# GET /api/v1/lambda/functions - get list of functions -# GET /api/v1/lambda/functions/ - get information about the function -# POST /api/v1/lambda/requests - call a function +# GET /api/lambda/functions - get list of functions +# GET /api/lambda/functions/ - get information about the function +# POST /api/lambda/requests - call a function # { "function": "", "mode": "online|offline", "job": "", "frame": "", # "points": [...], } -# GET /api/v1/lambda/requests - get list of requests -# GET /api/v1/lambda/requests/ - get status of the request -# DEL /api/v1/lambda/requests/ - cancel a request (don't delete) +# GET /api/lambda/requests - get list of requests +# GET /api/lambda/requests/ - get status of the request +# DEL /api/lambda/requests/ - cancel a request (don't delete) urlpatterns = [ - path('api/v1/lambda/', include((router.urls, 'cvat'), namespace='v1')) + path('api/lambda/', include((router.urls, 'cvat'), namespace='v1')) ] diff --git a/cvat/apps/restrictions/tests.py b/cvat/apps/restrictions/tests.py index 3b31c8cb1afa..19c6843fec2d 100644 --- a/cvat/apps/restrictions/tests.py +++ b/cvat/apps/restrictions/tests.py @@ -37,7 +37,7 @@ def tearDown(self): settings.RESTRICTIONS['user_agreements'] = self.user_agreements def _get_user_agreements(self): - response = self.client.get('/api/v1/restrictions/user-agreements') + response = self.client.get('/api/restrictions/user-agreements') assert response.status_code == status.HTTP_200_OK for agreements in response.data: assert 'name' in agreements, agreements['name'] @@ -46,7 +46,7 @@ def _get_user_agreements(self): return response.data def _register_user(self, data): - response = self.client.post('/api/v1/auth/register', data=data, format="json") + response = self.client.post('/api/auth/register', data=data, format="json") return response diff --git a/cvat/settings/base.py b/cvat/settings/base.py index c7593eaa3007..39840c59dba4 100644 --- a/cvat/settings/base.py +++ b/cvat/settings/base.py @@ -139,6 +139,9 @@ def add_ssh_keys(): 'rest_framework.parsers.MultiPartParser', 'cvat.apps.engine.parsers.TusUploadParser', ], + 'DEFAULT_RENDERER_CLASSES': [ + 'cvat.apps.engine.renderers.CVATAPIRenderer', + ], 'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.IsAuthenticated', 'cvat.apps.iam.permissions.IsMemberInOrganization', @@ -154,9 +157,9 @@ def add_ssh_keys(): # Don't try to use URLPathVersioning. It will give you /api/{version} # in path and '/api/docs' will not collapse similar items (flat list # of all possible methods isn't readable). - 'rest_framework.versioning.NamespaceVersioning', + 'rest_framework.versioning.AcceptHeaderVersioning', # Need to add 'api-docs' here as a workaround for include_docs_urls. - 'ALLOWED_VERSIONS': ('v1', 'api-docs'), + 'ALLOWED_VERSIONS': ('1.0', 'api-docs'), 'DEFAULT_PAGINATION_CLASS': 'cvat.apps.engine.pagination.CustomPagination', 'PAGE_SIZE': 10, diff --git a/cvat/urls.py b/cvat/urls.py index 54e18d2cbcae..629287fecbb4 100644 --- a/cvat/urls.py +++ b/cvat/urls.py @@ -44,4 +44,4 @@ urlpatterns.append(path('profiler/', include('silk.urls'))) if apps.is_installed('cvat.apps.training'): - urlpatterns.append(path('api/v1/predict/', include('cvat.apps.training.urls'))) + urlpatterns.append(path('api/predict/', include('cvat.apps.training.urls'))) diff --git a/site/config.toml b/site/config.toml index 1388566d24f4..12cf28a6d6ea 100644 --- a/site/config.toml +++ b/site/config.toml @@ -89,7 +89,7 @@ section = ["HTML", "print"] [params] intel_terms_of_use = "https://www.intel.com/content/www/us/en/legal/terms-of-use.html" intel_privacy_notice = "https://www.intel.com/content/www/us/en/privacy/intel-privacy-notice.html" -cvat_terms_of_use = "https://cvat.org/api/v1/restrictions/terms-of-use" +cvat_terms_of_use = "https://cvat.org/api/restrictions/terms-of-use" # First one is picked as the Twitter card image if not set on page. # images = ["images/project-illustration.png"] diff --git a/site/content/en/docs/contributing/rest-api-design.md b/site/content/en/docs/contributing/rest-api-design.md index 4444f7a52fc2..48959101f371 100644 --- a/site/content/en/docs/contributing/rest-api-design.md +++ b/site/content/en/docs/contributing/rest-api-design.md @@ -21,7 +21,7 @@ Common scheme for our REST API is ` [namespace] `. ## Design principles - Use nouns instead of verbs in endpoint paths. For example, - `POST /api/v1/tasks` instead of `POST /api/v1/tasks/create`. + `POST /api/tasks` instead of `POST /api/tasks/create`. - Accept and respond with JSON whenever it is possible - Name collections with plural nouns (e.g. `/tasks`, `/projects`) - Try to keep the API structure flat. Prefer two separate endpoints @@ -36,7 +36,7 @@ Common scheme for our REST API is ` [namespace] `. - Allow filtering, sorting, and pagination - Maintain good security practices - Cache data to improve performance -- Versioning our APIs (e.g. `/api/v1`, `/api/v2`). It should be done when you +- Versioning our APIs (e.g. `/api`, `/api/v2`). It should be done when you delete an endpoint or modify its behaviors. ## Links diff --git a/site/content/en/docs/manual/advanced/backup.md b/site/content/en/docs/manual/advanced/backup.md index ddd6ffe9653c..14a07f822149 100644 --- a/site/content/en/docs/manual/advanced/backup.md +++ b/site/content/en/docs/manual/advanced/backup.md @@ -54,7 +54,7 @@ As a result, you'll get a task containing data, parameters, and annotations of t ### Create from backup API -- endpoint: `/api/v1/tasks/backup` or `/api/v1/projects/backup` +- endpoint: `/api/tasks/backup` or `/api/projects/backup` - method: `POST` - Content-Type: `multipart/form-data` - responses: 202, 201 with json payload diff --git a/site/content/en/docs/manual/advanced/serverless-tutorial.md b/site/content/en/docs/manual/advanced/serverless-tutorial.md index 10c662adf07a..8c7adc0e8f9a 100644 --- a/site/content/en/docs/manual/advanced/serverless-tutorial.md +++ b/site/content/en/docs/manual/advanced/serverless-tutorial.md @@ -914,10 +914,10 @@ docker logs cvat ``` ``` 2021-07-06 13:44:54,699 DEBG 'runserver' stderr output: -[Tue Jul 06 13:44:54.699431 2021] [wsgi:error] [pid 625:tid 140010969868032] [remote 172.28.0.3:40972] [2021-07-06 13:44:54,699] ERROR django.request: Internal Server Error: /api/v1/lambda/functions/pth.shiyinzhang.iog +[Tue Jul 06 13:44:54.699431 2021] [wsgi:error] [pid 625:tid 140010969868032] [remote 172.28.0.3:40972] [2021-07-06 13:44:54,699] ERROR django.request: Internal Server Error: /api/lambda/functions/pth.shiyinzhang.iog 2021-07-06 13:44:54,700 DEBG 'runserver' stderr output: -[Tue Jul 06 13:44:54.699712 2021] [wsgi:error] [pid 625:tid 140010969868032] [remote 172.28.0.3:40972] ERROR - 2021-07-06 13:44:54,699 - log - Internal Server Error: /api/v1/lambda/functions/pth.shiyinzhang.iog +[Tue Jul 06 13:44:54.699712 2021] [wsgi:error] [pid 625:tid 140010969868032] [remote 172.28.0.3:40972] ERROR - 2021-07-06 13:44:54,699 - log - Internal Server Error: /api/lambda/functions/pth.shiyinzhang.iog ``` ```bash diff --git a/tests/cypress/integration/actions_tasks/case_52_dump_upload_annotation.js b/tests/cypress/integration/actions_tasks/case_52_dump_upload_annotation.js index e7de6a1f3e2a..d895dd4ff3ba 100644 --- a/tests/cypress/integration/actions_tasks/case_52_dump_upload_annotation.js +++ b/tests/cypress/integration/actions_tasks/case_52_dump_upload_annotation.js @@ -1,4 +1,4 @@ -// Copyright (C) 2021 Intel Corporation +// Copyright (C) 2021-2022 Intel Corporation // // SPDX-License-Identifier: MIT @@ -117,7 +117,7 @@ context('Dump/Upload annotation.', { browser: '!firefox' }, () => { cy.get('input[type=file]').attachFile(annotationArchiveName); }); confirmUpdate('.cvat-modal-content-load-job-annotation'); - cy.intercept('GET', '/api/v1/jobs/**/annotations**').as('uploadAnnotationsGet'); + cy.intercept('GET', '/api/jobs/**/annotations**').as('uploadAnnotationsGet'); cy.wait('@uploadAnnotationsGet').its('response.statusCode').should('equal', 200); cy.get('#cvat_canvas_shape_1').should('exist'); cy.get('#cvat-objects-sidebar-state-item-1').should('exist'); diff --git a/tests/cypress/integration/actions_tasks/issue_2473_import_annotations_frames_dots_in_name.js b/tests/cypress/integration/actions_tasks/issue_2473_import_annotations_frames_dots_in_name.js index de726e414178..e1c4f6528c90 100644 --- a/tests/cypress/integration/actions_tasks/issue_2473_import_annotations_frames_dots_in_name.js +++ b/tests/cypress/integration/actions_tasks/issue_2473_import_annotations_frames_dots_in_name.js @@ -1,4 +1,4 @@ -// Copyright (C) 2021 Intel Corporation +// Copyright (C) 2021-2022 Intel Corporation // // SPDX-License-Identifier: MIT @@ -65,7 +65,7 @@ context('Import annotations for frames with dots in name.', { browser: '!firefox describe(`Testing case "${issueId}"`, () => { it('Save job. Dump annotation to YOLO format. Remove annotation. Save job.', () => { cy.saveJob('PATCH', 200, 'saveJobDump'); - cy.intercept('GET', '/api/v1/tasks/**/annotations**').as('dumpAnnotations'); + cy.intercept('GET', '/api/tasks/**/annotations**').as('dumpAnnotations'); cy.interactMenu('Export task dataset'); cy.get('.cvat-modal-export-task').find('.cvat-modal-export-select').click(); cy.get('.ant-select-dropdown') @@ -105,7 +105,7 @@ context('Import annotations for frames with dots in name.', { browser: '!firefox .get('input[type=file]') .attachFile(annotationArchiveName); }); - cy.intercept('GET', '/api/v1/jobs/**/annotations?**').as('uploadAnnotationsGet'); + cy.intercept('GET', '/api/jobs/**/annotations?**').as('uploadAnnotationsGet'); confirmUpdate('.cvat-modal-content-load-job-annotation'); cy.wait('@uploadAnnotationsGet').its('response.statusCode').should('equal', 200); cy.get('.cvat-notification-notice-upload-annotations-fail').should('not.exist'); diff --git a/tests/cypress/integration/actions_tasks2/case_35_search_task_feature.js b/tests/cypress/integration/actions_tasks2/case_35_search_task_feature.js index b3a4e75a0c75..0129681544db 100644 --- a/tests/cypress/integration/actions_tasks2/case_35_search_task_feature.js +++ b/tests/cypress/integration/actions_tasks2/case_35_search_task_feature.js @@ -1,4 +1,4 @@ -// Copyright (C) 2020-2021 Intel Corporation +// Copyright (C) 2020-2022 Intel Corporation // // SPDX-License-Identifier: MIT @@ -10,7 +10,7 @@ context('Search task feature.', () => { const caseId = '35'; function searchTask(option, result) { - cy.intercept('GET', '/api/v1/tasks**').as('searchTask'); + cy.intercept('GET', '/api/tasks**').as('searchTask'); cy.get('.cvat-search-field').find('[placeholder="Search"]').clear().type(`${option}{Enter}`); cy.wait('@searchTask').its('response.statusCode').should('equal', 200); cy.get('.cvat-spinner').should('not.exist'); diff --git a/tests/cypress/integration/actions_tasks2/case_97_export_import_task.js b/tests/cypress/integration/actions_tasks2/case_97_export_import_task.js index afed3cdfa715..bf894b312243 100644 --- a/tests/cypress/integration/actions_tasks2/case_97_export_import_task.js +++ b/tests/cypress/integration/actions_tasks2/case_97_export_import_task.js @@ -1,4 +1,4 @@ -// Copyright (C) 2021 Intel Corporation +// Copyright (C) 2021-2022 Intel Corporation // // SPDX-License-Identifier: MIT @@ -93,7 +93,7 @@ context('Export, import an annotation task.', { browser: '!firefox' }, () => { }); it('Import the task. Check id, labels, shape.', () => { - cy.intercept('POST', '/api/v1/tasks/backup?**').as('importTask'); + cy.intercept('POST', '/api/tasks/backup?**').as('importTask'); cy.get('.cvat-import-task').click().find('input[type=file]').attachFile(taskBackupArchiveFullName); cy.wait('@importTask', { timeout: 5000 }).its('response.statusCode').should('equal', 202); cy.wait('@importTask').its('response.statusCode').should('equal', 201); diff --git a/tests/cypress/integration/actions_tasks3/case_109_dummy_cloud_storage.js b/tests/cypress/integration/actions_tasks3/case_109_dummy_cloud_storage.js index 52cd134c4f4d..edc47e97e282 100644 --- a/tests/cypress/integration/actions_tasks3/case_109_dummy_cloud_storage.js +++ b/tests/cypress/integration/actions_tasks3/case_109_dummy_cloud_storage.js @@ -1,4 +1,4 @@ -// Copyright (C) 2021 Intel Corporation +// Copyright (C) 2021-2022 Intel Corporation // // SPDX-License-Identifier: MIT @@ -15,7 +15,7 @@ context('Dummy cloud storages.', { browser: '!firefox' }, () => { const imageFolder = '../integration/actions_tasks3/assets/case_109'; function testListDummyCloudStorages(dummyCS) { - cy.intercept('GET', 'api/v1/cloudstorages?**', dummyCS).as('listCS'); + cy.intercept('GET', 'api/cloudstorages?**', dummyCS).as('listCS'); cy.contains('.cvat-header-button', 'Cloud Storages').should('be.visible').click(); cy.wait('@listCS').its('response.statusCode').should('eq', 200); cy.get('.cvat-cloud-storage-item-empty-preview').should('have.length', 1); @@ -57,10 +57,10 @@ context('Dummy cloud storages.', { browser: '!firefox' }, () => { } function testCSSetStatusPreview(id, status, image) { - cy.intercept('GET', `api/v1/cloudstorages/${id}/status?**`, status).as('csStatus'); + cy.intercept('GET', `api/cloudstorages/${id}/status?**`, status).as('csStatus'); cy.intercept( 'GET', - `api/v1/cloudstorages/${id}/preview?**`, + `api/cloudstorages/${id}/preview?**`, { fixture: `${imageFolder}/${image}` }, ).as('csPreview'); diff --git a/tests/cypress/integration/actions_tasks3/case_44_changing_default_value_for_attribute.js b/tests/cypress/integration/actions_tasks3/case_44_changing_default_value_for_attribute.js index a22ac3034561..542588a6cd4d 100644 --- a/tests/cypress/integration/actions_tasks3/case_44_changing_default_value_for_attribute.js +++ b/tests/cypress/integration/actions_tasks3/case_44_changing_default_value_for_attribute.js @@ -1,4 +1,4 @@ -// Copyright (C) 2021 Intel Corporation +// Copyright (C) 2021-2022 Intel Corporation // // SPDX-License-Identifier: MIT @@ -33,14 +33,14 @@ context('Changing a default value for an attribute.', () => { describe(`Testing case "${caseId}", issue 2968`, () => { it('Add a label, add text (leave it’s value empty by default) & checkbox attributes.', () => { - cy.intercept('PATCH', '/api/v1/tasks/**').as('patchTask'); + cy.intercept('PATCH', '/api/tasks/**').as('patchTask'); cy.addNewLabel(additionalLabel, additionalAttrsLabel); cy.wait('@patchTask').its('response.statusCode').should('equal', 200); cy.get('.cvat-constructor-viewer').should('exist').and('be.visible'); }); it('Open label editor. Change default values for text & checkbox attributes, press Done.', () => { - cy.intercept('PATCH', '/api/v1/tasks/**').as('patchTask'); + cy.intercept('PATCH', '/api/tasks/**').as('patchTask'); cy.get('.cvat-constructor-viewer').within(() => { // eslint-disable-next-line security/detect-non-literal-regexp cy.contains(new RegExp(`^${additionalLabel}$`)) diff --git a/tests/cypress/integration/actions_users/issue_1810_login_logout.js b/tests/cypress/integration/actions_users/issue_1810_login_logout.js index 142d2c40821b..62bf7f9be4d8 100644 --- a/tests/cypress/integration/actions_users/issue_1810_login_logout.js +++ b/tests/cypress/integration/actions_users/issue_1810_login_logout.js @@ -1,4 +1,4 @@ -// Copyright (C) 2020-2021 Intel Corporation +// Copyright (C) 2020-2022 Intel Corporation // // SPDX-License-Identifier: MIT @@ -59,7 +59,7 @@ context('When clicking on the Logout button, get the user session closed.', () = // get token and login to task cy.request({ method: 'POST', - url: '/api/v1/auth/login', + url: '/api/auth/login', body: { username: Cypress.env('user'), email: Cypress.env('email'), diff --git a/tests/cypress/integration/actions_users/registration_involved/case_28_review_pipeline_feature.js b/tests/cypress/integration/actions_users/registration_involved/case_28_review_pipeline_feature.js index ca134e264f56..49ac60076ea8 100644 --- a/tests/cypress/integration/actions_users/registration_involved/case_28_review_pipeline_feature.js +++ b/tests/cypress/integration/actions_users/registration_involved/case_28_review_pipeline_feature.js @@ -207,7 +207,7 @@ context('Review pipeline feature', () => { }); it('Second user sends the job to review.', () => { - cy.intercept('POST', '/api/v1/server/logs').as('sendLogs'); + cy.intercept('POST', '/api/server/logs').as('sendLogs'); cy.interactMenu('Request a review'); cy.contains('.cvat-modal-content-save-job', 'The job has unsaved annotations') .should('exist') diff --git a/tests/cypress/integration/actions_users/registration_involved/case_4_assign_taks_job_users.js b/tests/cypress/integration/actions_users/registration_involved/case_4_assign_taks_job_users.js index 82d9e7ae2d94..0463d4d0093a 100644 --- a/tests/cypress/integration/actions_users/registration_involved/case_4_assign_taks_job_users.js +++ b/tests/cypress/integration/actions_users/registration_involved/case_4_assign_taks_job_users.js @@ -48,7 +48,7 @@ context('Multiple users. Assign task, job. Deactivating users.', () => { function changeCheckUserStatusOpenTask(userName) { cy.changeUserActiveStatus(authKey, userName, isActive); cy.checkUserStatuses(authKey, userName, isStaff, isSuperuser, isActive); - cy.intercept('GET', `/api/v1/users*${thirdUserName}*`).as('users'); + cy.intercept('GET', `/api/users*${thirdUserName}*`).as('users'); cy.openTask(taskName); cy.wait('@users'); cy.get('.cvat-global-boundary').should('not.exist'); @@ -161,7 +161,7 @@ context('Multiple users. Assign task, job. Deactivating users.', () => { it('First user login. Getting authKey.', () => { cy.visit('/'); - cy.intercept('POST', '/api/v1/auth/login**').as('login'); + cy.intercept('POST', '/api/auth/login**').as('login'); cy.login(); cy.wait('@login').then((response) => { authKey = response.response.body.key; diff --git a/tests/cypress/integration/canvas3d_functionality/case_91_canvas3d_functionality_dump_upload_annotation_point_cloud_format.js b/tests/cypress/integration/canvas3d_functionality/case_91_canvas3d_functionality_dump_upload_annotation_point_cloud_format.js index dc840d472fba..c0371417ac06 100644 --- a/tests/cypress/integration/canvas3d_functionality/case_91_canvas3d_functionality_dump_upload_annotation_point_cloud_format.js +++ b/tests/cypress/integration/canvas3d_functionality/case_91_canvas3d_functionality_dump_upload_annotation_point_cloud_format.js @@ -1,4 +1,4 @@ -// Copyright (C) 2021 Intel Corporation +// Copyright (C) 2021-2022 Intel Corporation // // SPDX-License-Identifier: MIT @@ -75,7 +75,7 @@ context('Canvas 3D functionality. Dump/upload annotation. "Point Cloud" format', }); }); confirmUpdate('.cvat-modal-content-load-job-annotation'); - cy.intercept('GET', '/api/v1/jobs/**/annotations**').as('uploadAnnotationsGet'); + cy.intercept('GET', '/api/jobs/**/annotations**').as('uploadAnnotationsGet'); cy.wait('@uploadAnnotationsGet').its('response.statusCode').should('equal', 200); cy.get('#cvat-objects-sidebar-state-item-1').should('exist'); cy.removeAnnotations(); diff --git a/tests/cypress/integration/canvas3d_functionality/case_92_canvas3d_functionality_dump_upload_annotation_velodyne_points_format.js b/tests/cypress/integration/canvas3d_functionality/case_92_canvas3d_functionality_dump_upload_annotation_velodyne_points_format.js index c56d543e6828..ad67811d3deb 100644 --- a/tests/cypress/integration/canvas3d_functionality/case_92_canvas3d_functionality_dump_upload_annotation_velodyne_points_format.js +++ b/tests/cypress/integration/canvas3d_functionality/case_92_canvas3d_functionality_dump_upload_annotation_velodyne_points_format.js @@ -1,4 +1,4 @@ -// Copyright (C) 2021 Intel Corporation +// Copyright (C) 2021-2022 Intel Corporation // // SPDX-License-Identifier: MIT @@ -75,7 +75,7 @@ context('Canvas 3D functionality. Dump/upload annotation. "Velodyne Points" form }); }); confirmUpdate('.cvat-modal-content-load-job-annotation'); - cy.intercept('GET', '/api/v1/jobs/**/annotations**').as('uploadAnnotationsGet'); + cy.intercept('GET', '/api/jobs/**/annotations**').as('uploadAnnotationsGet'); cy.wait('@uploadAnnotationsGet').its('response.statusCode').should('equal', 200); cy.get('#cvat-objects-sidebar-state-item-1').should('exist'); cy.removeAnnotations(); diff --git a/tests/cypress/integration/email_system/check_email_verification_system.js b/tests/cypress/integration/email_system/check_email_verification_system.js index d5f9803085b6..6450866dddf7 100644 --- a/tests/cypress/integration/email_system/check_email_verification_system.js +++ b/tests/cypress/integration/email_system/check_email_verification_system.js @@ -1,4 +1,4 @@ -// Copyright (C) 2020-2021 Intel Corporation +// Copyright (C) 2020-2022 Intel Corporation // // SPDX-License-Identifier: MIT @@ -28,7 +28,7 @@ context('Check email verification system', () => { describe(`Case: "${caseId}"`, () => { it('Register user. Notification exist. The response status is successful.', () => { - cy.intercept('POST', '/api/v1/auth/register?**').as('userRegister'); + cy.intercept('POST', '/api/auth/register?**').as('userRegister'); cy.userRegistration(firstName, lastName, userName, emailAddr, password); cy.get('.ant-notification-topRight') .contains(`We have sent an email with a confirmation link to ${emailAddr}.`) diff --git a/tests/cypress/integration/issues_prs/pr_2203_error_cannot_read_property_at_saving_job.js b/tests/cypress/integration/issues_prs/pr_2203_error_cannot_read_property_at_saving_job.js index 4202dd5718d6..66ec8b43a256 100644 --- a/tests/cypress/integration/issues_prs/pr_2203_error_cannot_read_property_at_saving_job.js +++ b/tests/cypress/integration/issues_prs/pr_2203_error_cannot_read_property_at_saving_job.js @@ -1,4 +1,4 @@ -// Copyright (C) 2020-2021 Intel Corporation +// Copyright (C) 2020-2022 Intel Corporation // // SPDX-License-Identifier: MIT @@ -38,7 +38,7 @@ context('Check error сannot read property at saving job', () => { }); it('Save job and go to previous frame at saving job', () => { - cy.intercept('PATCH', '/api/v1/jobs/**').as('saveJob'); + cy.intercept('PATCH', '/api/jobs/**').as('saveJob'); cy.saveJob(); cy.get('body').type('d'); cy.wait('@saveJob').its('response.statusCode').should('equal', 200); diff --git a/tests/cypress/integration/remove_users_tasks_projects_organizations.js b/tests/cypress/integration/remove_users_tasks_projects_organizations.js index 913b0e53c7bc..407e8a42e38a 100644 --- a/tests/cypress/integration/remove_users_tasks_projects_organizations.js +++ b/tests/cypress/integration/remove_users_tasks_projects_organizations.js @@ -10,7 +10,7 @@ describe('Delete users, tasks, projects, organizations created during the tests it('Get token', () => { cy.request({ method: 'POST', - url: '/api/v1/auth/login', + url: '/api/auth/login', body: { username: Cypress.env('user'), email: Cypress.env('email'), @@ -23,7 +23,7 @@ describe('Delete users, tasks, projects, organizations created during the tests it('Get a list of tasks and delete them all', () => { cy.request({ - url: '/api/v1/tasks?page_size=1000', + url: '/api/tasks?page_size=1000', headers: { Authorization: `Token ${authKey}`, }, @@ -33,7 +33,7 @@ describe('Delete users, tasks, projects, organizations created during the tests const { id } = task; cy.request({ method: 'DELETE', - url: `/api/v1/tasks/${id}`, + url: `/api/tasks/${id}`, headers: { Authorization: `Token ${authKey}`, }, @@ -44,7 +44,7 @@ describe('Delete users, tasks, projects, organizations created during the tests it('Get a list of projects and delete them all', () => { cy.request({ - url: '/api/v1/projects?page_size=all', + url: '/api/projects?page_size=all', headers: { Authorization: `Token ${authKey}`, }, @@ -54,7 +54,7 @@ describe('Delete users, tasks, projects, organizations created during the tests const { id } = project; cy.request({ method: 'DELETE', - url: `/api/v1/projects/${id}`, + url: `/api/projects/${id}`, headers: { Authorization: `Token ${authKey}`, }, @@ -65,7 +65,7 @@ describe('Delete users, tasks, projects, organizations created during the tests it('Get a list of organizations and delete them all', () => { cy.request({ - url: '/api/v1/organizations?page_size=all', + url: '/api/organizations?page_size=all', headers: { Authorization: `Token ${authKey}`, }, @@ -75,7 +75,7 @@ describe('Delete users, tasks, projects, organizations created during the tests const { id } = org; cy.request({ method: 'DELETE', - url: `/api/v1/organizations/${id}`, + url: `/api/organizations/${id}`, headers: { Authorization: `Token ${authKey}`, }, @@ -86,7 +86,7 @@ describe('Delete users, tasks, projects, organizations created during the tests it('Get a list of users and delete all except id:1', () => { cy.request({ - url: '/api/v1/users', + url: '/api/users', headers: { Authorization: `Token ${authKey}`, }, @@ -97,7 +97,7 @@ describe('Delete users, tasks, projects, organizations created during the tests if (id !== 1) { cy.request({ method: 'DELETE', - url: `/api/v1/users/${id}`, + url: `/api/users/${id}`, headers: { Authorization: `Token ${authKey}`, }, diff --git a/tests/cypress/support/commands.js b/tests/cypress/support/commands.js index 82ce94ce2d4f..08cc6abaefa8 100644 --- a/tests/cypress/support/commands.js +++ b/tests/cypress/support/commands.js @@ -55,7 +55,7 @@ Cypress.Commands.add('userRegistration', (firstName, lastName, userName, emailAd Cypress.Commands.add('getAuthKey', () => { cy.request({ method: 'POST', - url: '/api/v1/auth/login', + url: '/api/auth/login', body: { username: Cypress.env('user'), email: Cypress.env('email'), @@ -67,7 +67,7 @@ Cypress.Commands.add('getAuthKey', () => { Cypress.Commands.add('deleteUsers', (authResponse, accountsToDelete) => { const authKey = authResponse.body.key; cy.request({ - url: '/api/v1/users?page_size=all', + url: '/api/users?page_size=all', headers: { Authorization: `Token ${authKey}`, }, @@ -79,7 +79,7 @@ Cypress.Commands.add('deleteUsers', (authResponse, accountsToDelete) => { if (username === account) { cy.request({ method: 'DELETE', - url: `/api/v1/users/${id}`, + url: `/api/users/${id}`, headers: { Authorization: `Token ${authKey}`, }, @@ -92,7 +92,7 @@ Cypress.Commands.add('deleteUsers', (authResponse, accountsToDelete) => { Cypress.Commands.add('changeUserActiveStatus', (authKey, accountsToChangeActiveStatus, isActive) => { cy.request({ - url: '/api/v1/users?page_size=all', + url: '/api/users?page_size=all', headers: { Authorization: `Token ${authKey}`, }, @@ -104,7 +104,7 @@ Cypress.Commands.add('changeUserActiveStatus', (authKey, accountsToChangeActiveS if (userName.includes(accountsToChangeActiveStatus)) { cy.request({ method: 'PATCH', - url: `/api/v1/users/${userId}`, + url: `/api/users/${userId}`, headers: { Authorization: `Token ${authKey}`, }, @@ -119,7 +119,7 @@ Cypress.Commands.add('changeUserActiveStatus', (authKey, accountsToChangeActiveS Cypress.Commands.add('checkUserStatuses', (authKey, userName, staffStatus, superuserStatus, activeStatus) => { cy.request({ - url: '/api/v1/users?page_size=all', + url: '/api/users?page_size=all', headers: { Authorization: `Token ${authKey}`, }, @@ -138,7 +138,7 @@ Cypress.Commands.add('checkUserStatuses', (authKey, userName, staffStatus, super Cypress.Commands.add('deleteTasks', (authResponse, tasksToDelete) => { const authKey = authResponse.body.key; cy.request({ - url: '/api/v1/tasks?page_size=all', + url: '/api/tasks?page_size=all', headers: { Authorization: `Token ${authKey}`, }, @@ -150,7 +150,7 @@ Cypress.Commands.add('deleteTasks', (authResponse, tasksToDelete) => { if (name === taskToDelete) { cy.request({ method: 'DELETE', - url: `/api/v1/tasks/${id}`, + url: `/api/tasks/${id}`, headers: { Authorization: `Token ${authKey}`, }, @@ -232,7 +232,7 @@ Cypress.Commands.add('openTask', (taskName, projectSubsetFieldValue) => { }); Cypress.Commands.add('saveJob', (method = 'PATCH', status = 200, as = 'saveJob') => { - cy.intercept(method, '/api/v1/jobs/**').as(as); + cy.intercept(method, '/api/jobs/**').as(as); cy.get('button').contains('Save').click({ force: true }).trigger('mouseout'); cy.wait(`@${as}`).its('response.statusCode').should('equal', status); }); diff --git a/tests/cypress/support/commands_organizations.js b/tests/cypress/support/commands_organizations.js index e3df85c48bd9..7dcf6034a8b4 100644 --- a/tests/cypress/support/commands_organizations.js +++ b/tests/cypress/support/commands_organizations.js @@ -22,7 +22,7 @@ Cypress.Commands.add('createOrganization', (organizationParams) => { cy.get('#email').type(organizationParams.email); cy.get('#phoneNumber').type(organizationParams.phoneNumber); cy.get('#location').type(organizationParams.location); - cy.intercept('POST', '/api/v1/organizations**').as('createOrganizations'); + cy.intercept('POST', '/api/organizations**').as('createOrganizations'); cy.get('[type="submit"]').click(); cy.wait('@createOrganizations').its('response.statusCode').should('equal', 201); }); @@ -31,7 +31,7 @@ Cypress.Commands.add('createOrganization', (organizationParams) => { Cypress.Commands.add('deleteOrganizations', (authResponse, otrganizationsToDelete) => { const authKey = authResponse.body.key; cy.request({ - url: '/api/v1/organizations?page_size=all', + url: '/api/organizations?page_size=all', headers: { Authorization: `Token ${authKey}`, }, @@ -43,7 +43,7 @@ Cypress.Commands.add('deleteOrganizations', (authResponse, otrganizationsToDelet if (slug === organizationToDelete) { cy.request({ method: 'DELETE', - url: `/api/v1/organizations/${id}`, + url: `/api/organizations/${id}`, headers: { Authorization: `Token ${authKey}`, }, diff --git a/tests/cypress/support/commands_projects.js b/tests/cypress/support/commands_projects.js index e0544c383779..aa84a0a11076 100644 --- a/tests/cypress/support/commands_projects.js +++ b/tests/cypress/support/commands_projects.js @@ -41,7 +41,7 @@ Cypress.Commands.add( Cypress.Commands.add('deleteProjects', (authResponse, projectsToDelete) => { const authKey = authResponse.body.key; cy.request({ - url: '/api/v1/projects?page_size=all', + url: '/api/projects?page_size=all', headers: { Authorization: `Token ${authKey}`, }, @@ -53,7 +53,7 @@ Cypress.Commands.add('deleteProjects', (authResponse, projectsToDelete) => { if (name === projectToDelete) { cy.request({ method: 'DELETE', - url: `/api/v1/projects/${id}`, + url: `/api/projects/${id}`, headers: { Authorization: `Token ${authKey}`, }, @@ -118,7 +118,7 @@ Cypress.Commands.add('backupProject', (projectName) => { }); Cypress.Commands.add('restoreProject', (archiveWithBackup) => { - cy.intercept('POST', '/api/v1/projects/backup?**').as('restoreProject'); + cy.intercept('POST', '/api/projects/backup?**').as('restoreProject'); cy.get('.cvat-import-project').click().find('input[type=file]').attachFile(archiveWithBackup); cy.wait('@restoreProject', { timeout: 5000 }).its('response.statusCode').should('equal', 202); cy.wait('@restoreProject').its('response.statusCode').should('equal', 201); diff --git a/tests/cypress/support/commands_review_pipeline.js b/tests/cypress/support/commands_review_pipeline.js index 75fbe3c9405d..249c260d5043 100644 --- a/tests/cypress/support/commands_review_pipeline.js +++ b/tests/cypress/support/commands_review_pipeline.js @@ -23,7 +23,7 @@ Cypress.Commands.add('assignJobToUser', (jobID, user) => { .click(); }); - cy.intercept('PATCH', '/api/v1/jobs/**').as('patchJobAssignee'); + cy.intercept('PATCH', '/api/jobs/**').as('patchJobAssignee'); cy.get('.ant-select-dropdown') .should('be.visible') .not('.ant-select-dropdown-hidden') @@ -146,7 +146,7 @@ Cypress.Commands.add('createIssueFromControlButton', (createIssueParams) => { .trigger('mousedown', createIssueParams.firstX, createIssueParams.firstY, { button: 0 }) .trigger('mouseup'); } - cy.intercept('POST', '/api/v1/issues?*').as('issues'); + cy.intercept('POST', '/api/issues?*').as('issues'); cy.get('.cvat-create-issue-dialog').within(() => { cy.get('#issue_description').type(createIssueParams.description); cy.get('[type="submit"]').click(); @@ -157,8 +157,8 @@ Cypress.Commands.add('createIssueFromControlButton', (createIssueParams) => { Cypress.Commands.add('resolveReopenIssue', (issueLabel, resolveText, reopen) => { cy.get(issueLabel).click(); - cy.intercept('POST', '/api/v1/comments').as('postComment'); - cy.intercept('PATCH', '/api/v1/issues/**').as('resolveReopenIssue'); + cy.intercept('POST', '/api/comments').as('postComment'); + cy.intercept('PATCH', '/api/issues/**').as('resolveReopenIssue'); cy.get('.cvat-issue-dialog-input').type(resolveText); cy.get('.cvat-issue-dialog-footer').within(() => { cy.contains('button', 'Comment').click(); @@ -175,7 +175,7 @@ Cypress.Commands.add('resolveReopenIssue', (issueLabel, resolveText, reopen) => Cypress.Commands.add('removeIssue', (issueLabel, submitRemove) => { cy.get(issueLabel).click(); - cy.intercept('DELETE', '/api/v1/issues/**').as('removeIssue'); + cy.intercept('DELETE', '/api/issues/**').as('removeIssue'); cy.get('.cvat-issue-dialog-footer').within(() => { cy.contains('button', 'Remove').click(); }); @@ -194,7 +194,7 @@ Cypress.Commands.add('submitReview', (decision, user) => { cy.get('.cvat-submit-review-dialog').within(() => { cy.contains(new RegExp(`^${decision}$`, 'g')).click(); if (decision === 'Review next') { - cy.intercept('GET', `/api/v1/users?search=${user}&limit=10&is_active=true`).as('searchUsers'); + cy.intercept('GET', `/api/users?search=${user}&limit=10&is_active=true`).as('searchUsers'); cy.get('.cvat-user-search-field').within(() => { cy.get('input[type="search"]').clear().type(`${user}`); cy.wait('@searchUsers').its('response.statusCode').should('equal', 200); diff --git a/tests/cypress/support/dummy-data.js b/tests/cypress/support/dummy-data.js index 5f0228247a68..fabe5d242cf7 100644 --- a/tests/cypress/support/dummy-data.js +++ b/tests/cypress/support/dummy-data.js @@ -10,7 +10,7 @@ const dummyGoogleStorage = { { id: 3, owner: { - url: 'http://localhost:7000/api/v1/users/1', + url: 'http://localhost:7000/api/users/1', id: 1, username: 'maya', first_name: '', @@ -39,7 +39,7 @@ const dummyAzureContainer = { { id: 2, owner: { - url: 'http://localhost:7000/api/v1/users/1', + url: 'http://localhost:7000/api/users/1', id: 1, username: 'maya', first_name: '', @@ -68,7 +68,7 @@ const dummyAWSBucket = { { id: 1, owner: { - url: 'http://localhost:7000/api/v1/users/1', + url: 'http://localhost:7000/api/users/1', id: 1, username: 'maya', first_name: '', diff --git a/tests/rest_api/README.md b/tests/rest_api/README.md index 11e27e539404..0fdffa5c47f3 100644 --- a/tests/rest_api/README.md +++ b/tests/rest_api/README.md @@ -84,7 +84,7 @@ with requests.Session() as session: session.auth = ('admin1', '!Q@W#E$R') for obj in ['user', 'project', 'task', 'job']: - response = session.get(f'http://localhost:8080/api/v1/{obj}s') + response = session.get(f'http://localhost:8080/api/{obj}s') with open(f'{obj}s.json', 'w') as f: json.dump(response.json(), f, indent=2, sort_keys=True) ``` diff --git a/tests/rest_api/assets/invitations.json b/tests/rest_api/assets/invitations.json index cf96d222b897..62bfa9f7f267 100644 --- a/tests/rest_api/assets/invitations.json +++ b/tests/rest_api/assets/invitations.json @@ -11,7 +11,7 @@ "first_name": "Business", "id": 10, "last_name": "First", - "url": "http://localhost:8080/api/v1/users/10", + "url": "http://localhost:8080/api/users/10", "username": "business1" }, "role": "supervisor", @@ -19,7 +19,7 @@ "first_name": "User", "id": 3, "last_name": "Second", - "url": "http://localhost:8080/api/v1/users/3", + "url": "http://localhost:8080/api/users/3", "username": "user2" } }, @@ -31,7 +31,7 @@ "first_name": "Business", "id": 10, "last_name": "First", - "url": "http://localhost:8080/api/v1/users/10", + "url": "http://localhost:8080/api/users/10", "username": "business1" }, "role": "worker", @@ -39,7 +39,7 @@ "first_name": "Worker", "id": 8, "last_name": "Third", - "url": "http://localhost:8080/api/v1/users/8", + "url": "http://localhost:8080/api/users/8", "username": "worker3" } }, @@ -51,7 +51,7 @@ "first_name": "Business", "id": 10, "last_name": "First", - "url": "http://localhost:8080/api/v1/users/10", + "url": "http://localhost:8080/api/users/10", "username": "business1" }, "role": "worker", @@ -59,7 +59,7 @@ "first_name": "Worker", "id": 7, "last_name": "Second", - "url": "http://localhost:8080/api/v1/users/7", + "url": "http://localhost:8080/api/users/7", "username": "worker2" } }, @@ -71,7 +71,7 @@ "first_name": "Business", "id": 10, "last_name": "First", - "url": "http://localhost:8080/api/v1/users/10", + "url": "http://localhost:8080/api/users/10", "username": "business1" }, "role": "maintainer", @@ -79,7 +79,7 @@ "first_name": "Business", "id": 11, "last_name": "Second", - "url": "http://localhost:8080/api/v1/users/11", + "url": "http://localhost:8080/api/users/11", "username": "business2" } }, @@ -91,7 +91,7 @@ "first_name": "User", "id": 2, "last_name": "First", - "url": "http://localhost:8080/api/v1/users/2", + "url": "http://localhost:8080/api/users/2", "username": "user1" }, "role": "maintainer", @@ -99,7 +99,7 @@ "first_name": "Business", "id": 10, "last_name": "First", - "url": "http://localhost:8080/api/v1/users/10", + "url": "http://localhost:8080/api/users/10", "username": "business1" } }, @@ -111,7 +111,7 @@ "first_name": "User", "id": 2, "last_name": "First", - "url": "http://localhost:8080/api/v1/users/2", + "url": "http://localhost:8080/api/users/2", "username": "user1" }, "role": "worker", @@ -119,7 +119,7 @@ "first_name": "Worker", "id": 7, "last_name": "Second", - "url": "http://localhost:8080/api/v1/users/7", + "url": "http://localhost:8080/api/users/7", "username": "worker2" } }, @@ -131,7 +131,7 @@ "first_name": "User", "id": 2, "last_name": "First", - "url": "http://localhost:8080/api/v1/users/2", + "url": "http://localhost:8080/api/users/2", "username": "user1" }, "role": "worker", @@ -139,7 +139,7 @@ "first_name": "Worker", "id": 6, "last_name": "First", - "url": "http://localhost:8080/api/v1/users/6", + "url": "http://localhost:8080/api/users/6", "username": "worker1" } } diff --git a/tests/rest_api/assets/jobs.json b/tests/rest_api/assets/jobs.json index 1ee3228d63ae..2d56927102d4 100644 --- a/tests/rest_api/assets/jobs.json +++ b/tests/rest_api/assets/jobs.json @@ -32,14 +32,14 @@ "status": "annotation", "stop_frame": 129, "task_id": 1, - "url": "http://localhost:8080/api/v1/jobs/1" + "url": "http://localhost:8080/api/jobs/1" }, { "assignee": { "first_name": "Worker", "id": 6, "last_name": "First", - "url": "http://localhost:8080/api/v1/users/6", + "url": "http://localhost:8080/api/users/6", "username": "worker1" }, "bug_tracker": null, @@ -69,7 +69,7 @@ "status": "annotation", "stop_frame": 22, "task_id": 2, - "url": "http://localhost:8080/api/v1/jobs/2" + "url": "http://localhost:8080/api/jobs/2" }, { "assignee": null, @@ -113,7 +113,7 @@ "status": "annotation", "stop_frame": 49, "task_id": 3, - "url": "http://localhost:8080/api/v1/jobs/3" + "url": "http://localhost:8080/api/jobs/3" }, { "assignee": null, @@ -157,7 +157,7 @@ "status": "validation", "stop_frame": 99, "task_id": 3, - "url": "http://localhost:8080/api/v1/jobs/4" + "url": "http://localhost:8080/api/jobs/4" }, { "assignee": null, @@ -201,14 +201,14 @@ "status": "validation", "stop_frame": 147, "task_id": 3, - "url": "http://localhost:8080/api/v1/jobs/5" + "url": "http://localhost:8080/api/jobs/5" }, { "assignee": { "first_name": "Worker", "id": 7, "last_name": "Second", - "url": "http://localhost:8080/api/v1/users/7", + "url": "http://localhost:8080/api/users/7", "username": "worker2" }, "bug_tracker": "", @@ -238,7 +238,7 @@ "status": "annotation", "stop_frame": 57, "task_id": 4, - "url": "http://localhost:8080/api/v1/jobs/6" + "url": "http://localhost:8080/api/jobs/6" } ] } \ No newline at end of file diff --git a/tests/rest_api/assets/memberships.json b/tests/rest_api/assets/memberships.json index 4e6ba5f922c1..677c8a0ea104 100644 --- a/tests/rest_api/assets/memberships.json +++ b/tests/rest_api/assets/memberships.json @@ -14,7 +14,7 @@ "first_name": "User", "id": 3, "last_name": "Second", - "url": "http://localhost:8080/api/v1/users/3", + "url": "http://localhost:8080/api/users/3", "username": "user2" } }, @@ -29,7 +29,7 @@ "first_name": "Worker", "id": 8, "last_name": "Third", - "url": "http://localhost:8080/api/v1/users/8", + "url": "http://localhost:8080/api/users/8", "username": "worker3" } }, @@ -44,7 +44,7 @@ "first_name": "Worker", "id": 7, "last_name": "Second", - "url": "http://localhost:8080/api/v1/users/7", + "url": "http://localhost:8080/api/users/7", "username": "worker2" } }, @@ -59,7 +59,7 @@ "first_name": "Business", "id": 11, "last_name": "Second", - "url": "http://localhost:8080/api/v1/users/11", + "url": "http://localhost:8080/api/users/11", "username": "business2" } }, @@ -74,7 +74,7 @@ "first_name": "Business", "id": 10, "last_name": "First", - "url": "http://localhost:8080/api/v1/users/10", + "url": "http://localhost:8080/api/users/10", "username": "business1" } }, @@ -89,7 +89,7 @@ "first_name": "Business", "id": 10, "last_name": "First", - "url": "http://localhost:8080/api/v1/users/10", + "url": "http://localhost:8080/api/users/10", "username": "business1" } }, @@ -104,7 +104,7 @@ "first_name": "Worker", "id": 7, "last_name": "Second", - "url": "http://localhost:8080/api/v1/users/7", + "url": "http://localhost:8080/api/users/7", "username": "worker2" } }, @@ -119,7 +119,7 @@ "first_name": "Worker", "id": 6, "last_name": "First", - "url": "http://localhost:8080/api/v1/users/6", + "url": "http://localhost:8080/api/users/6", "username": "worker1" } }, @@ -134,7 +134,7 @@ "first_name": "User", "id": 2, "last_name": "First", - "url": "http://localhost:8080/api/v1/users/2", + "url": "http://localhost:8080/api/users/2", "username": "user1" } } diff --git a/tests/rest_api/assets/organizations.json b/tests/rest_api/assets/organizations.json index 3b6fcabe5aad..8ca228124c94 100644 --- a/tests/rest_api/assets/organizations.json +++ b/tests/rest_api/assets/organizations.json @@ -11,7 +11,7 @@ "first_name": "Business", "id": 10, "last_name": "First", - "url": "http://localhost:8080/api/v1/users/10", + "url": "http://localhost:8080/api/users/10", "username": "business1" }, "slug": "org2", @@ -29,7 +29,7 @@ "first_name": "User", "id": 2, "last_name": "First", - "url": "http://localhost:8080/api/v1/users/2", + "url": "http://localhost:8080/api/users/2", "username": "user1" }, "slug": "org1", diff --git a/tests/rest_api/assets/projects.json b/tests/rest_api/assets/projects.json index 2d5265980c7b..f294827d97a0 100644 --- a/tests/rest_api/assets/projects.json +++ b/tests/rest_api/assets/projects.json @@ -8,7 +8,7 @@ "first_name": "User", "id": 3, "last_name": "Second", - "url": "http://localhost:8080/api/v1/users/3", + "url": "http://localhost:8080/api/users/3", "username": "user2" }, "bug_tracker": "", @@ -35,7 +35,7 @@ "first_name": "Business", "id": 10, "last_name": "First", - "url": "http://localhost:8080/api/v1/users/10", + "url": "http://localhost:8080/api/users/10", "username": "business1" }, "status": "annotation", @@ -47,7 +47,7 @@ ], "training_project": null, "updated_date": "2021-12-14T19:55:57.483506Z", - "url": "http://localhost:8080/api/v1/projects/2" + "url": "http://localhost:8080/api/projects/2" }, { "assignee": null, @@ -88,7 +88,7 @@ "first_name": "Business", "id": 10, "last_name": "First", - "url": "http://localhost:8080/api/v1/users/10", + "url": "http://localhost:8080/api/users/10", "username": "business1" }, "status": "annotation", @@ -100,7 +100,7 @@ ], "training_project": null, "updated_date": "2021-12-14T19:48:33.103265Z", - "url": "http://localhost:8080/api/v1/projects/1" + "url": "http://localhost:8080/api/projects/1" } ] } \ No newline at end of file diff --git a/tests/rest_api/assets/tasks.json b/tests/rest_api/assets/tasks.json index 382cbc6f4610..b58e51db1eff 100644 --- a/tests/rest_api/assets/tasks.json +++ b/tests/rest_api/assets/tasks.json @@ -36,7 +36,7 @@ "first_name": "Business", "id": 10, "last_name": "First", - "url": "http://localhost:8080/api/v1/users/10", + "url": "http://localhost:8080/api/users/10", "username": "business1" }, "project_id": 2, @@ -49,14 +49,14 @@ "first_name": "Worker", "id": 7, "last_name": "Second", - "url": "http://localhost:8080/api/v1/users/7", + "url": "http://localhost:8080/api/users/7", "username": "worker2" }, "id": 6, "stage": "annotation", "state": "new", "status": "annotation", - "url": "http://localhost:8080/api/v1/jobs/6" + "url": "http://localhost:8080/api/jobs/6" } ], "start_frame": 0, @@ -67,7 +67,7 @@ "status": "annotation", "subset": "train", "updated_date": "2021-12-22T07:17:34.836384Z", - "url": "http://localhost:8080/api/v1/tasks/4" + "url": "http://localhost:8080/api/tasks/4" }, { "assignee": null, @@ -115,7 +115,7 @@ "first_name": "Business", "id": 10, "last_name": "First", - "url": "http://localhost:8080/api/v1/users/10", + "url": "http://localhost:8080/api/users/10", "username": "business1" }, "project_id": 1, @@ -129,7 +129,7 @@ "stage": "annotation", "state": "new", "status": "annotation", - "url": "http://localhost:8080/api/v1/jobs/3" + "url": "http://localhost:8080/api/jobs/3" } ], "start_frame": 0, @@ -143,7 +143,7 @@ "stage": "validation", "state": "new", "status": "validation", - "url": "http://localhost:8080/api/v1/jobs/4" + "url": "http://localhost:8080/api/jobs/4" } ], "start_frame": 50, @@ -157,7 +157,7 @@ "stage": "acceptance", "state": "new", "status": "validation", - "url": "http://localhost:8080/api/v1/jobs/5" + "url": "http://localhost:8080/api/jobs/5" } ], "start_frame": 100, @@ -168,7 +168,7 @@ "status": "annotation", "subset": "Train", "updated_date": "2021-12-22T07:19:33.854760Z", - "url": "http://localhost:8080/api/v1/tasks/3" + "url": "http://localhost:8080/api/tasks/3" }, { "assignee": null, @@ -203,7 +203,7 @@ "first_name": "User", "id": 2, "last_name": "First", - "url": "http://localhost:8080/api/v1/users/2", + "url": "http://localhost:8080/api/users/2", "username": "user1" }, "project_id": null, @@ -216,14 +216,14 @@ "first_name": "Worker", "id": 6, "last_name": "First", - "url": "http://localhost:8080/api/v1/users/6", + "url": "http://localhost:8080/api/users/6", "username": "worker1" }, "id": 2, "stage": "annotation", "state": "new", "status": "annotation", - "url": "http://localhost:8080/api/v1/jobs/2" + "url": "http://localhost:8080/api/jobs/2" } ], "start_frame": 0, @@ -234,7 +234,7 @@ "status": "annotation", "subset": "", "updated_date": "2021-12-22T07:14:15.234748Z", - "url": "http://localhost:8080/api/v1/tasks/2" + "url": "http://localhost:8080/api/tasks/2" }, { "assignee": null, @@ -269,7 +269,7 @@ "first_name": "User", "id": 2, "last_name": "First", - "url": "http://localhost:8080/api/v1/users/2", + "url": "http://localhost:8080/api/users/2", "username": "user1" }, "project_id": null, @@ -283,7 +283,7 @@ "stage": "annotation", "state": "new", "status": "annotation", - "url": "http://localhost:8080/api/v1/jobs/1" + "url": "http://localhost:8080/api/jobs/1" } ], "start_frame": 0, @@ -294,7 +294,7 @@ "status": "annotation", "subset": "", "updated_date": "2021-12-22T07:15:22.942484Z", - "url": "http://localhost:8080/api/v1/tasks/1" + "url": "http://localhost:8080/api/tasks/1" } ] } \ No newline at end of file diff --git a/tests/rest_api/assets/users.json b/tests/rest_api/assets/users.json index cd460e8059eb..e7bbd437d350 100644 --- a/tests/rest_api/assets/users.json +++ b/tests/rest_api/assets/users.json @@ -16,7 +16,7 @@ "is_superuser": true, "last_login": "2021-12-22T07:32:58.602211Z", "last_name": "First", - "url": "http://localhost:8080/api/v1/users/1", + "url": "http://localhost:8080/api/users/1", "username": "admin1" }, { @@ -32,7 +32,7 @@ "is_superuser": false, "last_login": "2021-12-22T07:55:35.269206Z", "last_name": "First", - "url": "http://localhost:8080/api/v1/users/2", + "url": "http://localhost:8080/api/users/2", "username": "user1" }, { @@ -48,7 +48,7 @@ "is_superuser": false, "last_login": null, "last_name": "Second", - "url": "http://localhost:8080/api/v1/users/3", + "url": "http://localhost:8080/api/users/3", "username": "user2" }, { @@ -64,7 +64,7 @@ "is_superuser": false, "last_login": null, "last_name": "Third", - "url": "http://localhost:8080/api/v1/users/4", + "url": "http://localhost:8080/api/users/4", "username": "user3" }, { @@ -80,7 +80,7 @@ "is_superuser": false, "last_login": null, "last_name": "Fourth", - "url": "http://localhost:8080/api/v1/users/5", + "url": "http://localhost:8080/api/users/5", "username": "user4" }, { @@ -96,7 +96,7 @@ "is_superuser": false, "last_login": "2021-12-14T19:11:21.048740Z", "last_name": "First", - "url": "http://localhost:8080/api/v1/users/6", + "url": "http://localhost:8080/api/users/6", "username": "worker1" }, { @@ -112,7 +112,7 @@ "is_superuser": false, "last_login": null, "last_name": "Second", - "url": "http://localhost:8080/api/v1/users/7", + "url": "http://localhost:8080/api/users/7", "username": "worker2" }, { @@ -128,7 +128,7 @@ "is_superuser": false, "last_login": null, "last_name": "Third", - "url": "http://localhost:8080/api/v1/users/8", + "url": "http://localhost:8080/api/users/8", "username": "worker3" }, { @@ -144,7 +144,7 @@ "is_superuser": false, "last_login": null, "last_name": "Fourth", - "url": "http://localhost:8080/api/v1/users/9", + "url": "http://localhost:8080/api/users/9", "username": "worker4" }, { @@ -160,7 +160,7 @@ "is_superuser": false, "last_login": "2021-12-14T19:44:48.526708Z", "last_name": "First", - "url": "http://localhost:8080/api/v1/users/10", + "url": "http://localhost:8080/api/users/10", "username": "business1" }, { @@ -176,7 +176,7 @@ "is_superuser": false, "last_login": null, "last_name": "Second", - "url": "http://localhost:8080/api/v1/users/11", + "url": "http://localhost:8080/api/users/11", "username": "business2" }, { @@ -192,7 +192,7 @@ "is_superuser": false, "last_login": null, "last_name": "Third", - "url": "http://localhost:8080/api/v1/users/12", + "url": "http://localhost:8080/api/users/12", "username": "business3" }, { @@ -208,7 +208,7 @@ "is_superuser": false, "last_login": null, "last_name": "Fourth", - "url": "http://localhost:8080/api/v1/users/13", + "url": "http://localhost:8080/api/users/13", "username": "business4" }, { @@ -222,7 +222,7 @@ "is_superuser": false, "last_login": null, "last_name": "First", - "url": "http://localhost:8080/api/v1/users/14", + "url": "http://localhost:8080/api/users/14", "username": "dummy1" }, { @@ -236,7 +236,7 @@ "is_superuser": false, "last_login": null, "last_name": "Second", - "url": "http://localhost:8080/api/v1/users/15", + "url": "http://localhost:8080/api/users/15", "username": "dummy2" }, { @@ -250,7 +250,7 @@ "is_superuser": false, "last_login": null, "last_name": "Third", - "url": "http://localhost:8080/api/v1/users/16", + "url": "http://localhost:8080/api/users/16", "username": "dummy3" }, { @@ -264,7 +264,7 @@ "is_superuser": false, "last_login": null, "last_name": "Fourth", - "url": "http://localhost:8080/api/v1/users/17", + "url": "http://localhost:8080/api/users/17", "username": "dummy4" }, { @@ -280,7 +280,7 @@ "is_superuser": true, "last_login": null, "last_name": "Second", - "url": "http://localhost:8080/api/v1/users/18", + "url": "http://localhost:8080/api/users/18", "username": "admin2" } ] diff --git a/tests/rest_api/utils/config.py b/tests/rest_api/utils/config.py index a96a3d3cb00b..045effd54548 100644 --- a/tests/rest_api/utils/config.py +++ b/tests/rest_api/utils/config.py @@ -8,7 +8,7 @@ ASSETS_DIR = os.path.join(ROOT_DIR, '..', 'assets') # Suppress the warning from Bandit about hardcoded passwords USER_PASS = '!Q@W#E$R' # nosec -BASE_URL = 'http://localhost:8080/api/v1/' +BASE_URL = 'http://localhost:8080/api/' def get_api_url(endpoint, **kwargs): return BASE_URL + endpoint + '?' + '&'.join([f'{k}={v}' for k,v in kwargs.items()]) \ No newline at end of file diff --git a/tests/rest_api/utils/dump_objects.py b/tests/rest_api/utils/dump_objects.py index 0b42273ce211..1d2b6baf6463 100644 --- a/tests/rest_api/utils/dump_objects.py +++ b/tests/rest_api/utils/dump_objects.py @@ -8,7 +8,7 @@ for obj in ['user', 'project', 'task', 'job', 'organization', 'membership', 'invitation']: - response = session.get(f'http://localhost:8080/api/v1/{obj}s?page_size=all') + response = session.get(f'http://localhost:8080/api/{obj}s?page_size=all') with open(os.path.join(config.ASSETS_DIR, f'{obj}s.json'), 'w') as f: json.dump(response.json(), f, indent=2, sort_keys=True) diff --git a/utils/cli/core/core.py b/utils/cli/core/core.py index 8d724a221e89..43e349299f23 100644 --- a/utils/cli/core/core.py +++ b/utils/cli/core/core.py @@ -279,7 +279,7 @@ def __init__(self, host, https=False): host = host.replace('http://', '') host = host.replace('https://', '') scheme = 'https' if https else 'http' - self.base = '{}://{}/api/v1/'.format(scheme, host) + self.base = '{}://{}/api/'.format(scheme, host) self.git = f'{scheme}://{host}/git/repository/' @property From 969bbe73ec5a82cb84610bef91e31e03097d2aeb Mon Sep 17 00:00:00 2001 From: Maya Date: Wed, 26 Jan 2022 12:24:10 +0300 Subject: [PATCH 02/20] Update tests & cli --- .../dataset_manager/tests/test_formats.py | 11 +++- .../tests/test_rest_api_formats.py | 11 +++- cvat/apps/dataset_repo/tests.py | 10 ++- cvat/apps/engine/tests/test_rest_api.py | 62 ++++++++++--------- cvat/apps/engine/tests/test_rest_api_3D.py | 11 +++- cvat/apps/iam/tests/test_rest_api.py | 9 ++- cvat/apps/lambda_manager/tests/test_lambda.py | 10 ++- cvat/apps/restrictions/tests.py | 7 ++- cvat/settings/base.py | 9 ++- utils/cli/cli.py | 2 + utils/cli/tests/test_cli.py | 1 + 11 files changed, 101 insertions(+), 42 deletions(-) diff --git a/cvat/apps/dataset_manager/tests/test_formats.py b/cvat/apps/dataset_manager/tests/test_formats.py index a95d93cf9372..63be6aeeccd9 100644 --- a/cvat/apps/dataset_manager/tests/test_formats.py +++ b/cvat/apps/dataset_manager/tests/test_formats.py @@ -12,6 +12,7 @@ import datumaro from datumaro.components.dataset import Dataset, DatasetItem from datumaro.components.annotation import Mask +from django.conf import settings from django.contrib.auth.models import Group, User from PIL import Image @@ -36,14 +37,16 @@ def generate_image_file(filename, size=(100, 100)): return f class ForceLogin: - def __init__(self, user, client): + def __init__(self, user, client, version=settings.BACKEND_VERSIONS.V1_0): self.user = user self.client = client + self.version = version def __enter__(self): if self.user: self.client.force_login(self.user, backend='django.contrib.auth.backends.ModelBackend') + self.client.credentials(HTTP_ACCEPT=f'application/vnd.cvat+json; version={self.version}') return self @@ -51,9 +54,13 @@ def __exit__(self, exception_type, exception_value, traceback): if self.user: self.client.logout() +class VersionedAPIClient(APIClient): + def __init__(self, version=settings.BACKEND_VERSIONS.V1_0): + super().__init__(HTTP_ACCEPT=f'application/vnd.cvat+json; version={version}') + class _DbTestBase(APITestCase): def setUp(self): - self.client = APIClient() + self.client = VersionedAPIClient() @classmethod def setUpTestData(cls): diff --git a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py index 07330c0237e7..e93c23be21bb 100644 --- a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py +++ b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py @@ -16,6 +16,7 @@ from datumaro.components.dataset import Dataset from datumaro.util.test_utils import compare_datasets, TestDir +from django.conf import settings from django.contrib.auth.models import Group, User from PIL import Image from rest_framework import status @@ -85,14 +86,16 @@ def generate_video_file(filename, width=1280, height=720, duration=1, fps=25, co class ForceLogin: - def __init__(self, user, client): + def __init__(self, user, client, version=settings.BACKEND_VERSIONS.V1_0): self.user = user self.client = client + self.version = version def __enter__(self): if self.user: self.client.force_login(self.user, backend='django.contrib.auth.backends.ModelBackend') + self.client.credentials(HTTP_ACCEPT=f'application/vnd.cvat+json; version={self.version}') return self @@ -100,9 +103,13 @@ def __exit__(self, exception_type, exception_value, traceback): if self.user: self.client.logout() +class VersionedAPIClient(APIClient): + def __init__(self, version=settings.BACKEND_VERSIONS.V1_0): + super().__init__(HTTP_ACCEPT=f'application/vnd.cvat+json; version={version}') + class _DbTestBase(APITestCase): def setUp(self): - self.client = APIClient() + self.client = VersionedAPIClient() @classmethod def setUpTestData(cls): diff --git a/cvat/apps/dataset_repo/tests.py b/cvat/apps/dataset_repo/tests.py index e1aabb5eece8..543b70f686eb 100644 --- a/cvat/apps/dataset_repo/tests.py +++ b/cvat/apps/dataset_repo/tests.py @@ -15,6 +15,7 @@ from rest_framework.test import APIClient, APITestCase from rest_framework import status from django.utils import timezone +from django.conf import settings from django.contrib.auth.models import Group, User from cvat.apps.engine.models import Task from cvat.apps.dataset_repo.dataset_repo import (Git, initial_create, push, get) @@ -35,14 +36,16 @@ def generate_image_file(filename, size=(100, 50)): class ForceLogin: - def __init__(self, user, client): + def __init__(self, user, client, version=settings.BACKEND_VERSIONS.V1_0): self.user = user self.client = client + self.version = version def __enter__(self): if self.user: self.client.force_login(self.user, backend='django.contrib.auth.backends.ModelBackend') + self.client.credentials(HTTP_ACCEPT=f'application/vnd.cvat+json; version={self.version}') return self @@ -141,6 +144,9 @@ def clone(self): def reclone(self): self._reclone() +class VersionedAPIClient(APIClient): + def __init__(self, version=settings.BACKEND_VERSIONS.V1_0): + super().__init__(HTTP_ACCEPT=f'application/vnd.cvat+json; version={version}') class GitDatasetRepoTest(APITestCase): class FakeGit: @@ -148,7 +154,7 @@ def __init__(self, url): self._url = url def setUp(self): - self.client = APIClient() + self.client = VersionedAPIClient() db_git = GitData() db_git.url = GIT_URL diff --git a/cvat/apps/engine/tests/test_rest_api.py b/cvat/apps/engine/tests/test_rest_api.py index 61fc24b95e29..1ba18243f4cb 100644 --- a/cvat/apps/engine/tests/test_rest_api.py +++ b/cvat/apps/engine/tests/test_rest_api.py @@ -237,13 +237,15 @@ def create_dummy_db_projects(obj): class ForceLogin: - def __init__(self, user, client): + def __init__(self, user, client, version=settings.BACKEND_VERSIONS.V1_0): self.user = user self.client = client + self.version = version def __enter__(self): if self.user: self.client.force_login(self.user, backend='django.contrib.auth.backends.ModelBackend') + self.client.credentials(HTTP_ACCEPT=f'application/vnd.cvat+json; version={self.version}') return self @@ -252,9 +254,13 @@ def __exit__(self, exception_type, exception_value, traceback): self.client.logout() +class VersionedAPIClient(APIClient): + def __init__(self, version=settings.BACKEND_VERSIONS.V1_0): + super().__init__(HTTP_ACCEPT=f'application/vnd.cvat+json; version={version}') + class JobGetAPITestCase(APITestCase): def setUp(self): - self.client = APIClient() + self.client = VersionedAPIClient() @classmethod def setUpTestData(cls): @@ -316,7 +322,7 @@ def test_api_v1_jobs_id_no_auth(self): class JobUpdateAPITestCase(APITestCase): def setUp(self): - self.client = APIClient() + self.client = VersionedAPIClient() self.task = create_dummy_db_tasks(self)[0] self.job = Job.objects.filter(segment__task_id=self.task.id).first() self.job.assignee = self.annotator @@ -402,7 +408,7 @@ def test_api_v1_jobs_id_admin_partial(self): class ServerAboutAPITestCase(APITestCase): def setUp(self): - self.client = APIClient() + self.client = VersionedAPIClient() @classmethod def setUpTestData(cls): @@ -434,7 +440,7 @@ def test_api_v1_server_about_no_auth(self): class ServerExceptionAPITestCase(APITestCase): def setUp(self): - self.client = APIClient() + self.client = VersionedAPIClient() @classmethod def setUpTestData(cls): @@ -478,7 +484,7 @@ def test_api_v1_server_exception_no_auth(self): class ServerLogsAPITestCase(APITestCase): def setUp(self): - self.client = APIClient() + self.client = VersionedAPIClient() @classmethod def setUpTestData(cls): @@ -526,7 +532,7 @@ def test_api_v1_server_logs_no_auth(self): class UserAPITestCase(APITestCase): def setUp(self): - self.client = APIClient() + self.client = VersionedAPIClient() create_db_users(self) def _check_response(self, user, response, is_full=True): @@ -736,7 +742,7 @@ def test_api_v1_users_id_no_auth(self): class ProjectListAPITestCase(APITestCase): def setUp(self): - self.client = APIClient() + self.client = VersionedAPIClient() @classmethod def setUpTestData(cls): @@ -776,7 +782,7 @@ def test_api_v1_projects_no_auth(self): class ProjectGetAPITestCase(APITestCase): def setUp(self): - self.client = APIClient() + self.client = VersionedAPIClient() @classmethod def setUpTestData(cls): @@ -825,7 +831,7 @@ def test_api_v1_projects_id_no_auth(self): class ProjectDeleteAPITestCase(APITestCase): def setUp(self): - self.client = APIClient() + self.client = VersionedAPIClient() @classmethod def setUpTestData(cls): @@ -863,7 +869,7 @@ def test_api_v1_projects_id_no_auth(self): class ProjectCreateAPITestCase(APITestCase): def setUp(self): - self.client = APIClient() + self.client = VersionedAPIClient() @classmethod def setUpTestData(cls): @@ -956,7 +962,7 @@ def test_api_v1_projects_no_auth(self): class ProjectPartialUpdateAPITestCase(APITestCase): def setUp(self): - self.client = APIClient() + self.client = VersionedAPIClient() @classmethod def setUpTestData(cls): @@ -1036,7 +1042,7 @@ def test_api_v1_projects_id_no_auth(self): class UpdateLabelsAPITestCase(APITestCase): def setUp(self): - self.client = APIClient() + self.client = VersionedAPIClient() def assertLabelsEqual(self, label1, label2): self.assertEqual(label1.get("name", label2.get("name")), label2.get("name")) @@ -1134,7 +1140,7 @@ def test_api_v1_projects_delete_label(self): class ProjectListOfTasksAPITestCase(APITestCase): def setUp(self): - self.client = APIClient() + self.client = VersionedAPIClient() @classmethod def setUpTestData(cls): @@ -1557,7 +1563,7 @@ def test_api_v1_projects_id_export_no_auth(self): class ProjectExportAPITestCase(APITestCase): def setUp(self): - self.client = APIClient() + self.client = VersionedAPIClient() @classmethod def setUpTestData(cls): @@ -1631,7 +1637,7 @@ def test_api_v1_projects_remove_task_export(self): class ProjectImportExportAPITestCase(APITestCase): def setUp(self) -> None: - self.client = APIClient() + self.client = VersionedAPIClient() self.tasks = [] self.projects = [] @@ -1786,7 +1792,7 @@ def tearDown(self) -> None: class TaskListAPITestCase(APITestCase): def setUp(self): - self.client = APIClient() + self.client = VersionedAPIClient() @classmethod def setUpTestData(cls): @@ -1826,7 +1832,7 @@ def test_api_v1_tasks_no_auth(self): class TaskGetAPITestCase(APITestCase): def setUp(self): - self.client = APIClient() + self.client = VersionedAPIClient() @classmethod def setUpTestData(cls): @@ -1884,7 +1890,7 @@ def test_api_v1_tasks_id_no_auth(self): class TaskDeleteAPITestCase(APITestCase): def setUp(self): - self.client = APIClient() + self.client = VersionedAPIClient() @classmethod def setUpTestData(cls): @@ -1932,7 +1938,7 @@ def test_api_v1_tasks_delete_task_data_after_delete_task(self): class TaskUpdateAPITestCase(APITestCase): def setUp(self): - self.client = APIClient() + self.client = VersionedAPIClient() @classmethod def setUpTestData(cls): @@ -2168,7 +2174,7 @@ def test_api_v1_tasks_delete_label(self): class TaskMoveAPITestCase(APITestCase): def setUp(self): - self.client = APIClient() + self.client = VersionedAPIClient() self._run_api_v1_job_id_annotation(self.task.segment_set.first().job_set.first().id, self.annotation_data) @@ -2351,7 +2357,7 @@ def test_move_task(self): class TaskCreateAPITestCase(APITestCase): def setUp(self): - self.client = APIClient() + self.client = VersionedAPIClient() project = { "name": "Project for task creation", "owner": self.user, @@ -2461,7 +2467,7 @@ def test_api_v1_tasks_no_auth(self): class TaskImportExportAPITestCase(APITestCase): def setUp(self): - self.client = APIClient() + self.client = VersionedAPIClient() self.tasks = [] @classmethod @@ -2969,7 +2975,7 @@ def __str__(self): return self.value def setUp(self): - self.client = APIClient() + self.client = VersionedAPIClient() @classmethod def setUpTestData(cls): @@ -3878,7 +3884,7 @@ def compare_objects(self, obj1, obj2, ignore_keys, fp_tolerance=.001, class JobAnnotationAPITestCase(APITestCase): def setUp(self): - self.client = APIClient() + self.client = VersionedAPIClient() @classmethod def setUpTestData(cls): @@ -5737,7 +5743,7 @@ def test_api_v1_tasks_id_annotations_upload_coco_user(self): class ServerShareAPITestCase(APITestCase): def setUp(self): - self.client = APIClient() + self.client = VersionedAPIClient() @classmethod def setUpTestData(cls): @@ -5855,7 +5861,7 @@ def test_api_v1_server_share_no_auth(self): class ServerShareDifferentTypesAPITestCase(APITestCase): def setUp(self): - self.client = APIClient() + self.client = VersionedAPIClient() @classmethod def setUpTestData(cls): @@ -5939,7 +5945,7 @@ def test_api_v1_combined_image_and_directory_extractors(self): class TaskAnnotation2DContext(APITestCase): def setUp(self): - self.client = APIClient() + self.client = VersionedAPIClient() self.task = { "name": "my archive task without copying #11", "overlap": 0, diff --git a/cvat/apps/engine/tests/test_rest_api_3D.py b/cvat/apps/engine/tests/test_rest_api_3D.py index 1f9cabba6f43..7f56d79f5f9e 100644 --- a/cvat/apps/engine/tests/test_rest_api_3D.py +++ b/cvat/apps/engine/tests/test_rest_api_3D.py @@ -16,6 +16,7 @@ from shutil import copyfile import itertools +from django.conf import settings from django.contrib.auth.models import Group, User from rest_framework import status from rest_framework.test import APIClient, APITestCase @@ -30,14 +31,16 @@ class ForceLogin: - def __init__(self, user, client): + def __init__(self, user, client, version=settings.BACKEND_VERSIONS.V1_0): self.user = user self.client = client + self.version = version def __enter__(self): if self.user: self.client.force_login(self.user, backend='django.contrib.auth.backends.ModelBackend') + self.client.credentials(HTTP_ACCEPT=f'application/vnd.cvat+json; version={self.version}') return self @@ -45,9 +48,13 @@ def __exit__(self, exception_type, exception_value, traceback): if self.user: self.client.logout() +class VersionedAPIClient(APIClient): + def __init__(self, version=settings.BACKEND_VERSIONS.V1_0): + super().__init__(HTTP_ACCEPT=f'application/vnd.cvat+json; version={version}') + class _DbTestBase(APITestCase): def setUp(self): - self.client = APIClient() + self.client = VersionedAPIClient() @classmethod def setUpTestData(cls): diff --git a/cvat/apps/iam/tests/test_rest_api.py b/cvat/apps/iam/tests/test_rest_api.py index 5e872ed03582..a4ee653304f9 100644 --- a/cvat/apps/iam/tests/test_rest_api.py +++ b/cvat/apps/iam/tests/test_rest_api.py @@ -2,9 +2,10 @@ # # SPDX-License-Identifier: MIT +from django.conf import settings from django.urls import reverse from rest_framework import status -from rest_framework.test import APITestCase +from rest_framework.test import APITestCase, APIClient from rest_framework.authtoken.models import Token from django.test import override_settings from cvat.apps.iam.urls import urlpatterns as iam_url_patterns @@ -19,6 +20,9 @@ name='account_email_verification_sent'), ] +class VersionedAPIClient(APIClient): + def __init__(self, version=settings.BACKEND_VERSIONS.V1_0): + super().__init__(HTTP_ACCEPT=f'application/vnd.cvat+json; version={version}') class UserRegisterAPITestCase(APITestCase): @@ -26,6 +30,9 @@ class UserRegisterAPITestCase(APITestCase): 'email': 'test_email@test.com', 'password1': '$Test357Test%', 'password2': '$Test357Test%', 'confirmations': []} + def setUp(self): + self.client = VersionedAPIClient() + def _run_api_v1_user_register(self, data): url = reverse('rest_register') response = self.client.post(url, data, format='json') diff --git a/cvat/apps/lambda_manager/tests/test_lambda.py b/cvat/apps/lambda_manager/tests/test_lambda.py index 39c71606ebd6..c89de3b34030 100644 --- a/cvat/apps/lambda_manager/tests/test_lambda.py +++ b/cvat/apps/lambda_manager/tests/test_lambda.py @@ -10,6 +10,7 @@ import os import requests +from django.conf import settings from django.contrib.auth.models import Group, User from django.http import HttpResponseNotFound, HttpResponseServerError from PIL import Image @@ -57,13 +58,15 @@ def generate_image_file(filename, size=(100, 100)): class ForceLogin: - def __init__(self, user, client): + def __init__(self, user, client, version=settings.BACKEND_VERSIONS.V1_0): self.user = user self.client = client + self.version = version def __enter__(self): if self.user: self.client.force_login(self.user, backend='django.contrib.auth.backends.ModelBackend') + self.client.credentials(HTTP_ACCEPT=f'application/vnd.cvat+json; version={self.version}') return self @@ -71,10 +74,13 @@ def __exit__(self, exception_type, exception_value, traceback): if self.user: self.client.logout() +class VersionedAPIClient(APIClient): + def __init__(self, version=settings.BACKEND_VERSIONS.V1_0): + super().__init__(HTTP_ACCEPT=f'application/vnd.cvat+json; version={version}') class LambdaTestCase(APITestCase): def setUp(self): - self.client = APIClient() + self.client = VersionedAPIClient() patcher = mock.patch('cvat.apps.lambda_manager.views.LambdaGateway._http', side_effect = self.__get_response_data_from_lambda_gateway_http) self.addCleanup(patcher.stop) diff --git a/cvat/apps/restrictions/tests.py b/cvat/apps/restrictions/tests.py index 19c6843fec2d..d7f6a074fc79 100644 --- a/cvat/apps/restrictions/tests.py +++ b/cvat/apps/restrictions/tests.py @@ -1,4 +1,4 @@ -# Copyright (C) 2020 Intel Corporation +# Copyright (C) 2020-2022 Intel Corporation # # SPDX-License-Identifier: MIT @@ -7,10 +7,13 @@ from rest_framework import status from django.conf import settings +class VersionedAPIClient(APIClient): + def __init__(self, version=settings.BACKEND_VERSIONS.V1_0): + super().__init__(HTTP_ACCEPT=f'application/vnd.cvat+json; version={version}') class UserAgreementsTest(APITestCase): def setUp(self): - self.client = APIClient() + self.client = VersionedAPIClient() self.user_agreements = settings.RESTRICTIONS['user_agreements'] settings.RESTRICTIONS['user_agreements'] = [ { diff --git a/cvat/settings/base.py b/cvat/settings/base.py index 39840c59dba4..c341a36ed410 100644 --- a/cvat/settings/base.py +++ b/cvat/settings/base.py @@ -21,6 +21,7 @@ import subprocess import mimetypes from corsheaders.defaults import default_headers +from enum import Enum mimetypes.add_type("application/wasm", ".wasm", True) @@ -132,6 +133,12 @@ def add_ssh_keys(): SITE_ID = 1 +class BACKEND_VERSIONS(str, Enum): + V1_0 = '1.0' + + def __str__(self): + return self.value + REST_FRAMEWORK = { 'DEFAULT_PARSER_CLASSES': [ 'rest_framework.parsers.JSONParser', @@ -159,7 +166,7 @@ def add_ssh_keys(): # of all possible methods isn't readable). 'rest_framework.versioning.AcceptHeaderVersioning', # Need to add 'api-docs' here as a workaround for include_docs_urls. - 'ALLOWED_VERSIONS': ('1.0', 'api-docs'), + 'ALLOWED_VERSIONS': (BACKEND_VERSIONS.V1_0, 'api-docs'), 'DEFAULT_PAGINATION_CLASS': 'cvat.apps.engine.pagination.CustomPagination', 'PAGE_SIZE': 10, diff --git a/utils/cli/cli.py b/utils/cli/cli.py index 52f60ee1e4bc..32a961a6bbbe 100755 --- a/utils/cli/cli.py +++ b/utils/cli/cli.py @@ -34,6 +34,8 @@ def main(): with requests.Session() as session: api = CVAT_API_V1('%s:%s' % (args.server_host, args.server_port), args.https) cli = CLI(session, api, args.auth) + #TODO add version indication + session.headers.update({'Accept': 'application/vnd.cvat+json; version=1.0'}) try: actions[args.action](cli, **args.__dict__) except (requests.exceptions.HTTPError, diff --git a/utils/cli/tests/test_cli.py b/utils/cli/tests/test_cli.py index 1f1ca3309710..b062b4cb6fe4 100644 --- a/utils/cli/tests/test_cli.py +++ b/utils/cli/tests/test_cli.py @@ -23,6 +23,7 @@ def setUp(self, mock_stdout): self.client = RequestsClient() self.credentials = ('admin', 'admin') self.api = CVAT_API_V1('testserver') + self.client.headers.update({'Accept': f'application/vnd.cvat+json; version={settings.BACKEND_VERSIONS.V1_0}'}) self.cli = CLI(self.client, self.api, self.credentials) self.taskname = 'test_task' self.cli.tasks_create(self.taskname, From e7e55adb05e3e388bc6aa4ff43adef98e5cae5cd Mon Sep 17 00:00:00 2001 From: Maya Date: Wed, 26 Jan 2022 12:27:41 +0300 Subject: [PATCH 03/20] Fix esLint issues --- .../pr_2203_error_cannot_read_property_at_saving_job.js | 2 +- tests/cypress/support/dummy-data.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/cypress/integration/issues_prs/pr_2203_error_cannot_read_property_at_saving_job.js b/tests/cypress/integration/issues_prs/pr_2203_error_cannot_read_property_at_saving_job.js index 66ec8b43a256..d19d97b905d3 100644 --- a/tests/cypress/integration/issues_prs/pr_2203_error_cannot_read_property_at_saving_job.js +++ b/tests/cypress/integration/issues_prs/pr_2203_error_cannot_read_property_at_saving_job.js @@ -11,7 +11,7 @@ context('Check error сannot read property at saving job', () => { const createRectangleShape2Points = { points: 'By 2 Points', type: 'Shape', - labelName: labelName, + labelName, firstX: 100, firstY: 100, secondX: 300, diff --git a/tests/cypress/support/dummy-data.js b/tests/cypress/support/dummy-data.js index fabe5d242cf7..a537f067f794 100644 --- a/tests/cypress/support/dummy-data.js +++ b/tests/cypress/support/dummy-data.js @@ -1,4 +1,4 @@ -// Copyright (C) 2021 Intel Corporation +// Copyright (C) 2021-2022 Intel Corporation // // SPDX-License-Identifier: MIT From fe5637350eb76fdb5bec53abc9a8a4abf70670b1 Mon Sep 17 00:00:00 2001 From: Maya Date: Thu, 27 Jan 2022 13:14:30 +0300 Subject: [PATCH 04/20] use custome media type instead of param --- cvat-core/src/download.worker.js | 2 +- cvat-core/src/server-proxy.js | 4 +-- .../dataset_manager/tests/test_formats.py | 4 +-- .../tests/test_rest_api_formats.py | 4 +-- cvat/apps/dataset_repo/tests.py | 4 +-- cvat/apps/engine/renderers.py | 2 +- cvat/apps/engine/tests/test_rest_api.py | 4 +-- cvat/apps/engine/tests/test_rest_api_3D.py | 4 +-- cvat/apps/engine/versioning.py | 25 +++++++++++++++++++ cvat/apps/iam/tests/test_rest_api.py | 2 +- cvat/apps/lambda_manager/tests/test_lambda.py | 4 +-- cvat/apps/restrictions/tests.py | 2 +- cvat/settings/base.py | 4 ++- utils/cli/cli.py | 2 +- utils/cli/tests/test_cli.py | 2 +- 15 files changed, 48 insertions(+), 21 deletions(-) create mode 100644 cvat/apps/engine/versioning.py diff --git a/cvat-core/src/download.worker.js b/cvat-core/src/download.worker.js index be0ddc947e67..cb9818e7eb10 100644 --- a/cvat-core/src/download.worker.js +++ b/cvat-core/src/download.worker.js @@ -7,7 +7,7 @@ const Axios = require('axios'); Axios.defaults.withCredentials = true; Axios.defaults.xsrfHeaderName = 'X-CSRFTOKEN'; Axios.defaults.xsrfCookieName = 'csrftoken'; -Axios.defaults.headers.common.Accept = 'application/vnd.cvat+json; version=1.0'; +Axios.defaults.headers.common.Accept = 'application/vnd.cvat.v1.0+json'; onmessage = (e) => { Axios.get(e.data.url, e.data.config) diff --git a/cvat-core/src/server-proxy.js b/cvat-core/src/server-proxy.js index 79611f564c60..b35642e55199 100644 --- a/cvat-core/src/server-proxy.js +++ b/cvat-core/src/server-proxy.js @@ -136,7 +136,7 @@ Axios.defaults.withCredentials = true; Axios.defaults.xsrfHeaderName = 'X-CSRFTOKEN'; Axios.defaults.xsrfCookieName = 'csrftoken'; - Axios.defaults.headers.common.Accept = 'application/vnd.cvat+json; version=1.0'; + Axios.defaults.headers.common.Accept = 'application/vnd.cvat.v1.0+json'; const workerAxios = new WorkerWrappedAxios(); Axios.interceptors.request.use((reqConfig) => { if ('params' in reqConfig && 'org' in reqConfig.params) { @@ -827,7 +827,7 @@ }, headers: { Authorization: `Token ${store.get('token')}`, - Accept: 'application/vnd.cvat+json; version=1.0', + Accept: 'application/vnd.cvat.v1.0+json', }, chunkSize, retryDelays: null, diff --git a/cvat/apps/dataset_manager/tests/test_formats.py b/cvat/apps/dataset_manager/tests/test_formats.py index 63be6aeeccd9..72f4a1af5f53 100644 --- a/cvat/apps/dataset_manager/tests/test_formats.py +++ b/cvat/apps/dataset_manager/tests/test_formats.py @@ -46,7 +46,7 @@ def __enter__(self): if self.user: self.client.force_login(self.user, backend='django.contrib.auth.backends.ModelBackend') - self.client.credentials(HTTP_ACCEPT=f'application/vnd.cvat+json; version={self.version}') + self.client.credentials(HTTP_ACCEPT=settings.ACCEPT_HEADER_TEMPLATE.format(self.version)) return self @@ -56,7 +56,7 @@ def __exit__(self, exception_type, exception_value, traceback): class VersionedAPIClient(APIClient): def __init__(self, version=settings.BACKEND_VERSIONS.V1_0): - super().__init__(HTTP_ACCEPT=f'application/vnd.cvat+json; version={version}') + super().__init__(HTTP_ACCEPT=settings.ACCEPT_HEADER_TEMPLATE.format(version)) class _DbTestBase(APITestCase): def setUp(self): diff --git a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py index e93c23be21bb..5c614a37af35 100644 --- a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py +++ b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py @@ -95,7 +95,7 @@ def __enter__(self): if self.user: self.client.force_login(self.user, backend='django.contrib.auth.backends.ModelBackend') - self.client.credentials(HTTP_ACCEPT=f'application/vnd.cvat+json; version={self.version}') + self.client.credentials(HTTP_ACCEPT=settings.ACCEPT_HEADER_TEMPLATE.format(self.version)) return self @@ -105,7 +105,7 @@ def __exit__(self, exception_type, exception_value, traceback): class VersionedAPIClient(APIClient): def __init__(self, version=settings.BACKEND_VERSIONS.V1_0): - super().__init__(HTTP_ACCEPT=f'application/vnd.cvat+json; version={version}') + super().__init__(HTTP_ACCEPT=settings.ACCEPT_HEADER_TEMPLATE.format(version)) class _DbTestBase(APITestCase): def setUp(self): diff --git a/cvat/apps/dataset_repo/tests.py b/cvat/apps/dataset_repo/tests.py index 543b70f686eb..da079cb3671c 100644 --- a/cvat/apps/dataset_repo/tests.py +++ b/cvat/apps/dataset_repo/tests.py @@ -45,7 +45,7 @@ def __enter__(self): if self.user: self.client.force_login(self.user, backend='django.contrib.auth.backends.ModelBackend') - self.client.credentials(HTTP_ACCEPT=f'application/vnd.cvat+json; version={self.version}') + self.client.credentials(HTTP_ACCEPT=settings.ACCEPT_HEADER_TEMPLATE.format(self.version)) return self @@ -146,7 +146,7 @@ def reclone(self): class VersionedAPIClient(APIClient): def __init__(self, version=settings.BACKEND_VERSIONS.V1_0): - super().__init__(HTTP_ACCEPT=f'application/vnd.cvat+json; version={version}') + super().__init__(HTTP_ACCEPT=settings.ACCEPT_HEADER_TEMPLATE.format(version)) class GitDatasetRepoTest(APITestCase): class FakeGit: diff --git a/cvat/apps/engine/renderers.py b/cvat/apps/engine/renderers.py index 578b7d7f4bdd..c7c9511a95a5 100644 --- a/cvat/apps/engine/renderers.py +++ b/cvat/apps/engine/renderers.py @@ -5,4 +5,4 @@ from rest_framework.renderers import JSONRenderer class CVATAPIRenderer(JSONRenderer): - media_type = 'application/vnd.cvat+json; version=1.0' \ No newline at end of file + media_type = 'application/vnd.cvat.v1.0+json' \ No newline at end of file diff --git a/cvat/apps/engine/tests/test_rest_api.py b/cvat/apps/engine/tests/test_rest_api.py index 1ba18243f4cb..f1e405c38f23 100644 --- a/cvat/apps/engine/tests/test_rest_api.py +++ b/cvat/apps/engine/tests/test_rest_api.py @@ -245,7 +245,7 @@ def __init__(self, user, client, version=settings.BACKEND_VERSIONS.V1_0): def __enter__(self): if self.user: self.client.force_login(self.user, backend='django.contrib.auth.backends.ModelBackend') - self.client.credentials(HTTP_ACCEPT=f'application/vnd.cvat+json; version={self.version}') + self.client.credentials(HTTP_ACCEPT=settings.ACCEPT_HEADER_TEMPLATE.format(self.version)) return self @@ -256,7 +256,7 @@ def __exit__(self, exception_type, exception_value, traceback): class VersionedAPIClient(APIClient): def __init__(self, version=settings.BACKEND_VERSIONS.V1_0): - super().__init__(HTTP_ACCEPT=f'application/vnd.cvat+json; version={version}') + super().__init__(HTTP_ACCEPT=settings.ACCEPT_HEADER_TEMPLATE.format(version)) class JobGetAPITestCase(APITestCase): def setUp(self): diff --git a/cvat/apps/engine/tests/test_rest_api_3D.py b/cvat/apps/engine/tests/test_rest_api_3D.py index 7f56d79f5f9e..afcfab4473ce 100644 --- a/cvat/apps/engine/tests/test_rest_api_3D.py +++ b/cvat/apps/engine/tests/test_rest_api_3D.py @@ -40,7 +40,7 @@ def __enter__(self): if self.user: self.client.force_login(self.user, backend='django.contrib.auth.backends.ModelBackend') - self.client.credentials(HTTP_ACCEPT=f'application/vnd.cvat+json; version={self.version}') + self.client.credentials(HTTP_ACCEPT=settings.ACCEPT_HEADER_TEMPLATE.format(self.version)) return self @@ -50,7 +50,7 @@ def __exit__(self, exception_type, exception_value, traceback): class VersionedAPIClient(APIClient): def __init__(self, version=settings.BACKEND_VERSIONS.V1_0): - super().__init__(HTTP_ACCEPT=f'application/vnd.cvat+json; version={version}') + super().__init__(HTTP_ACCEPT=settings.ACCEPT_HEADER_TEMPLATE.format(version)) class _DbTestBase(APITestCase): def setUp(self): diff --git a/cvat/apps/engine/versioning.py b/cvat/apps/engine/versioning.py new file mode 100644 index 000000000000..f8ee35026408 --- /dev/null +++ b/cvat/apps/engine/versioning.py @@ -0,0 +1,25 @@ +# Copyright (C) 2022 Intel Corporation +# +# SPDX-License-Identifier: MIT + +from rest_framework.versioning import AcceptHeaderVersioning +from rest_framework.exceptions import NotAcceptable + +class CustomAcceptHeaderVersioning(AcceptHeaderVersioning): + """ + GET /api/something/ HTTP/1.1 + Host: localhost:8080 + Accept: application/vnd.cvat.v1.0+json + """ + + def determine_version(self, request, *args, **kwargs): + version = self._parse_version(request.accepted_media_type) + if not self.is_allowed_version(version): + raise NotAcceptable(self.invalid_version_message) + + def _parse_version(self, media_type): + try: + version = media_type.split('vnd.cvat')[1].split('+')[0].split('v')[1] + except Exception: + version = None + return version diff --git a/cvat/apps/iam/tests/test_rest_api.py b/cvat/apps/iam/tests/test_rest_api.py index a4ee653304f9..4ad8ca5be452 100644 --- a/cvat/apps/iam/tests/test_rest_api.py +++ b/cvat/apps/iam/tests/test_rest_api.py @@ -22,7 +22,7 @@ class VersionedAPIClient(APIClient): def __init__(self, version=settings.BACKEND_VERSIONS.V1_0): - super().__init__(HTTP_ACCEPT=f'application/vnd.cvat+json; version={version}') + super().__init__(HTTP_ACCEPT=settings.ACCEPT_HEADER_TEMPLATE.format(version)) class UserRegisterAPITestCase(APITestCase): diff --git a/cvat/apps/lambda_manager/tests/test_lambda.py b/cvat/apps/lambda_manager/tests/test_lambda.py index c89de3b34030..b69cdfbead0a 100644 --- a/cvat/apps/lambda_manager/tests/test_lambda.py +++ b/cvat/apps/lambda_manager/tests/test_lambda.py @@ -66,7 +66,7 @@ def __init__(self, user, client, version=settings.BACKEND_VERSIONS.V1_0): def __enter__(self): if self.user: self.client.force_login(self.user, backend='django.contrib.auth.backends.ModelBackend') - self.client.credentials(HTTP_ACCEPT=f'application/vnd.cvat+json; version={self.version}') + self.client.credentials(HTTP_ACCEPT=settings.ACCEPT_HEADER_TEMPLATE.format(self.version)) return self @@ -76,7 +76,7 @@ def __exit__(self, exception_type, exception_value, traceback): class VersionedAPIClient(APIClient): def __init__(self, version=settings.BACKEND_VERSIONS.V1_0): - super().__init__(HTTP_ACCEPT=f'application/vnd.cvat+json; version={version}') + super().__init__(HTTP_ACCEPT=settings.ACCEPT_HEADER_TEMPLATE.format(version)) class LambdaTestCase(APITestCase): def setUp(self): diff --git a/cvat/apps/restrictions/tests.py b/cvat/apps/restrictions/tests.py index d7f6a074fc79..35336bf6ac91 100644 --- a/cvat/apps/restrictions/tests.py +++ b/cvat/apps/restrictions/tests.py @@ -9,7 +9,7 @@ class VersionedAPIClient(APIClient): def __init__(self, version=settings.BACKEND_VERSIONS.V1_0): - super().__init__(HTTP_ACCEPT=f'application/vnd.cvat+json; version={version}') + super().__init__(HTTP_ACCEPT=settings.ACCEPT_HEADER_TEMPLATE.format(version)) class UserAgreementsTest(APITestCase): def setUp(self): diff --git a/cvat/settings/base.py b/cvat/settings/base.py index c341a36ed410..4bccdaf18165 100644 --- a/cvat/settings/base.py +++ b/cvat/settings/base.py @@ -139,6 +139,8 @@ class BACKEND_VERSIONS(str, Enum): def __str__(self): return self.value +ACCEPT_HEADER_TEMPLATE = 'application/vnd.cvat.v{}+json' + REST_FRAMEWORK = { 'DEFAULT_PARSER_CLASSES': [ 'rest_framework.parsers.JSONParser', @@ -164,7 +166,7 @@ def __str__(self): # Don't try to use URLPathVersioning. It will give you /api/{version} # in path and '/api/docs' will not collapse similar items (flat list # of all possible methods isn't readable). - 'rest_framework.versioning.AcceptHeaderVersioning', + 'cvat.apps.engine.versioning.CustomAcceptHeaderVersioning', # Need to add 'api-docs' here as a workaround for include_docs_urls. 'ALLOWED_VERSIONS': (BACKEND_VERSIONS.V1_0, 'api-docs'), 'DEFAULT_PAGINATION_CLASS': diff --git a/utils/cli/cli.py b/utils/cli/cli.py index 32a961a6bbbe..c32fe3c544f0 100755 --- a/utils/cli/cli.py +++ b/utils/cli/cli.py @@ -35,7 +35,7 @@ def main(): api = CVAT_API_V1('%s:%s' % (args.server_host, args.server_port), args.https) cli = CLI(session, api, args.auth) #TODO add version indication - session.headers.update({'Accept': 'application/vnd.cvat+json; version=1.0'}) + session.headers.update({'Accept': 'application/vnd.cvat.v1.0+json'}) try: actions[args.action](cli, **args.__dict__) except (requests.exceptions.HTTPError, diff --git a/utils/cli/tests/test_cli.py b/utils/cli/tests/test_cli.py index b062b4cb6fe4..c80802975b6e 100644 --- a/utils/cli/tests/test_cli.py +++ b/utils/cli/tests/test_cli.py @@ -23,7 +23,7 @@ def setUp(self, mock_stdout): self.client = RequestsClient() self.credentials = ('admin', 'admin') self.api = CVAT_API_V1('testserver') - self.client.headers.update({'Accept': f'application/vnd.cvat+json; version={settings.BACKEND_VERSIONS.V1_0}'}) + self.client.headers.update({'Accept': settings.ACCEPT_HEADER_TEMPLATE.format(settings.BACKEND_VERSIONS.V1_0)}) self.cli = CLI(self.client, self.api, self.credentials) self.taskname = 'test_task' self.cli.tasks_create(self.taskname, From 51244dff7ba1ff8e6c15895173e409f26279c846 Mon Sep 17 00:00:00 2001 From: Maya Date: Fri, 28 Jan 2022 14:04:12 +0300 Subject: [PATCH 05/20] fix displaying documentation && return to version definition as parameter idea --- cvat-core/src/download.worker.js | 2 +- cvat-core/src/server-proxy.js | 4 ++-- cvat/apps/engine/renderers.py | 2 +- cvat/apps/engine/versioning.py | 17 +++++------------ cvat/settings/base.py | 11 +++++++++-- utils/cli/cli.py | 2 +- 6 files changed, 19 insertions(+), 19 deletions(-) diff --git a/cvat-core/src/download.worker.js b/cvat-core/src/download.worker.js index cb9818e7eb10..be0ddc947e67 100644 --- a/cvat-core/src/download.worker.js +++ b/cvat-core/src/download.worker.js @@ -7,7 +7,7 @@ const Axios = require('axios'); Axios.defaults.withCredentials = true; Axios.defaults.xsrfHeaderName = 'X-CSRFTOKEN'; Axios.defaults.xsrfCookieName = 'csrftoken'; -Axios.defaults.headers.common.Accept = 'application/vnd.cvat.v1.0+json'; +Axios.defaults.headers.common.Accept = 'application/vnd.cvat+json; version=1.0'; onmessage = (e) => { Axios.get(e.data.url, e.data.config) diff --git a/cvat-core/src/server-proxy.js b/cvat-core/src/server-proxy.js index b35642e55199..79611f564c60 100644 --- a/cvat-core/src/server-proxy.js +++ b/cvat-core/src/server-proxy.js @@ -136,7 +136,7 @@ Axios.defaults.withCredentials = true; Axios.defaults.xsrfHeaderName = 'X-CSRFTOKEN'; Axios.defaults.xsrfCookieName = 'csrftoken'; - Axios.defaults.headers.common.Accept = 'application/vnd.cvat.v1.0+json'; + Axios.defaults.headers.common.Accept = 'application/vnd.cvat+json; version=1.0'; const workerAxios = new WorkerWrappedAxios(); Axios.interceptors.request.use((reqConfig) => { if ('params' in reqConfig && 'org' in reqConfig.params) { @@ -827,7 +827,7 @@ }, headers: { Authorization: `Token ${store.get('token')}`, - Accept: 'application/vnd.cvat.v1.0+json', + Accept: 'application/vnd.cvat+json; version=1.0', }, chunkSize, retryDelays: null, diff --git a/cvat/apps/engine/renderers.py b/cvat/apps/engine/renderers.py index c7c9511a95a5..32c78c2444d1 100644 --- a/cvat/apps/engine/renderers.py +++ b/cvat/apps/engine/renderers.py @@ -5,4 +5,4 @@ from rest_framework.renderers import JSONRenderer class CVATAPIRenderer(JSONRenderer): - media_type = 'application/vnd.cvat.v1.0+json' \ No newline at end of file + media_type = 'application/vnd.cvat+json' \ No newline at end of file diff --git a/cvat/apps/engine/versioning.py b/cvat/apps/engine/versioning.py index f8ee35026408..2804dd95eb9e 100644 --- a/cvat/apps/engine/versioning.py +++ b/cvat/apps/engine/versioning.py @@ -3,23 +3,16 @@ # SPDX-License-Identifier: MIT from rest_framework.versioning import AcceptHeaderVersioning -from rest_framework.exceptions import NotAcceptable class CustomAcceptHeaderVersioning(AcceptHeaderVersioning): """ GET /api/something/ HTTP/1.1 Host: localhost:8080 - Accept: application/vnd.cvat.v1.0+json + Accept: application/vnd.cvat+json; version=1.0 """ def determine_version(self, request, *args, **kwargs): - version = self._parse_version(request.accepted_media_type) - if not self.is_allowed_version(version): - raise NotAcceptable(self.invalid_version_message) - - def _parse_version(self, media_type): - try: - version = media_type.split('vnd.cvat')[1].split('+')[0].split('v')[1] - except Exception: - version = None - return version + # it's needed for browsable api + if request.accepted_media_type in {'text/html', 'application/json'}: + return 'api-docs' + return super().determine_version(request, *args, **kwargs) diff --git a/cvat/settings/base.py b/cvat/settings/base.py index 4bccdaf18165..6629802310a3 100644 --- a/cvat/settings/base.py +++ b/cvat/settings/base.py @@ -139,7 +139,9 @@ class BACKEND_VERSIONS(str, Enum): def __str__(self): return self.value -ACCEPT_HEADER_TEMPLATE = 'application/vnd.cvat.v{}+json' + @classmethod + def list(cls): + return list(map(lambda x: x.value, cls)) REST_FRAMEWORK = { 'DEFAULT_PARSER_CLASSES': [ @@ -150,6 +152,7 @@ def __str__(self): ], 'DEFAULT_RENDERER_CLASSES': [ 'cvat.apps.engine.renderers.CVATAPIRenderer', + 'rest_framework.renderers.BrowsableAPIRenderer', ], 'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.IsAuthenticated', @@ -168,7 +171,8 @@ def __str__(self): # of all possible methods isn't readable). 'cvat.apps.engine.versioning.CustomAcceptHeaderVersioning', # Need to add 'api-docs' here as a workaround for include_docs_urls. - 'ALLOWED_VERSIONS': (BACKEND_VERSIONS.V1_0, 'api-docs'), + 'ALLOWED_VERSIONS': (*BACKEND_VERSIONS.list(), 'api-docs'), + 'VERSION_PARAM': 'version', 'DEFAULT_PAGINATION_CLASS': 'cvat.apps.engine.pagination.CustomPagination', 'PAGE_SIZE': 10, @@ -189,6 +193,9 @@ def __str__(self): 'DEFAULT_METADATA_CLASS': 'rest_framework.metadata.SimpleMetadata', } +ACCEPT_HEADER_TEMPLATE_WITH_VERSION_PARAM = f'application/vnd.cvat+json; {REST_FRAMEWORK["VERSION_PARAM"]}=' +ACCEPT_HEADER_TEMPLATE = ''.join([ACCEPT_HEADER_TEMPLATE_WITH_VERSION_PARAM, '{}']) + REST_AUTH_REGISTER_SERIALIZERS = { 'REGISTER_SERIALIZER': 'cvat.apps.restrictions.serializers.RestrictedRegisterSerializer', } diff --git a/utils/cli/cli.py b/utils/cli/cli.py index c32fe3c544f0..32a961a6bbbe 100755 --- a/utils/cli/cli.py +++ b/utils/cli/cli.py @@ -35,7 +35,7 @@ def main(): api = CVAT_API_V1('%s:%s' % (args.server_host, args.server_port), args.https) cli = CLI(session, api, args.auth) #TODO add version indication - session.headers.update({'Accept': 'application/vnd.cvat.v1.0+json'}) + session.headers.update({'Accept': 'application/vnd.cvat+json; version=1.0'}) try: actions[args.action](cli, **args.__dict__) except (requests.exceptions.HTTPError, From 9ec3eb69e32f6f7361c779fb981cc03abab1225d Mon Sep 17 00:00:00 2001 From: Maya Date: Fri, 28 Jan 2022 17:23:17 +0300 Subject: [PATCH 06/20] fix workflow --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ea7e6ace638e..c8fe6690d949 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -76,7 +76,7 @@ jobs: API_ABOUT_PAGE: "localhost:8080/api/server/about" run: | docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f components/serverless/docker-compose.serverless.yml up -d - /bin/bash -c 'while [[ "$(curl -s -o /dev/null -w ''%{http_code}'' ${API_ABOUT_PAGE})" != "401" ]]; do sleep 5; done' + /bin/bash -c 'while [[ "$(curl -s -o /dev/null --header 'Accept: application/vnd.cvat+json; version=1.0' -w ''%{http_code}'' ${API_ABOUT_PAGE})" != "401" ]]; do sleep 5; done' cat tests/rest_api/assets/cvat_db.sql | docker exec -i cvat_db psql -q -U root -d cvat cat tests/rest_api/assets/cvat_data.tar.bz2 | docker run --rm -i --volumes-from cvat ubuntu tar -xj --strip 3 -C /home/django/data pip3 install --user -r tests/rest_api/requirements.txt From 08c677e0a3efc4c61f1579730fb7f7f3f5041219 Mon Sep 17 00:00:00 2001 From: Maya Date: Fri, 28 Jan 2022 17:44:58 +0300 Subject: [PATCH 07/20] Fix REST API tests --- tests/rest_api/test_0000_check_objects_integrity.py | 1 + tests/rest_api/test_0001_users_api.py | 9 ++++++--- tests/rest_api/test_0002_organizations.py | 6 ++++-- tests/rest_api/utils/config.py | 1 + 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/tests/rest_api/test_0000_check_objects_integrity.py b/tests/rest_api/test_0000_check_objects_integrity.py index 6e602e5f6096..13b7fd92316b 100644 --- a/tests/rest_api/test_0000_check_objects_integrity.py +++ b/tests/rest_api/test_0000_check_objects_integrity.py @@ -12,6 +12,7 @@ def test_check_objects_integrity(): with requests.Session() as session: session.auth = ('admin1', config.USER_PASS) + session.headers.update({'Accept': config.ACCEPT_HEADER}) for filename in glob.glob(os.path.join(config.ASSETS_DIR, '*.json')): with open(filename) as f: diff --git a/tests/rest_api/test_0001_users_api.py b/tests/rest_api/test_0001_users_api.py index 9f6eea7243dc..df93cbb4459a 100644 --- a/tests/rest_api/test_0001_users_api.py +++ b/tests/rest_api/test_0001_users_api.py @@ -12,12 +12,14 @@ def test_non_admin_cannot_see_others(): for username in ['dummy1', 'worker1', 'user1', 'business1']: - response = requests.get(config.get_api_url('users'), auth=(username, config.USER_PASS)) + response = requests.get(config.get_api_url('users'), auth=(username, config.USER_PASS), + headers={'Accept': config.ACCEPT_HEADER}) assert response.status_code == HTTPStatus.OK assert response.json()['count'] == 1 def test_admin_can_see_all_others(): - response = requests.get(config.get_api_url('users'), auth=('admin2', config.USER_PASS)) + response = requests.get(config.get_api_url('users'), auth=('admin2', config.USER_PASS), + headers={'Accept': config.ACCEPT_HEADER}) assert response.status_code == HTTPStatus.OK with open(os.path.join(config.ASSETS_DIR, 'users.json')) as f: data = json.load(f) @@ -29,7 +31,8 @@ def test_everybody_can_see_self(): users = {user['username']:user for user in data} for username in ['dummy1', 'worker1', 'user1', 'business1', 'admin1']: - response = requests.get(config.get_api_url('users/self'), auth=(username, config.USER_PASS)) + response = requests.get(config.get_api_url('users/self'), auth=(username, config.USER_PASS), + headers={'Accept': config.ACCEPT_HEADER}) assert response.status_code == HTTPStatus.OK assert DeepDiff(users[username], response.json(), ignore_order=True, exclude_paths="root['last_login']") == {} diff --git a/tests/rest_api/test_0002_organizations.py b/tests/rest_api/test_0002_organizations.py index 18d6b5a0a277..11963965cf51 100644 --- a/tests/rest_api/test_0002_organizations.py +++ b/tests/rest_api/test_0002_organizations.py @@ -16,10 +16,12 @@ def compare_organizations(org_id, response): DeepDiff(org, response.json()) def test_admin1_get_organization_id_1(): - response = requests.get(config.get_api_url('organizations/1'), auth=('admin1', config.USER_PASS)) + response = requests.get(config.get_api_url('organizations/1'), auth=('admin1', config.USER_PASS), + headers={'Accept': config.ACCEPT_HEADER}) compare_organizations(1, response) def test_user1_get_organization_id_1(): - response = requests.get(config.get_api_url('organizations/1'), auth=('user1', config.USER_PASS)) + response = requests.get(config.get_api_url('organizations/1'), auth=('user1', config.USER_PASS), + headers={'Accept': config.ACCEPT_HEADER}) compare_organizations(1, response) diff --git a/tests/rest_api/utils/config.py b/tests/rest_api/utils/config.py index 045effd54548..c650fd2a6568 100644 --- a/tests/rest_api/utils/config.py +++ b/tests/rest_api/utils/config.py @@ -9,6 +9,7 @@ # Suppress the warning from Bandit about hardcoded passwords USER_PASS = '!Q@W#E$R' # nosec BASE_URL = 'http://localhost:8080/api/' +ACCEPT_HEADER = 'application/vnd.cvat+json; version=1.0' def get_api_url(endpoint, **kwargs): return BASE_URL + endpoint + '?' + '&'.join([f'{k}={v}' for k,v in kwargs.items()]) \ No newline at end of file From 2451855ec68762d80a6f62235829c8d3e8f87d7c Mon Sep 17 00:00:00 2001 From: Maya Date: Mon, 31 Jan 2022 11:48:48 +0300 Subject: [PATCH 08/20] Update workflow --- .github/workflows/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c8fe6690d949..a69ed0091eaa 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -76,7 +76,7 @@ jobs: API_ABOUT_PAGE: "localhost:8080/api/server/about" run: | docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f components/serverless/docker-compose.serverless.yml up -d - /bin/bash -c 'while [[ "$(curl -s -o /dev/null --header 'Accept: application/vnd.cvat+json; version=1.0' -w ''%{http_code}'' ${API_ABOUT_PAGE})" != "401" ]]; do sleep 5; done' + /bin/bash -c "while [[ "$(curl -s -o /dev/null -H "Accept: application/vnd.cvat+json; version=1.0" -w ''%{http_code}'' ${API_ABOUT_PAGE})" != "401" ]]; do sleep 5; done" cat tests/rest_api/assets/cvat_db.sql | docker exec -i cvat_db psql -q -U root -d cvat cat tests/rest_api/assets/cvat_data.tar.bz2 | docker run --rm -i --volumes-from cvat ubuntu tar -xj --strip 3 -C /home/django/data pip3 install --user -r tests/rest_api/requirements.txt @@ -187,7 +187,7 @@ jobs: API_ABOUT_PAGE: "localhost:8080/api/server/about" run: | docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f components/serverless/docker-compose.serverless.yml -f tests/docker-compose.file_share.yml up -d - /bin/bash -c 'while [[ "$(curl -s -o /dev/null -w ''%{http_code}'' ${API_ABOUT_PAGE})" != "401" ]]; do sleep 5; done' + /bin/bash -c "while [[ "$(curl -s -o /dev/null -H "Accept: application/vnd.cvat+json; version=1.0" -w ''%{http_code}'' ${API_ABOUT_PAGE})" != "401" ]]; do sleep 5; done" docker exec -i cvat /bin/bash -c "echo \"from django.contrib.auth.models import User; User.objects.create_superuser('${DJANGO_SU_NAME}', '${DJANGO_SU_EMAIL}', '${DJANGO_SU_PASSWORD}')\" | python3 ~/manage.py shell" cd ./tests npm ci From 112e86faca036fa732574bedddf7ca8740902281 Mon Sep 17 00:00:00 2001 From: Maya Date: Mon, 31 Jan 2022 11:54:56 +0300 Subject: [PATCH 09/20] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 38d0d5b4001d..8fdd56e66ede 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Users don't have access to a task object anymore if they are assigneed only on some jobs of the task () - Different resources (tasks, projects) are not visible anymore for all CVAT instance users by default () +- API versioning scheme: using accept header versioning instead of namespace versioning () ### Deprecated - Job field "status" is not used in UI anymore, but it has not been removed from the database yet () From 7b841d3c158ed73b3f4e7586cca7aeeaa6e72746 Mon Sep 17 00:00:00 2001 From: Maya Date: Mon, 31 Jan 2022 12:10:34 +0300 Subject: [PATCH 10/20] Update workflows --- .github/workflows/main.yml | 4 ++-- .github/workflows/publish_docker_images.yml | 2 +- .github/workflows/schedule.yml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a69ed0091eaa..3fa9187ed824 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -76,7 +76,7 @@ jobs: API_ABOUT_PAGE: "localhost:8080/api/server/about" run: | docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f components/serverless/docker-compose.serverless.yml up -d - /bin/bash -c "while [[ "$(curl -s -o /dev/null -H "Accept: application/vnd.cvat+json; version=1.0" -w ''%{http_code}'' ${API_ABOUT_PAGE})" != "401" ]]; do sleep 5; done" + /bin/bash -c 'while [[ $(curl -s -o /dev/null -H "Accept: application/vnd.cvat+json; version=1.0" -w "%{http_code}" ${API_ABOUT_PAGE}) != "401" ]]; do sleep 5; done' cat tests/rest_api/assets/cvat_db.sql | docker exec -i cvat_db psql -q -U root -d cvat cat tests/rest_api/assets/cvat_data.tar.bz2 | docker run --rm -i --volumes-from cvat ubuntu tar -xj --strip 3 -C /home/django/data pip3 install --user -r tests/rest_api/requirements.txt @@ -187,7 +187,7 @@ jobs: API_ABOUT_PAGE: "localhost:8080/api/server/about" run: | docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f components/serverless/docker-compose.serverless.yml -f tests/docker-compose.file_share.yml up -d - /bin/bash -c "while [[ "$(curl -s -o /dev/null -H "Accept: application/vnd.cvat+json; version=1.0" -w ''%{http_code}'' ${API_ABOUT_PAGE})" != "401" ]]; do sleep 5; done" + /bin/bash -c 'while [[ $(curl -s -o /dev/null -H "Accept: application/vnd.cvat+json; version=1.0" -w "%{http_code}" ${API_ABOUT_PAGE}) != "401" ]]; do sleep 5; done' docker exec -i cvat /bin/bash -c "echo \"from django.contrib.auth.models import User; User.objects.create_superuser('${DJANGO_SU_NAME}', '${DJANGO_SU_EMAIL}', '${DJANGO_SU_PASSWORD}')\" | python3 ~/manage.py shell" cd ./tests npm ci diff --git a/.github/workflows/publish_docker_images.yml b/.github/workflows/publish_docker_images.yml index 4cb9bd1656e0..7ca1e5332967 100644 --- a/.github/workflows/publish_docker_images.yml +++ b/.github/workflows/publish_docker_images.yml @@ -32,7 +32,7 @@ jobs: run: | docker-compose -f docker-compose.yml -f docker-compose.dev.yml build docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f components/serverless/docker-compose.serverless.yml -f tests/docker-compose.file_share.yml up -d - /bin/bash -c 'while [[ "$(curl -s -o /dev/null -w ''%{http_code}'' ${API_ABOUT_PAGE})" != "401" ]]; do sleep 5; done' + /bin/bash -c 'while [[ $(curl -s -o /dev/null -H "Accept: application/vnd.cvat+json; version=1.0" -w "%{http_code}" ${API_ABOUT_PAGE}) != "401" ]]; do sleep 5; done' docker exec -i cvat /bin/bash -c "echo \"from django.contrib.auth.models import User; User.objects.create_superuser('${DJANGO_SU_NAME}', '${DJANGO_SU_EMAIL}', '${DJANGO_SU_PASSWORD}')\" | python3 ~/manage.py shell" cd ./tests npm ci diff --git a/.github/workflows/schedule.yml b/.github/workflows/schedule.yml index af81875e599f..141c73081c0c 100644 --- a/.github/workflows/schedule.yml +++ b/.github/workflows/schedule.yml @@ -19,7 +19,7 @@ jobs: API_ABOUT_PAGE: "localhost:8080/api/server/about" run: | docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f ./tests/docker-compose.email.yml -f tests/docker-compose.file_share.yml -f components/serverless/docker-compose.serverless.yml up -d --build - /bin/bash -c 'while [[ "$(curl -s -o /dev/null -w ''%{http_code}'' ${API_ABOUT_PAGE})" != "401" ]]; do sleep 5; done' + /bin/bash -c 'while [[ $(curl -s -o /dev/null -H "Accept: application/vnd.cvat+json; version=1.0" -w "%{http_code}" ${API_ABOUT_PAGE}) != "401" ]]; do sleep 5; done' docker exec -i cvat /bin/bash -c "echo \"from django.contrib.auth.models import User; User.objects.create_superuser('${DJANGO_SU_NAME}', '${DJANGO_SU_EMAIL}', '${DJANGO_SU_PASSWORD}')\" | python3 ~/manage.py shell" - name: End-to-end testing run: | From aa64bf8ea7a15e28d1ba1902cd825fa94138e79b Mon Sep 17 00:00:00 2001 From: Maya Date: Mon, 31 Jan 2022 19:12:47 +0300 Subject: [PATCH 11/20] Update cypress tests --- .../actions_users/issue_1810_login_logout.js | 5 ++++- .../remove_users_tasks_projects_organizations.js | 13 +++++++++++++ tests/cypress/support/commands.js | 11 +++++++++++ tests/cypress/support/commands_organizations.js | 4 ++++ tests/cypress/support/commands_projects.js | 4 ++++ tests/cypress/support/const.js | 3 ++- 6 files changed, 38 insertions(+), 2 deletions(-) diff --git a/tests/cypress/integration/actions_users/issue_1810_login_logout.js b/tests/cypress/integration/actions_users/issue_1810_login_logout.js index 62bf7f9be4d8..1bf33500fa8a 100644 --- a/tests/cypress/integration/actions_users/issue_1810_login_logout.js +++ b/tests/cypress/integration/actions_users/issue_1810_login_logout.js @@ -4,7 +4,7 @@ /// -import { taskName } from '../../support/const'; +import { acceptHeader, taskName } from '../../support/const'; context('When clicking on the Logout button, get the user session closed.', () => { const issueId = '1810'; @@ -60,6 +60,9 @@ context('When clicking on the Logout button, get the user session closed.', () = cy.request({ method: 'POST', url: '/api/auth/login', + headers: { + Accept: acceptHeader, + }, body: { username: Cypress.env('user'), email: Cypress.env('email'), diff --git a/tests/cypress/integration/remove_users_tasks_projects_organizations.js b/tests/cypress/integration/remove_users_tasks_projects_organizations.js index 407e8a42e38a..4e0bacf65c00 100644 --- a/tests/cypress/integration/remove_users_tasks_projects_organizations.js +++ b/tests/cypress/integration/remove_users_tasks_projects_organizations.js @@ -4,6 +4,8 @@ /// +import { acceptHeader } from '../support/const'; + let authKey = ''; describe('Delete users, tasks, projects, organizations created during the tests run.', () => { @@ -11,6 +13,9 @@ describe('Delete users, tasks, projects, organizations created during the tests cy.request({ method: 'POST', url: '/api/auth/login', + headers: { + Accept: acceptHeader, + }, body: { username: Cypress.env('user'), email: Cypress.env('email'), @@ -26,6 +31,7 @@ describe('Delete users, tasks, projects, organizations created during the tests url: '/api/tasks?page_size=1000', headers: { Authorization: `Token ${authKey}`, + Accept: acceptHeader, }, }).then((response) => { const responseResult = response.body.results; @@ -36,6 +42,7 @@ describe('Delete users, tasks, projects, organizations created during the tests url: `/api/tasks/${id}`, headers: { Authorization: `Token ${authKey}`, + Accept: acceptHeader, }, }); } @@ -47,6 +54,7 @@ describe('Delete users, tasks, projects, organizations created during the tests url: '/api/projects?page_size=all', headers: { Authorization: `Token ${authKey}`, + Accept: acceptHeader, }, }).then((response) => { const responseResult = response.body.results; @@ -57,6 +65,7 @@ describe('Delete users, tasks, projects, organizations created during the tests url: `/api/projects/${id}`, headers: { Authorization: `Token ${authKey}`, + Accept: acceptHeader, }, }); } @@ -68,6 +77,7 @@ describe('Delete users, tasks, projects, organizations created during the tests url: '/api/organizations?page_size=all', headers: { Authorization: `Token ${authKey}`, + Accept: acceptHeader, }, }).then((response) => { const responseResult = response.body; @@ -78,6 +88,7 @@ describe('Delete users, tasks, projects, organizations created during the tests url: `/api/organizations/${id}`, headers: { Authorization: `Token ${authKey}`, + Accept: acceptHeader, }, }); } @@ -89,6 +100,7 @@ describe('Delete users, tasks, projects, organizations created during the tests url: '/api/users', headers: { Authorization: `Token ${authKey}`, + Accept: acceptHeader, }, }).then((response) => { const responseResult = response.body.results; @@ -100,6 +112,7 @@ describe('Delete users, tasks, projects, organizations created during the tests url: `/api/users/${id}`, headers: { Authorization: `Token ${authKey}`, + Accept: acceptHeader, }, }); } diff --git a/tests/cypress/support/commands.js b/tests/cypress/support/commands.js index 08cc6abaefa8..187fd441ee3a 100644 --- a/tests/cypress/support/commands.js +++ b/tests/cypress/support/commands.js @@ -5,6 +5,7 @@ /// import { decomposeMatrix } from './utils'; +import { acceptHeader } from './const'; require('cypress-file-upload'); require('../plugins/imageGenerator/imageGeneratorCommand'); @@ -56,6 +57,9 @@ Cypress.Commands.add('getAuthKey', () => { cy.request({ method: 'POST', url: '/api/auth/login', + headers: { + Accept: acceptHeader, + }, body: { username: Cypress.env('user'), email: Cypress.env('email'), @@ -70,6 +74,7 @@ Cypress.Commands.add('deleteUsers', (authResponse, accountsToDelete) => { url: '/api/users?page_size=all', headers: { Authorization: `Token ${authKey}`, + Accept: acceptHeader, }, }).then((_response) => { const responseResult = _response.body.results; @@ -82,6 +87,7 @@ Cypress.Commands.add('deleteUsers', (authResponse, accountsToDelete) => { url: `/api/users/${id}`, headers: { Authorization: `Token ${authKey}`, + Accept: acceptHeader, }, }); } @@ -95,6 +101,7 @@ Cypress.Commands.add('changeUserActiveStatus', (authKey, accountsToChangeActiveS url: '/api/users?page_size=all', headers: { Authorization: `Token ${authKey}`, + Accept: acceptHeader, }, }).then((response) => { const responceResult = response.body.results; @@ -107,6 +114,7 @@ Cypress.Commands.add('changeUserActiveStatus', (authKey, accountsToChangeActiveS url: `/api/users/${userId}`, headers: { Authorization: `Token ${authKey}`, + Accept: acceptHeader, }, body: { is_active: isActive, @@ -122,6 +130,7 @@ Cypress.Commands.add('checkUserStatuses', (authKey, userName, staffStatus, super url: '/api/users?page_size=all', headers: { Authorization: `Token ${authKey}`, + Accept: acceptHeader, }, }).then((response) => { const responceResult = response.body.results; @@ -141,6 +150,7 @@ Cypress.Commands.add('deleteTasks', (authResponse, tasksToDelete) => { url: '/api/tasks?page_size=all', headers: { Authorization: `Token ${authKey}`, + Accept: acceptHeader, }, }).then((_response) => { const responceResult = _response.body.results; @@ -153,6 +163,7 @@ Cypress.Commands.add('deleteTasks', (authResponse, tasksToDelete) => { url: `/api/tasks/${id}`, headers: { Authorization: `Token ${authKey}`, + Accept: acceptHeader, }, }); } diff --git a/tests/cypress/support/commands_organizations.js b/tests/cypress/support/commands_organizations.js index 7dcf6034a8b4..a95f76964248 100644 --- a/tests/cypress/support/commands_organizations.js +++ b/tests/cypress/support/commands_organizations.js @@ -4,6 +4,8 @@ /// +import { acceptHeader } from './const'; + Cypress.Commands.add('createOrganization', (organizationParams) => { cy.get('.cvat-header-menu-user-dropdown').trigger('mouseover'); cy.get('.cvat-header-menu') @@ -34,6 +36,7 @@ Cypress.Commands.add('deleteOrganizations', (authResponse, otrganizationsToDelet url: '/api/organizations?page_size=all', headers: { Authorization: `Token ${authKey}`, + Accept: acceptHeader, }, }).then((_response) => { const responceResult = _response.body; @@ -46,6 +49,7 @@ Cypress.Commands.add('deleteOrganizations', (authResponse, otrganizationsToDelet url: `/api/organizations/${id}`, headers: { Authorization: `Token ${authKey}`, + Accept: acceptHeader, }, }); } diff --git a/tests/cypress/support/commands_projects.js b/tests/cypress/support/commands_projects.js index aa84a0a11076..655222173913 100644 --- a/tests/cypress/support/commands_projects.js +++ b/tests/cypress/support/commands_projects.js @@ -4,6 +4,8 @@ /// +import { acceptHeader } from './const'; + Cypress.Commands.add('goToProjectsList', () => { cy.get('[value="projects"]').click(); cy.url().should('include', '/projects'); @@ -44,6 +46,7 @@ Cypress.Commands.add('deleteProjects', (authResponse, projectsToDelete) => { url: '/api/projects?page_size=all', headers: { Authorization: `Token ${authKey}`, + Accept: acceptHeader, }, }).then((_response) => { const responceResult = _response.body.results; @@ -56,6 +59,7 @@ Cypress.Commands.add('deleteProjects', (authResponse, projectsToDelete) => { url: `/api/projects/${id}`, headers: { Authorization: `Token ${authKey}`, + Accept: acceptHeader, }, }); } diff --git a/tests/cypress/support/const.js b/tests/cypress/support/const.js index 9c2c08381568..834d97d8f4a6 100644 --- a/tests/cypress/support/const.js +++ b/tests/cypress/support/const.js @@ -1,4 +1,4 @@ -// Copyright (C) 2020 Intel Corporation +// Copyright (C) 2020-2022 Intel Corporation // // SPDX-License-Identifier: MIT @@ -32,6 +32,7 @@ export const multiAttrParams = { additionalValue: `Attr value 2`, typeAttribute: 'Text', }; +export const acceptHeader = 'application/vnd.cvat+json; version=1.0'; it('Prepare to testing', () => { cy.visit('/'); From a2697b3363634b9651137fb25399d02db14f375a Mon Sep 17 00:00:00 2001 From: Maya Date: Mon, 31 Jan 2022 19:19:01 +0300 Subject: [PATCH 12/20] Fix eslint issues --- tests/cypress/support/const.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/cypress/support/const.js b/tests/cypress/support/const.js index 834d97d8f4a6..de63c665b472 100644 --- a/tests/cypress/support/const.js +++ b/tests/cypress/support/const.js @@ -4,7 +4,7 @@ /// -export const labelName = `Main task`; +export const labelName = 'Main task'; export const taskName = `New annotation task for ${labelName}`; export const attrName = `Attr for ${labelName}`; export const textDefaultValue = 'Some default value for type Text'; @@ -28,8 +28,8 @@ export const advancedConfigurationParams = { frameStep: 2, }; export const multiAttrParams = { - additionalAttrName: `Attr 2`, - additionalValue: `Attr value 2`, + additionalAttrName: 'Attr 2', + additionalValue: 'Attr value 2', typeAttribute: 'Text', }; export const acceptHeader = 'application/vnd.cvat+json; version=1.0'; @@ -38,14 +38,14 @@ it('Prepare to testing', () => { cy.visit('/'); cy.login(); cy.get('.cvat-tasks-page').should('exist'); - let listItems = []; + const listItems = []; cy.document().then((doc) => { const collection = Array.from(doc.querySelectorAll('.cvat-item-task-name')); for (let i = 0; i < collection.length; i++) { listItems.push(collection[i].innerText); } if (listItems.indexOf(taskName) === -1) { - cy.task('log', "A task doesn't exist. Creating."); + cy.task('log', 'A task doesn\'t exist. Creating.'); cy.imageGenerator(imagesFolder, imageFileName, width, height, color, posX, posY, labelName, imagesCount); cy.createZipArchive(directoryToArchive, archivePath); cy.createAnnotationTask( From 4a31881101cb2caad91d4905064d6f3a1d89e0b9 Mon Sep 17 00:00:00 2001 From: Maya Date: Tue, 1 Feb 2022 13:25:14 +0300 Subject: [PATCH 13/20] Dummy fix for downloading resources --- cvat/apps/engine/versioning.py | 10 +++++++++- cvat/settings/base.py | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/cvat/apps/engine/versioning.py b/cvat/apps/engine/versioning.py index 2804dd95eb9e..972f49e93a45 100644 --- a/cvat/apps/engine/versioning.py +++ b/cvat/apps/engine/versioning.py @@ -3,6 +3,7 @@ # SPDX-License-Identifier: MIT from rest_framework.versioning import AcceptHeaderVersioning +from rest_framework.exceptions import NotAcceptable class CustomAcceptHeaderVersioning(AcceptHeaderVersioning): """ @@ -15,4 +16,11 @@ def determine_version(self, request, *args, **kwargs): # it's needed for browsable api if request.accepted_media_type in {'text/html', 'application/json'}: return 'api-docs' - return super().determine_version(request, *args, **kwargs) + try: + version = super().determine_version(request, *args, **kwargs) + except NotAcceptable: + # resource download requests such as backup/annotation files + if request.query_params.get('action') == 'download': + version = 'downloading' + else: raise + return version diff --git a/cvat/settings/base.py b/cvat/settings/base.py index 5998986a1139..947acce5ce6b 100644 --- a/cvat/settings/base.py +++ b/cvat/settings/base.py @@ -171,7 +171,7 @@ def list(cls): # of all possible methods isn't readable). 'cvat.apps.engine.versioning.CustomAcceptHeaderVersioning', # Need to add 'api-docs' here as a workaround for include_docs_urls. - 'ALLOWED_VERSIONS': (*BACKEND_VERSIONS.list(), 'api-docs'), + 'ALLOWED_VERSIONS': (*BACKEND_VERSIONS.list(), 'api-docs', 'downloading'), 'VERSION_PARAM': 'version', 'DEFAULT_PAGINATION_CLASS': 'cvat.apps.engine.pagination.CustomPagination', From 39564eaae16119a3ca786d020ef8db6081d31492 Mon Sep 17 00:00:00 2001 From: Maya Date: Wed, 2 Feb 2022 11:46:48 +0300 Subject: [PATCH 14/20] Use default version --- .github/workflows/main.yml | 4 +- .github/workflows/publish_docker_images.yml | 2 +- .github/workflows/schedule.yml | 2 +- cvat-core/src/download.worker.js | 1 - cvat-core/src/server-proxy.js | 2 - .../dataset_manager/tests/test_formats.py | 10 +-- .../tests/test_rest_api_formats.py | 10 +-- cvat/apps/dataset_repo/tests.py | 11 +--- cvat/apps/engine/tests/test_rest_api.py | 63 +++++++++---------- cvat/apps/engine/tests/test_rest_api_3D.py | 10 +-- cvat/apps/iam/tests/test_rest_api.py | 6 +- cvat/apps/lambda_manager/tests/test_lambda.py | 10 +-- cvat/apps/restrictions/tests.py | 6 +- cvat/settings/base.py | 22 +------ .../actions_users/issue_1810_login_logout.js | 5 +- ...move_users_tasks_projects_organizations.js | 13 ---- tests/cypress/support/commands.js | 11 ---- .../cypress/support/commands_organizations.js | 4 -- tests/cypress/support/commands_projects.js | 4 -- tests/cypress/support/const.js | 1 - .../test_0000_check_objects_integrity.py | 1 - tests/rest_api/test_0001_users_api.py | 9 +-- tests/rest_api/test_0002_organizations.py | 6 +- tests/rest_api/utils/config.py | 1 - utils/cli/cli.py | 2 - utils/cli/tests/test_cli.py | 1 - 26 files changed, 53 insertions(+), 164 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3fa9187ed824..d6de7a3a30e8 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -76,7 +76,7 @@ jobs: API_ABOUT_PAGE: "localhost:8080/api/server/about" run: | docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f components/serverless/docker-compose.serverless.yml up -d - /bin/bash -c 'while [[ $(curl -s -o /dev/null -H "Accept: application/vnd.cvat+json; version=1.0" -w "%{http_code}" ${API_ABOUT_PAGE}) != "401" ]]; do sleep 5; done' + /bin/bash -c 'while [[ $(curl -s -o /dev/null -w "%{http_code}" ${API_ABOUT_PAGE}) != "401" ]]; do sleep 5; done' cat tests/rest_api/assets/cvat_db.sql | docker exec -i cvat_db psql -q -U root -d cvat cat tests/rest_api/assets/cvat_data.tar.bz2 | docker run --rm -i --volumes-from cvat ubuntu tar -xj --strip 3 -C /home/django/data pip3 install --user -r tests/rest_api/requirements.txt @@ -187,7 +187,7 @@ jobs: API_ABOUT_PAGE: "localhost:8080/api/server/about" run: | docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f components/serverless/docker-compose.serverless.yml -f tests/docker-compose.file_share.yml up -d - /bin/bash -c 'while [[ $(curl -s -o /dev/null -H "Accept: application/vnd.cvat+json; version=1.0" -w "%{http_code}" ${API_ABOUT_PAGE}) != "401" ]]; do sleep 5; done' + /bin/bash -c 'while [[ $(curl -s -o /dev/null -w "%{http_code}" ${API_ABOUT_PAGE}) != "401" ]]; do sleep 5; done' docker exec -i cvat /bin/bash -c "echo \"from django.contrib.auth.models import User; User.objects.create_superuser('${DJANGO_SU_NAME}', '${DJANGO_SU_EMAIL}', '${DJANGO_SU_PASSWORD}')\" | python3 ~/manage.py shell" cd ./tests npm ci diff --git a/.github/workflows/publish_docker_images.yml b/.github/workflows/publish_docker_images.yml index 7ca1e5332967..67cd1d9a724e 100644 --- a/.github/workflows/publish_docker_images.yml +++ b/.github/workflows/publish_docker_images.yml @@ -32,7 +32,7 @@ jobs: run: | docker-compose -f docker-compose.yml -f docker-compose.dev.yml build docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f components/serverless/docker-compose.serverless.yml -f tests/docker-compose.file_share.yml up -d - /bin/bash -c 'while [[ $(curl -s -o /dev/null -H "Accept: application/vnd.cvat+json; version=1.0" -w "%{http_code}" ${API_ABOUT_PAGE}) != "401" ]]; do sleep 5; done' + /bin/bash -c 'while [[ $(curl -s -o /dev/null -w "%{http_code}" ${API_ABOUT_PAGE}) != "401" ]]; do sleep 5; done' docker exec -i cvat /bin/bash -c "echo \"from django.contrib.auth.models import User; User.objects.create_superuser('${DJANGO_SU_NAME}', '${DJANGO_SU_EMAIL}', '${DJANGO_SU_PASSWORD}')\" | python3 ~/manage.py shell" cd ./tests npm ci diff --git a/.github/workflows/schedule.yml b/.github/workflows/schedule.yml index 141c73081c0c..7f6d7005f926 100644 --- a/.github/workflows/schedule.yml +++ b/.github/workflows/schedule.yml @@ -19,7 +19,7 @@ jobs: API_ABOUT_PAGE: "localhost:8080/api/server/about" run: | docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f ./tests/docker-compose.email.yml -f tests/docker-compose.file_share.yml -f components/serverless/docker-compose.serverless.yml up -d --build - /bin/bash -c 'while [[ $(curl -s -o /dev/null -H "Accept: application/vnd.cvat+json; version=1.0" -w "%{http_code}" ${API_ABOUT_PAGE}) != "401" ]]; do sleep 5; done' + /bin/bash -c 'while [[ $(curl -s -o /dev/null -w "%{http_code}" ${API_ABOUT_PAGE}) != "401" ]]; do sleep 5; done' docker exec -i cvat /bin/bash -c "echo \"from django.contrib.auth.models import User; User.objects.create_superuser('${DJANGO_SU_NAME}', '${DJANGO_SU_EMAIL}', '${DJANGO_SU_PASSWORD}')\" | python3 ~/manage.py shell" - name: End-to-end testing run: | diff --git a/cvat-core/src/download.worker.js b/cvat-core/src/download.worker.js index be0ddc947e67..687f0fc0f2b9 100644 --- a/cvat-core/src/download.worker.js +++ b/cvat-core/src/download.worker.js @@ -7,7 +7,6 @@ const Axios = require('axios'); Axios.defaults.withCredentials = true; Axios.defaults.xsrfHeaderName = 'X-CSRFTOKEN'; Axios.defaults.xsrfCookieName = 'csrftoken'; -Axios.defaults.headers.common.Accept = 'application/vnd.cvat+json; version=1.0'; onmessage = (e) => { Axios.get(e.data.url, e.data.config) diff --git a/cvat-core/src/server-proxy.js b/cvat-core/src/server-proxy.js index af2dd9a6ff13..ca46f12d5f79 100644 --- a/cvat-core/src/server-proxy.js +++ b/cvat-core/src/server-proxy.js @@ -136,7 +136,6 @@ Axios.defaults.withCredentials = true; Axios.defaults.xsrfHeaderName = 'X-CSRFTOKEN'; Axios.defaults.xsrfCookieName = 'csrftoken'; - Axios.defaults.headers.common.Accept = 'application/vnd.cvat+json; version=1.0'; const workerAxios = new WorkerWrappedAxios(); Axios.interceptors.request.use((reqConfig) => { if ('params' in reqConfig && 'org' in reqConfig.params) { @@ -827,7 +826,6 @@ }, headers: { Authorization: `Token ${store.get('token')}`, - Accept: 'application/vnd.cvat+json; version=1.0', }, chunkSize, retryDelays: null, diff --git a/cvat/apps/dataset_manager/tests/test_formats.py b/cvat/apps/dataset_manager/tests/test_formats.py index 72f4a1af5f53..1bfa358d8c4c 100644 --- a/cvat/apps/dataset_manager/tests/test_formats.py +++ b/cvat/apps/dataset_manager/tests/test_formats.py @@ -37,16 +37,14 @@ def generate_image_file(filename, size=(100, 100)): return f class ForceLogin: - def __init__(self, user, client, version=settings.BACKEND_VERSIONS.V1_0): + def __init__(self, user, client): self.user = user self.client = client - self.version = version def __enter__(self): if self.user: self.client.force_login(self.user, backend='django.contrib.auth.backends.ModelBackend') - self.client.credentials(HTTP_ACCEPT=settings.ACCEPT_HEADER_TEMPLATE.format(self.version)) return self @@ -54,13 +52,9 @@ def __exit__(self, exception_type, exception_value, traceback): if self.user: self.client.logout() -class VersionedAPIClient(APIClient): - def __init__(self, version=settings.BACKEND_VERSIONS.V1_0): - super().__init__(HTTP_ACCEPT=settings.ACCEPT_HEADER_TEMPLATE.format(version)) - class _DbTestBase(APITestCase): def setUp(self): - self.client = VersionedAPIClient() + self.client = APIClient() @classmethod def setUpTestData(cls): diff --git a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py index 5c614a37af35..43a77db01616 100644 --- a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py +++ b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py @@ -86,16 +86,14 @@ def generate_video_file(filename, width=1280, height=720, duration=1, fps=25, co class ForceLogin: - def __init__(self, user, client, version=settings.BACKEND_VERSIONS.V1_0): + def __init__(self, user, client): self.user = user self.client = client - self.version = version def __enter__(self): if self.user: self.client.force_login(self.user, backend='django.contrib.auth.backends.ModelBackend') - self.client.credentials(HTTP_ACCEPT=settings.ACCEPT_HEADER_TEMPLATE.format(self.version)) return self @@ -103,13 +101,9 @@ def __exit__(self, exception_type, exception_value, traceback): if self.user: self.client.logout() -class VersionedAPIClient(APIClient): - def __init__(self, version=settings.BACKEND_VERSIONS.V1_0): - super().__init__(HTTP_ACCEPT=settings.ACCEPT_HEADER_TEMPLATE.format(version)) - class _DbTestBase(APITestCase): def setUp(self): - self.client = VersionedAPIClient() + self.client = APIClient() @classmethod def setUpTestData(cls): diff --git a/cvat/apps/dataset_repo/tests.py b/cvat/apps/dataset_repo/tests.py index da079cb3671c..b8193458c2bb 100644 --- a/cvat/apps/dataset_repo/tests.py +++ b/cvat/apps/dataset_repo/tests.py @@ -36,16 +36,14 @@ def generate_image_file(filename, size=(100, 50)): class ForceLogin: - def __init__(self, user, client, version=settings.BACKEND_VERSIONS.V1_0): + def __init__(self, user, client): self.user = user self.client = client - self.version = version def __enter__(self): if self.user: self.client.force_login(self.user, backend='django.contrib.auth.backends.ModelBackend') - self.client.credentials(HTTP_ACCEPT=settings.ACCEPT_HEADER_TEMPLATE.format(self.version)) return self @@ -53,7 +51,6 @@ def __exit__(self, exception_type, exception_value, traceback): if self.user: self.client.logout() - class GitRemote: def pull(self, refspec=None, progress=None, **kwargs): _ = (refspec, progress, *kwargs) @@ -144,17 +141,13 @@ def clone(self): def reclone(self): self._reclone() -class VersionedAPIClient(APIClient): - def __init__(self, version=settings.BACKEND_VERSIONS.V1_0): - super().__init__(HTTP_ACCEPT=settings.ACCEPT_HEADER_TEMPLATE.format(version)) - class GitDatasetRepoTest(APITestCase): class FakeGit: def __init__(self, url): self._url = url def setUp(self): - self.client = VersionedAPIClient() + self.client = APIClient() db_git = GitData() db_git.url = GIT_URL diff --git a/cvat/apps/engine/tests/test_rest_api.py b/cvat/apps/engine/tests/test_rest_api.py index f1e405c38f23..12bc7e1e66a3 100644 --- a/cvat/apps/engine/tests/test_rest_api.py +++ b/cvat/apps/engine/tests/test_rest_api.py @@ -237,15 +237,13 @@ def create_dummy_db_projects(obj): class ForceLogin: - def __init__(self, user, client, version=settings.BACKEND_VERSIONS.V1_0): + def __init__(self, user, client): self.user = user self.client = client - self.version = version def __enter__(self): if self.user: self.client.force_login(self.user, backend='django.contrib.auth.backends.ModelBackend') - self.client.credentials(HTTP_ACCEPT=settings.ACCEPT_HEADER_TEMPLATE.format(self.version)) return self @@ -253,14 +251,9 @@ def __exit__(self, exception_type, exception_value, traceback): if self.user: self.client.logout() - -class VersionedAPIClient(APIClient): - def __init__(self, version=settings.BACKEND_VERSIONS.V1_0): - super().__init__(HTTP_ACCEPT=settings.ACCEPT_HEADER_TEMPLATE.format(version)) - class JobGetAPITestCase(APITestCase): def setUp(self): - self.client = VersionedAPIClient() + self.client = APIClient() @classmethod def setUpTestData(cls): @@ -322,7 +315,7 @@ def test_api_v1_jobs_id_no_auth(self): class JobUpdateAPITestCase(APITestCase): def setUp(self): - self.client = VersionedAPIClient() + self.client = APIClient() self.task = create_dummy_db_tasks(self)[0] self.job = Job.objects.filter(segment__task_id=self.task.id).first() self.job.assignee = self.annotator @@ -408,7 +401,7 @@ def test_api_v1_jobs_id_admin_partial(self): class ServerAboutAPITestCase(APITestCase): def setUp(self): - self.client = VersionedAPIClient() + self.client = APIClient() @classmethod def setUpTestData(cls): @@ -440,7 +433,7 @@ def test_api_v1_server_about_no_auth(self): class ServerExceptionAPITestCase(APITestCase): def setUp(self): - self.client = VersionedAPIClient() + self.client = APIClient() @classmethod def setUpTestData(cls): @@ -484,7 +477,7 @@ def test_api_v1_server_exception_no_auth(self): class ServerLogsAPITestCase(APITestCase): def setUp(self): - self.client = VersionedAPIClient() + self.client = APIClient() @classmethod def setUpTestData(cls): @@ -532,7 +525,7 @@ def test_api_v1_server_logs_no_auth(self): class UserAPITestCase(APITestCase): def setUp(self): - self.client = VersionedAPIClient() + self.client = APIClient() create_db_users(self) def _check_response(self, user, response, is_full=True): @@ -742,7 +735,7 @@ def test_api_v1_users_id_no_auth(self): class ProjectListAPITestCase(APITestCase): def setUp(self): - self.client = VersionedAPIClient() + self.client = APIClient() @classmethod def setUpTestData(cls): @@ -782,7 +775,7 @@ def test_api_v1_projects_no_auth(self): class ProjectGetAPITestCase(APITestCase): def setUp(self): - self.client = VersionedAPIClient() + self.client = APIClient() @classmethod def setUpTestData(cls): @@ -831,7 +824,7 @@ def test_api_v1_projects_id_no_auth(self): class ProjectDeleteAPITestCase(APITestCase): def setUp(self): - self.client = VersionedAPIClient() + self.client = APIClient() @classmethod def setUpTestData(cls): @@ -869,7 +862,7 @@ def test_api_v1_projects_id_no_auth(self): class ProjectCreateAPITestCase(APITestCase): def setUp(self): - self.client = VersionedAPIClient() + self.client = APIClient() @classmethod def setUpTestData(cls): @@ -962,7 +955,7 @@ def test_api_v1_projects_no_auth(self): class ProjectPartialUpdateAPITestCase(APITestCase): def setUp(self): - self.client = VersionedAPIClient() + self.client = APIClient() @classmethod def setUpTestData(cls): @@ -1042,7 +1035,7 @@ def test_api_v1_projects_id_no_auth(self): class UpdateLabelsAPITestCase(APITestCase): def setUp(self): - self.client = VersionedAPIClient() + self.client = APIClient() def assertLabelsEqual(self, label1, label2): self.assertEqual(label1.get("name", label2.get("name")), label2.get("name")) @@ -1140,7 +1133,7 @@ def test_api_v1_projects_delete_label(self): class ProjectListOfTasksAPITestCase(APITestCase): def setUp(self): - self.client = VersionedAPIClient() + self.client = APIClient() @classmethod def setUpTestData(cls): @@ -1563,7 +1556,7 @@ def test_api_v1_projects_id_export_no_auth(self): class ProjectExportAPITestCase(APITestCase): def setUp(self): - self.client = VersionedAPIClient() + self.client = APIClient() @classmethod def setUpTestData(cls): @@ -1637,7 +1630,7 @@ def test_api_v1_projects_remove_task_export(self): class ProjectImportExportAPITestCase(APITestCase): def setUp(self) -> None: - self.client = VersionedAPIClient() + self.client = APIClient() self.tasks = [] self.projects = [] @@ -1792,7 +1785,7 @@ def tearDown(self) -> None: class TaskListAPITestCase(APITestCase): def setUp(self): - self.client = VersionedAPIClient() + self.client = APIClient() @classmethod def setUpTestData(cls): @@ -1832,7 +1825,7 @@ def test_api_v1_tasks_no_auth(self): class TaskGetAPITestCase(APITestCase): def setUp(self): - self.client = VersionedAPIClient() + self.client = APIClient() @classmethod def setUpTestData(cls): @@ -1890,7 +1883,7 @@ def test_api_v1_tasks_id_no_auth(self): class TaskDeleteAPITestCase(APITestCase): def setUp(self): - self.client = VersionedAPIClient() + self.client = APIClient() @classmethod def setUpTestData(cls): @@ -1938,7 +1931,7 @@ def test_api_v1_tasks_delete_task_data_after_delete_task(self): class TaskUpdateAPITestCase(APITestCase): def setUp(self): - self.client = VersionedAPIClient() + self.client = APIClient() @classmethod def setUpTestData(cls): @@ -2174,7 +2167,7 @@ def test_api_v1_tasks_delete_label(self): class TaskMoveAPITestCase(APITestCase): def setUp(self): - self.client = VersionedAPIClient() + self.client = APIClient() self._run_api_v1_job_id_annotation(self.task.segment_set.first().job_set.first().id, self.annotation_data) @@ -2357,7 +2350,7 @@ def test_move_task(self): class TaskCreateAPITestCase(APITestCase): def setUp(self): - self.client = VersionedAPIClient() + self.client = APIClient() project = { "name": "Project for task creation", "owner": self.user, @@ -2467,7 +2460,7 @@ def test_api_v1_tasks_no_auth(self): class TaskImportExportAPITestCase(APITestCase): def setUp(self): - self.client = VersionedAPIClient() + self.client = APIClient() self.tasks = [] @classmethod @@ -2975,7 +2968,7 @@ def __str__(self): return self.value def setUp(self): - self.client = VersionedAPIClient() + self.client = APIClient() @classmethod def setUpTestData(cls): @@ -3884,7 +3877,7 @@ def compare_objects(self, obj1, obj2, ignore_keys, fp_tolerance=.001, class JobAnnotationAPITestCase(APITestCase): def setUp(self): - self.client = VersionedAPIClient() + self.client = APIClient() @classmethod def setUpTestData(cls): @@ -5743,7 +5736,7 @@ def test_api_v1_tasks_id_annotations_upload_coco_user(self): class ServerShareAPITestCase(APITestCase): def setUp(self): - self.client = VersionedAPIClient() + self.client = APIClient() @classmethod def setUpTestData(cls): @@ -5861,7 +5854,7 @@ def test_api_v1_server_share_no_auth(self): class ServerShareDifferentTypesAPITestCase(APITestCase): def setUp(self): - self.client = VersionedAPIClient() + self.client = APIClient() @classmethod def setUpTestData(cls): @@ -5945,7 +5938,7 @@ def test_api_v1_combined_image_and_directory_extractors(self): class TaskAnnotation2DContext(APITestCase): def setUp(self): - self.client = VersionedAPIClient() + self.client = APIClient() self.task = { "name": "my archive task without copying #11", "overlap": 0, diff --git a/cvat/apps/engine/tests/test_rest_api_3D.py b/cvat/apps/engine/tests/test_rest_api_3D.py index afcfab4473ce..26952293abda 100644 --- a/cvat/apps/engine/tests/test_rest_api_3D.py +++ b/cvat/apps/engine/tests/test_rest_api_3D.py @@ -31,16 +31,14 @@ class ForceLogin: - def __init__(self, user, client, version=settings.BACKEND_VERSIONS.V1_0): + def __init__(self, user, client): self.user = user self.client = client - self.version = version def __enter__(self): if self.user: self.client.force_login(self.user, backend='django.contrib.auth.backends.ModelBackend') - self.client.credentials(HTTP_ACCEPT=settings.ACCEPT_HEADER_TEMPLATE.format(self.version)) return self @@ -48,13 +46,9 @@ def __exit__(self, exception_type, exception_value, traceback): if self.user: self.client.logout() -class VersionedAPIClient(APIClient): - def __init__(self, version=settings.BACKEND_VERSIONS.V1_0): - super().__init__(HTTP_ACCEPT=settings.ACCEPT_HEADER_TEMPLATE.format(version)) - class _DbTestBase(APITestCase): def setUp(self): - self.client = VersionedAPIClient() + self.client = APIClient() @classmethod def setUpTestData(cls): diff --git a/cvat/apps/iam/tests/test_rest_api.py b/cvat/apps/iam/tests/test_rest_api.py index 4ad8ca5be452..18d02e23d632 100644 --- a/cvat/apps/iam/tests/test_rest_api.py +++ b/cvat/apps/iam/tests/test_rest_api.py @@ -20,10 +20,6 @@ name='account_email_verification_sent'), ] -class VersionedAPIClient(APIClient): - def __init__(self, version=settings.BACKEND_VERSIONS.V1_0): - super().__init__(HTTP_ACCEPT=settings.ACCEPT_HEADER_TEMPLATE.format(version)) - class UserRegisterAPITestCase(APITestCase): user_data = {'first_name': 'test_first', 'last_name': 'test_last', 'username': 'test_username', @@ -31,7 +27,7 @@ class UserRegisterAPITestCase(APITestCase): 'confirmations': []} def setUp(self): - self.client = VersionedAPIClient() + self.client = APIClient() def _run_api_v1_user_register(self, data): url = reverse('rest_register') diff --git a/cvat/apps/lambda_manager/tests/test_lambda.py b/cvat/apps/lambda_manager/tests/test_lambda.py index b69cdfbead0a..d5ef94ca27a2 100644 --- a/cvat/apps/lambda_manager/tests/test_lambda.py +++ b/cvat/apps/lambda_manager/tests/test_lambda.py @@ -58,15 +58,13 @@ def generate_image_file(filename, size=(100, 100)): class ForceLogin: - def __init__(self, user, client, version=settings.BACKEND_VERSIONS.V1_0): + def __init__(self, user, client): self.user = user self.client = client - self.version = version def __enter__(self): if self.user: self.client.force_login(self.user, backend='django.contrib.auth.backends.ModelBackend') - self.client.credentials(HTTP_ACCEPT=settings.ACCEPT_HEADER_TEMPLATE.format(self.version)) return self @@ -74,13 +72,9 @@ def __exit__(self, exception_type, exception_value, traceback): if self.user: self.client.logout() -class VersionedAPIClient(APIClient): - def __init__(self, version=settings.BACKEND_VERSIONS.V1_0): - super().__init__(HTTP_ACCEPT=settings.ACCEPT_HEADER_TEMPLATE.format(version)) - class LambdaTestCase(APITestCase): def setUp(self): - self.client = VersionedAPIClient() + self.client = APIClient() patcher = mock.patch('cvat.apps.lambda_manager.views.LambdaGateway._http', side_effect = self.__get_response_data_from_lambda_gateway_http) self.addCleanup(patcher.stop) diff --git a/cvat/apps/restrictions/tests.py b/cvat/apps/restrictions/tests.py index 35336bf6ac91..c88490ce1ca5 100644 --- a/cvat/apps/restrictions/tests.py +++ b/cvat/apps/restrictions/tests.py @@ -7,13 +7,9 @@ from rest_framework import status from django.conf import settings -class VersionedAPIClient(APIClient): - def __init__(self, version=settings.BACKEND_VERSIONS.V1_0): - super().__init__(HTTP_ACCEPT=settings.ACCEPT_HEADER_TEMPLATE.format(version)) - class UserAgreementsTest(APITestCase): def setUp(self): - self.client = VersionedAPIClient() + self.client = APIClient() self.user_agreements = settings.RESTRICTIONS['user_agreements'] settings.RESTRICTIONS['user_agreements'] = [ { diff --git a/cvat/settings/base.py b/cvat/settings/base.py index 947acce5ce6b..4e804341378a 100644 --- a/cvat/settings/base.py +++ b/cvat/settings/base.py @@ -133,16 +133,6 @@ def add_ssh_keys(): SITE_ID = 1 -class BACKEND_VERSIONS(str, Enum): - V1_0 = '1.0' - - def __str__(self): - return self.value - - @classmethod - def list(cls): - return list(map(lambda x: x.value, cls)) - REST_FRAMEWORK = { 'DEFAULT_PARSER_CLASSES': [ 'rest_framework.parsers.JSONParser', @@ -166,12 +156,9 @@ def list(cls): 'rest_framework.authentication.BasicAuthentication' ], 'DEFAULT_VERSIONING_CLASS': - # Don't try to use URLPathVersioning. It will give you /api/{version} - # in path and '/api/docs' will not collapse similar items (flat list - # of all possible methods isn't readable). - 'cvat.apps.engine.versioning.CustomAcceptHeaderVersioning', - # Need to add 'api-docs' here as a workaround for include_docs_urls. - 'ALLOWED_VERSIONS': (*BACKEND_VERSIONS.list(), 'api-docs', 'downloading'), + 'rest_framework.versioning.AcceptHeaderVersioning', + 'ALLOWED_VERSIONS': ('1.0'), + 'DEFAULT_VERSION': '1.0', 'VERSION_PARAM': 'version', 'DEFAULT_PAGINATION_CLASS': 'cvat.apps.engine.pagination.CustomPagination', @@ -193,9 +180,6 @@ def list(cls): 'DEFAULT_METADATA_CLASS': 'rest_framework.metadata.SimpleMetadata', } -ACCEPT_HEADER_TEMPLATE_WITH_VERSION_PARAM = f'application/vnd.cvat+json; {REST_FRAMEWORK["VERSION_PARAM"]}=' -ACCEPT_HEADER_TEMPLATE = ''.join([ACCEPT_HEADER_TEMPLATE_WITH_VERSION_PARAM, '{}']) - REST_AUTH_REGISTER_SERIALIZERS = { 'REGISTER_SERIALIZER': 'cvat.apps.restrictions.serializers.RestrictedRegisterSerializer', } diff --git a/tests/cypress/integration/actions_users/issue_1810_login_logout.js b/tests/cypress/integration/actions_users/issue_1810_login_logout.js index 1bf33500fa8a..62bf7f9be4d8 100644 --- a/tests/cypress/integration/actions_users/issue_1810_login_logout.js +++ b/tests/cypress/integration/actions_users/issue_1810_login_logout.js @@ -4,7 +4,7 @@ /// -import { acceptHeader, taskName } from '../../support/const'; +import { taskName } from '../../support/const'; context('When clicking on the Logout button, get the user session closed.', () => { const issueId = '1810'; @@ -60,9 +60,6 @@ context('When clicking on the Logout button, get the user session closed.', () = cy.request({ method: 'POST', url: '/api/auth/login', - headers: { - Accept: acceptHeader, - }, body: { username: Cypress.env('user'), email: Cypress.env('email'), diff --git a/tests/cypress/integration/remove_users_tasks_projects_organizations.js b/tests/cypress/integration/remove_users_tasks_projects_organizations.js index 4e0bacf65c00..407e8a42e38a 100644 --- a/tests/cypress/integration/remove_users_tasks_projects_organizations.js +++ b/tests/cypress/integration/remove_users_tasks_projects_organizations.js @@ -4,8 +4,6 @@ /// -import { acceptHeader } from '../support/const'; - let authKey = ''; describe('Delete users, tasks, projects, organizations created during the tests run.', () => { @@ -13,9 +11,6 @@ describe('Delete users, tasks, projects, organizations created during the tests cy.request({ method: 'POST', url: '/api/auth/login', - headers: { - Accept: acceptHeader, - }, body: { username: Cypress.env('user'), email: Cypress.env('email'), @@ -31,7 +26,6 @@ describe('Delete users, tasks, projects, organizations created during the tests url: '/api/tasks?page_size=1000', headers: { Authorization: `Token ${authKey}`, - Accept: acceptHeader, }, }).then((response) => { const responseResult = response.body.results; @@ -42,7 +36,6 @@ describe('Delete users, tasks, projects, organizations created during the tests url: `/api/tasks/${id}`, headers: { Authorization: `Token ${authKey}`, - Accept: acceptHeader, }, }); } @@ -54,7 +47,6 @@ describe('Delete users, tasks, projects, organizations created during the tests url: '/api/projects?page_size=all', headers: { Authorization: `Token ${authKey}`, - Accept: acceptHeader, }, }).then((response) => { const responseResult = response.body.results; @@ -65,7 +57,6 @@ describe('Delete users, tasks, projects, organizations created during the tests url: `/api/projects/${id}`, headers: { Authorization: `Token ${authKey}`, - Accept: acceptHeader, }, }); } @@ -77,7 +68,6 @@ describe('Delete users, tasks, projects, organizations created during the tests url: '/api/organizations?page_size=all', headers: { Authorization: `Token ${authKey}`, - Accept: acceptHeader, }, }).then((response) => { const responseResult = response.body; @@ -88,7 +78,6 @@ describe('Delete users, tasks, projects, organizations created during the tests url: `/api/organizations/${id}`, headers: { Authorization: `Token ${authKey}`, - Accept: acceptHeader, }, }); } @@ -100,7 +89,6 @@ describe('Delete users, tasks, projects, organizations created during the tests url: '/api/users', headers: { Authorization: `Token ${authKey}`, - Accept: acceptHeader, }, }).then((response) => { const responseResult = response.body.results; @@ -112,7 +100,6 @@ describe('Delete users, tasks, projects, organizations created during the tests url: `/api/users/${id}`, headers: { Authorization: `Token ${authKey}`, - Accept: acceptHeader, }, }); } diff --git a/tests/cypress/support/commands.js b/tests/cypress/support/commands.js index 50907ce2296e..02d01d58ee5d 100644 --- a/tests/cypress/support/commands.js +++ b/tests/cypress/support/commands.js @@ -5,7 +5,6 @@ /// import { decomposeMatrix } from './utils'; -import { acceptHeader } from './const'; require('cypress-file-upload'); require('../plugins/imageGenerator/imageGeneratorCommand'); @@ -57,9 +56,6 @@ Cypress.Commands.add('getAuthKey', () => { cy.request({ method: 'POST', url: '/api/auth/login', - headers: { - Accept: acceptHeader, - }, body: { username: Cypress.env('user'), email: Cypress.env('email'), @@ -74,7 +70,6 @@ Cypress.Commands.add('deleteUsers', (authResponse, accountsToDelete) => { url: '/api/users?page_size=all', headers: { Authorization: `Token ${authKey}`, - Accept: acceptHeader, }, }).then((_response) => { const responseResult = _response.body.results; @@ -87,7 +82,6 @@ Cypress.Commands.add('deleteUsers', (authResponse, accountsToDelete) => { url: `/api/users/${id}`, headers: { Authorization: `Token ${authKey}`, - Accept: acceptHeader, }, }); } @@ -101,7 +95,6 @@ Cypress.Commands.add('changeUserActiveStatus', (authKey, accountsToChangeActiveS url: '/api/users?page_size=all', headers: { Authorization: `Token ${authKey}`, - Accept: acceptHeader, }, }).then((response) => { const responceResult = response.body.results; @@ -114,7 +107,6 @@ Cypress.Commands.add('changeUserActiveStatus', (authKey, accountsToChangeActiveS url: `/api/users/${userId}`, headers: { Authorization: `Token ${authKey}`, - Accept: acceptHeader, }, body: { is_active: isActive, @@ -130,7 +122,6 @@ Cypress.Commands.add('checkUserStatuses', (authKey, userName, staffStatus, super url: '/api/users?page_size=all', headers: { Authorization: `Token ${authKey}`, - Accept: acceptHeader, }, }).then((response) => { const responceResult = response.body.results; @@ -150,7 +141,6 @@ Cypress.Commands.add('deleteTasks', (authResponse, tasksToDelete) => { url: '/api/tasks?page_size=all', headers: { Authorization: `Token ${authKey}`, - Accept: acceptHeader, }, }).then((_response) => { const responceResult = _response.body.results; @@ -163,7 +153,6 @@ Cypress.Commands.add('deleteTasks', (authResponse, tasksToDelete) => { url: `/api/tasks/${id}`, headers: { Authorization: `Token ${authKey}`, - Accept: acceptHeader, }, }); } diff --git a/tests/cypress/support/commands_organizations.js b/tests/cypress/support/commands_organizations.js index a95f76964248..7dcf6034a8b4 100644 --- a/tests/cypress/support/commands_organizations.js +++ b/tests/cypress/support/commands_organizations.js @@ -4,8 +4,6 @@ /// -import { acceptHeader } from './const'; - Cypress.Commands.add('createOrganization', (organizationParams) => { cy.get('.cvat-header-menu-user-dropdown').trigger('mouseover'); cy.get('.cvat-header-menu') @@ -36,7 +34,6 @@ Cypress.Commands.add('deleteOrganizations', (authResponse, otrganizationsToDelet url: '/api/organizations?page_size=all', headers: { Authorization: `Token ${authKey}`, - Accept: acceptHeader, }, }).then((_response) => { const responceResult = _response.body; @@ -49,7 +46,6 @@ Cypress.Commands.add('deleteOrganizations', (authResponse, otrganizationsToDelet url: `/api/organizations/${id}`, headers: { Authorization: `Token ${authKey}`, - Accept: acceptHeader, }, }); } diff --git a/tests/cypress/support/commands_projects.js b/tests/cypress/support/commands_projects.js index 2837baaa76a9..c89bb20b2e70 100644 --- a/tests/cypress/support/commands_projects.js +++ b/tests/cypress/support/commands_projects.js @@ -4,8 +4,6 @@ /// -import { acceptHeader } from './const'; - Cypress.Commands.add('goToProjectsList', () => { cy.get('[value="projects"]').click(); cy.url().should('include', '/projects'); @@ -46,7 +44,6 @@ Cypress.Commands.add('deleteProjects', (authResponse, projectsToDelete) => { url: '/api/projects?page_size=all', headers: { Authorization: `Token ${authKey}`, - Accept: acceptHeader, }, }).then((_response) => { const responceResult = _response.body.results; @@ -59,7 +56,6 @@ Cypress.Commands.add('deleteProjects', (authResponse, projectsToDelete) => { url: `/api/projects/${id}`, headers: { Authorization: `Token ${authKey}`, - Accept: acceptHeader, }, }); } diff --git a/tests/cypress/support/const.js b/tests/cypress/support/const.js index de63c665b472..7661f954bd98 100644 --- a/tests/cypress/support/const.js +++ b/tests/cypress/support/const.js @@ -32,7 +32,6 @@ export const multiAttrParams = { additionalValue: 'Attr value 2', typeAttribute: 'Text', }; -export const acceptHeader = 'application/vnd.cvat+json; version=1.0'; it('Prepare to testing', () => { cy.visit('/'); diff --git a/tests/rest_api/test_0000_check_objects_integrity.py b/tests/rest_api/test_0000_check_objects_integrity.py index 13b7fd92316b..6e602e5f6096 100644 --- a/tests/rest_api/test_0000_check_objects_integrity.py +++ b/tests/rest_api/test_0000_check_objects_integrity.py @@ -12,7 +12,6 @@ def test_check_objects_integrity(): with requests.Session() as session: session.auth = ('admin1', config.USER_PASS) - session.headers.update({'Accept': config.ACCEPT_HEADER}) for filename in glob.glob(os.path.join(config.ASSETS_DIR, '*.json')): with open(filename) as f: diff --git a/tests/rest_api/test_0001_users_api.py b/tests/rest_api/test_0001_users_api.py index df93cbb4459a..9f6eea7243dc 100644 --- a/tests/rest_api/test_0001_users_api.py +++ b/tests/rest_api/test_0001_users_api.py @@ -12,14 +12,12 @@ def test_non_admin_cannot_see_others(): for username in ['dummy1', 'worker1', 'user1', 'business1']: - response = requests.get(config.get_api_url('users'), auth=(username, config.USER_PASS), - headers={'Accept': config.ACCEPT_HEADER}) + response = requests.get(config.get_api_url('users'), auth=(username, config.USER_PASS)) assert response.status_code == HTTPStatus.OK assert response.json()['count'] == 1 def test_admin_can_see_all_others(): - response = requests.get(config.get_api_url('users'), auth=('admin2', config.USER_PASS), - headers={'Accept': config.ACCEPT_HEADER}) + response = requests.get(config.get_api_url('users'), auth=('admin2', config.USER_PASS)) assert response.status_code == HTTPStatus.OK with open(os.path.join(config.ASSETS_DIR, 'users.json')) as f: data = json.load(f) @@ -31,8 +29,7 @@ def test_everybody_can_see_self(): users = {user['username']:user for user in data} for username in ['dummy1', 'worker1', 'user1', 'business1', 'admin1']: - response = requests.get(config.get_api_url('users/self'), auth=(username, config.USER_PASS), - headers={'Accept': config.ACCEPT_HEADER}) + response = requests.get(config.get_api_url('users/self'), auth=(username, config.USER_PASS)) assert response.status_code == HTTPStatus.OK assert DeepDiff(users[username], response.json(), ignore_order=True, exclude_paths="root['last_login']") == {} diff --git a/tests/rest_api/test_0002_organizations.py b/tests/rest_api/test_0002_organizations.py index 11963965cf51..18d6b5a0a277 100644 --- a/tests/rest_api/test_0002_organizations.py +++ b/tests/rest_api/test_0002_organizations.py @@ -16,12 +16,10 @@ def compare_organizations(org_id, response): DeepDiff(org, response.json()) def test_admin1_get_organization_id_1(): - response = requests.get(config.get_api_url('organizations/1'), auth=('admin1', config.USER_PASS), - headers={'Accept': config.ACCEPT_HEADER}) + response = requests.get(config.get_api_url('organizations/1'), auth=('admin1', config.USER_PASS)) compare_organizations(1, response) def test_user1_get_organization_id_1(): - response = requests.get(config.get_api_url('organizations/1'), auth=('user1', config.USER_PASS), - headers={'Accept': config.ACCEPT_HEADER}) + response = requests.get(config.get_api_url('organizations/1'), auth=('user1', config.USER_PASS)) compare_organizations(1, response) diff --git a/tests/rest_api/utils/config.py b/tests/rest_api/utils/config.py index c650fd2a6568..045effd54548 100644 --- a/tests/rest_api/utils/config.py +++ b/tests/rest_api/utils/config.py @@ -9,7 +9,6 @@ # Suppress the warning from Bandit about hardcoded passwords USER_PASS = '!Q@W#E$R' # nosec BASE_URL = 'http://localhost:8080/api/' -ACCEPT_HEADER = 'application/vnd.cvat+json; version=1.0' def get_api_url(endpoint, **kwargs): return BASE_URL + endpoint + '?' + '&'.join([f'{k}={v}' for k,v in kwargs.items()]) \ No newline at end of file diff --git a/utils/cli/cli.py b/utils/cli/cli.py index 32a961a6bbbe..52f60ee1e4bc 100755 --- a/utils/cli/cli.py +++ b/utils/cli/cli.py @@ -34,8 +34,6 @@ def main(): with requests.Session() as session: api = CVAT_API_V1('%s:%s' % (args.server_host, args.server_port), args.https) cli = CLI(session, api, args.auth) - #TODO add version indication - session.headers.update({'Accept': 'application/vnd.cvat+json; version=1.0'}) try: actions[args.action](cli, **args.__dict__) except (requests.exceptions.HTTPError, diff --git a/utils/cli/tests/test_cli.py b/utils/cli/tests/test_cli.py index c80802975b6e..1f1ca3309710 100644 --- a/utils/cli/tests/test_cli.py +++ b/utils/cli/tests/test_cli.py @@ -23,7 +23,6 @@ def setUp(self, mock_stdout): self.client = RequestsClient() self.credentials = ('admin', 'admin') self.api = CVAT_API_V1('testserver') - self.client.headers.update({'Accept': settings.ACCEPT_HEADER_TEMPLATE.format(settings.BACKEND_VERSIONS.V1_0)}) self.cli = CLI(self.client, self.api, self.credentials) self.taskname = 'test_task' self.cli.tasks_create(self.taskname, From abe510aa3ee4f58843095e7d0a8b7dc7270a29ab Mon Sep 17 00:00:00 2001 From: Maya Date: Wed, 2 Feb 2022 12:02:16 +0300 Subject: [PATCH 15/20] Update rest api design --- site/content/en/docs/contributing/rest-api-design.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/site/content/en/docs/contributing/rest-api-design.md b/site/content/en/docs/contributing/rest-api-design.md index 48959101f371..4b3c377647c6 100644 --- a/site/content/en/docs/contributing/rest-api-design.md +++ b/site/content/en/docs/contributing/rest-api-design.md @@ -36,8 +36,8 @@ Common scheme for our REST API is ` [namespace] `. - Allow filtering, sorting, and pagination - Maintain good security practices - Cache data to improve performance -- Versioning our APIs (e.g. `/api`, `/api/v2`). It should be done when you - delete an endpoint or modify its behaviors. +- Versioning our APIs. It should be done when you delete an endpoint or modify + its behaviors. Versioning uses a schema with `Accept` header with vendor media type. ## Links From 6c3d5371ee6dc78076b6f14f2bf84979c67e3626 Mon Sep 17 00:00:00 2001 From: Maya Date: Wed, 2 Feb 2022 12:03:50 +0300 Subject: [PATCH 16/20] Remove extra --- cvat/apps/engine/versioning.py | 26 -------------------------- 1 file changed, 26 deletions(-) delete mode 100644 cvat/apps/engine/versioning.py diff --git a/cvat/apps/engine/versioning.py b/cvat/apps/engine/versioning.py deleted file mode 100644 index 972f49e93a45..000000000000 --- a/cvat/apps/engine/versioning.py +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright (C) 2022 Intel Corporation -# -# SPDX-License-Identifier: MIT - -from rest_framework.versioning import AcceptHeaderVersioning -from rest_framework.exceptions import NotAcceptable - -class CustomAcceptHeaderVersioning(AcceptHeaderVersioning): - """ - GET /api/something/ HTTP/1.1 - Host: localhost:8080 - Accept: application/vnd.cvat+json; version=1.0 - """ - - def determine_version(self, request, *args, **kwargs): - # it's needed for browsable api - if request.accepted_media_type in {'text/html', 'application/json'}: - return 'api-docs' - try: - version = super().determine_version(request, *args, **kwargs) - except NotAcceptable: - # resource download requests such as backup/annotation files - if request.query_params.get('action') == 'download': - version = 'downloading' - else: raise - return version From 904b21f9a6c10b4f25409f0b4ef2e1f424597ee8 Mon Sep 17 00:00:00 2001 From: Maya Date: Wed, 2 Feb 2022 13:16:21 +0300 Subject: [PATCH 17/20] Remove unused imports && fix headers --- cvat-core/src/download.worker.js | 2 +- cvat/apps/dataset_manager/tests/test_formats.py | 1 - cvat/apps/dataset_manager/tests/test_rest_api_formats.py | 1 - cvat/apps/dataset_repo/tests.py | 1 - cvat/apps/engine/tests/test_rest_api_3D.py | 1 - cvat/apps/iam/tests/test_rest_api.py | 1 - cvat/apps/lambda_manager/tests/test_lambda.py | 3 +-- cvat/settings/base.py | 1 - 8 files changed, 2 insertions(+), 9 deletions(-) diff --git a/cvat-core/src/download.worker.js b/cvat-core/src/download.worker.js index 687f0fc0f2b9..40542e0b848f 100644 --- a/cvat-core/src/download.worker.js +++ b/cvat-core/src/download.worker.js @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2022 Intel Corporation +// Copyright (C) 2022 Intel Corporation // // SPDX-License-Identifier: MIT diff --git a/cvat/apps/dataset_manager/tests/test_formats.py b/cvat/apps/dataset_manager/tests/test_formats.py index 1bfa358d8c4c..a95d93cf9372 100644 --- a/cvat/apps/dataset_manager/tests/test_formats.py +++ b/cvat/apps/dataset_manager/tests/test_formats.py @@ -12,7 +12,6 @@ import datumaro from datumaro.components.dataset import Dataset, DatasetItem from datumaro.components.annotation import Mask -from django.conf import settings from django.contrib.auth.models import Group, User from PIL import Image diff --git a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py index 43a77db01616..07330c0237e7 100644 --- a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py +++ b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py @@ -16,7 +16,6 @@ from datumaro.components.dataset import Dataset from datumaro.util.test_utils import compare_datasets, TestDir -from django.conf import settings from django.contrib.auth.models import Group, User from PIL import Image from rest_framework import status diff --git a/cvat/apps/dataset_repo/tests.py b/cvat/apps/dataset_repo/tests.py index b8193458c2bb..79c20ecda5a1 100644 --- a/cvat/apps/dataset_repo/tests.py +++ b/cvat/apps/dataset_repo/tests.py @@ -15,7 +15,6 @@ from rest_framework.test import APIClient, APITestCase from rest_framework import status from django.utils import timezone -from django.conf import settings from django.contrib.auth.models import Group, User from cvat.apps.engine.models import Task from cvat.apps.dataset_repo.dataset_repo import (Git, initial_create, push, get) diff --git a/cvat/apps/engine/tests/test_rest_api_3D.py b/cvat/apps/engine/tests/test_rest_api_3D.py index 26952293abda..1f9cabba6f43 100644 --- a/cvat/apps/engine/tests/test_rest_api_3D.py +++ b/cvat/apps/engine/tests/test_rest_api_3D.py @@ -16,7 +16,6 @@ from shutil import copyfile import itertools -from django.conf import settings from django.contrib.auth.models import Group, User from rest_framework import status from rest_framework.test import APIClient, APITestCase diff --git a/cvat/apps/iam/tests/test_rest_api.py b/cvat/apps/iam/tests/test_rest_api.py index 18d02e23d632..8716c36eca25 100644 --- a/cvat/apps/iam/tests/test_rest_api.py +++ b/cvat/apps/iam/tests/test_rest_api.py @@ -2,7 +2,6 @@ # # SPDX-License-Identifier: MIT -from django.conf import settings from django.urls import reverse from rest_framework import status from rest_framework.test import APITestCase, APIClient diff --git a/cvat/apps/lambda_manager/tests/test_lambda.py b/cvat/apps/lambda_manager/tests/test_lambda.py index d5ef94ca27a2..98b29627be71 100644 --- a/cvat/apps/lambda_manager/tests/test_lambda.py +++ b/cvat/apps/lambda_manager/tests/test_lambda.py @@ -1,5 +1,5 @@ -# Copyright (C) 2021 Intel Corporation +# Copyright (C) 2021-2022 Intel Corporation # # SPDX-License-Identifier: MIT @@ -10,7 +10,6 @@ import os import requests -from django.conf import settings from django.contrib.auth.models import Group, User from django.http import HttpResponseNotFound, HttpResponseServerError from PIL import Image diff --git a/cvat/settings/base.py b/cvat/settings/base.py index 4e804341378a..690b7b73cc19 100644 --- a/cvat/settings/base.py +++ b/cvat/settings/base.py @@ -21,7 +21,6 @@ import subprocess import mimetypes from corsheaders.defaults import default_headers -from enum import Enum from distutils.util import strtobool mimetypes.add_type("application/wasm", ".wasm", True) From 9ccff04ca58e9c34777021f7542f8007aba2b772 Mon Sep 17 00:00:00 2001 From: Maya Date: Wed, 2 Feb 2022 14:29:25 +0300 Subject: [PATCH 18/20] Update assets --- tests/rest_api/assets/invitations.json | 8 ++++---- tests/rest_api/assets/memberships.json | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/rest_api/assets/invitations.json b/tests/rest_api/assets/invitations.json index 777b438b4f46..e9c3a007493f 100644 --- a/tests/rest_api/assets/invitations.json +++ b/tests/rest_api/assets/invitations.json @@ -11,7 +11,7 @@ "first_name": "Business", "id": 10, "last_name": "First", - "url": "http://localhost:8080/api/v1/users/10", + "url": "http://localhost:8080/api/users/10", "username": "business1" }, "role": "maintainer", @@ -19,7 +19,7 @@ "first_name": "User", "id": 5, "last_name": "Fourth", - "url": "http://localhost:8080/api/v1/users/5", + "url": "http://localhost:8080/api/users/5", "username": "user4" } }, @@ -31,7 +31,7 @@ "first_name": "Business", "id": 10, "last_name": "First", - "url": "http://localhost:8080/api/v1/users/10", + "url": "http://localhost:8080/api/users/10", "username": "business1" }, "role": "supervisor", @@ -39,7 +39,7 @@ "first_name": "User", "id": 4, "last_name": "Third", - "url": "http://localhost:8080/api/v1/users/4", + "url": "http://localhost:8080/api/users/4", "username": "user3" } }, diff --git a/tests/rest_api/assets/memberships.json b/tests/rest_api/assets/memberships.json index ce27a9232cab..e07940dd3166 100644 --- a/tests/rest_api/assets/memberships.json +++ b/tests/rest_api/assets/memberships.json @@ -14,7 +14,7 @@ "first_name": "User", "id": 5, "last_name": "Fourth", - "url": "http://localhost:8080/api/v1/users/5", + "url": "http://localhost:8080/api/users/5", "username": "user4" } }, @@ -29,7 +29,7 @@ "first_name": "User", "id": 4, "last_name": "Third", - "url": "http://localhost:8080/api/v1/users/4", + "url": "http://localhost:8080/api/users/4", "username": "user3" } }, From 3c8c61e9dde8a5d9c411e3a73a3e0431b02a0bf4 Mon Sep 17 00:00:00 2001 From: Maya Date: Thu, 3 Feb 2022 10:13:24 +0300 Subject: [PATCH 19/20] Add test && API version 2.0 --- cvat/apps/engine/tests/test_rest_api.py | 16 ++++++++++++++++ cvat/settings/base.py | 4 ++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/cvat/apps/engine/tests/test_rest_api.py b/cvat/apps/engine/tests/test_rest_api.py index 12bc7e1e66a3..daf4a151d641 100644 --- a/cvat/apps/engine/tests/test_rest_api.py +++ b/cvat/apps/engine/tests/test_rest_api.py @@ -400,6 +400,8 @@ def test_api_v1_jobs_id_admin_partial(self): self._check_request(response, data) class ServerAboutAPITestCase(APITestCase): + ACCEPT_HEADER_TEMPLATE = 'application/vnd.cvat+json; version={}' + def setUp(self): self.client = APIClient() @@ -413,6 +415,15 @@ def _run_api_v1_server_about(self, user): return response + def _run_api_server_about(self, user, version): + with ForceLogin(user, self.client): + response = self.client.get('/api/server/about', + HTTP_ACCEPT=self.ACCEPT_HEADER_TEMPLATE.format(version)) + return response + + def _check_response_version(self, response, version): + self.assertEqual(response.accepted_media_type, self.ACCEPT_HEADER_TEMPLATE.format(version)) + def _check_request(self, response): self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertIsNotNone(response.data.get("name", None)) @@ -431,6 +442,11 @@ def test_api_v1_server_about_no_auth(self): response = self._run_api_v1_server_about(None) self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) + def test_api_server_about_versions_admin(self): + for version in settings.REST_FRAMEWORK['ALLOWED_VERSIONS']: + response = self._run_api_server_about(self.admin, version) + self._check_response_version(response, version) + class ServerExceptionAPITestCase(APITestCase): def setUp(self): self.client = APIClient() diff --git a/cvat/settings/base.py b/cvat/settings/base.py index 690b7b73cc19..c8e7500c527a 100644 --- a/cvat/settings/base.py +++ b/cvat/settings/base.py @@ -156,8 +156,8 @@ def add_ssh_keys(): ], 'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.AcceptHeaderVersioning', - 'ALLOWED_VERSIONS': ('1.0'), - 'DEFAULT_VERSION': '1.0', + 'ALLOWED_VERSIONS': ('1.0', '2.0'), + 'DEFAULT_VERSION': '2.0', 'VERSION_PARAM': 'version', 'DEFAULT_PAGINATION_CLASS': 'cvat.apps.engine.pagination.CustomPagination', From fa884187d640719d41fd9eee909ee85e185fc46e Mon Sep 17 00:00:00 2001 From: Maya Date: Thu, 3 Feb 2022 10:44:37 +0300 Subject: [PATCH 20/20] Update tests & cli --- .../dataset_manager/tests/test_formats.py | 12 +- .../tests/test_rest_api_formats.py | 48 +- cvat/apps/dataset_repo/tests.py | 6 +- cvat/apps/engine/tests/test_rest_api.py | 974 +++++++++--------- cvat/apps/engine/tests/test_rest_api_3D.py | 68 +- cvat/apps/iam/tests/test_rest_api.py | 14 +- cvat/apps/lambda_manager/tests/test_lambda.py | 92 +- utils/cli/cli.py | 4 +- utils/cli/core/__init__.py | 2 +- utils/cli/core/core.py | 4 +- utils/cli/tests/test_cli.py | 6 +- 11 files changed, 615 insertions(+), 615 deletions(-) diff --git a/cvat/apps/dataset_manager/tests/test_formats.py b/cvat/apps/dataset_manager/tests/test_formats.py index a95d93cf9372..4a771dcb2031 100644 --- a/cvat/apps/dataset_manager/tests/test_formats.py +++ b/cvat/apps/dataset_manager/tests/test_formats.py @@ -1,5 +1,5 @@ -# Copyright (C) 2020 Intel Corporation +# Copyright (C) 2020-2022 Intel Corporation # # SPDX-License-Identifier: MIT @@ -69,14 +69,14 @@ def create_db_users(cls): cls.user = admin - def _put_api_v1_task_id_annotations(self, tid, data): + def _put_api_v2_task_id_annotations(self, tid, data): with ForceLogin(self.user, self.client): response = self.client.put("/api/tasks/%s/annotations" % tid, data=data, format="json") return response - def _put_api_v1_job_id_annotations(self, jid, data): + def _put_api_v2_job_id_annotations(self, jid, data): with ForceLogin(self.user, self.client): response = self.client.put("/api/jobs/%s/annotations" % jid, data=data, format="json") @@ -100,7 +100,7 @@ def _create_task(self, data, image_data): class TaskExportTest(_DbTestBase): def _generate_custom_annotations(self, annotations, task): - self._put_api_v1_task_id_annotations(task["id"], annotations) + self._put_api_v2_task_id_annotations(task["id"], annotations) return annotations def _generate_annotations(self, task): @@ -497,7 +497,7 @@ def test_frames_outside_are_not_generated(self): }, ] } - self._put_api_v1_job_id_annotations( + self._put_api_v2_job_id_annotations( task["segments"][2]["jobs"][0]["id"], annotations) task_ann = TaskAnnotation(task["id"]) @@ -602,7 +602,7 @@ def test_dataset_root(self): class TaskAnnotationsImportTest(_DbTestBase): def _generate_custom_annotations(self, annotations, task): - self._put_api_v1_task_id_annotations(task["id"], annotations) + self._put_api_v2_task_id_annotations(task["id"], annotations) return annotations def _generate_task_images(self, count, name="image", **image_params): diff --git a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py index 07330c0237e7..47a1556a08fa 100644 --- a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py +++ b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py @@ -1,4 +1,4 @@ -# Copyright (C) 2021 Intel Corporation +# Copyright (C) 2021-2022 Intel Corporation # # SPDX-License-Identifier: MIT @@ -122,14 +122,14 @@ def create_db_users(cls): cls.admin = user_admin cls.user = user_dummy - def _put_api_v1_task_id_annotations(self, tid, data): + def _put_api_v2_task_id_annotations(self, tid, data): with ForceLogin(self.admin, self.client): response = self.client.put("/api/tasks/%s/annotations" % tid, data=data, format="json") return response - def _put_api_v1_job_id_annotations(self, jid, data): + def _put_api_v2_job_id_annotations(self, jid, data): with ForceLogin(self.admin, self.client): response = self.client.put("/api/jobs/%s/annotations" % jid, data=data, format="json") @@ -237,7 +237,7 @@ def _create_annotations(self, task, name_ann, key_get_values): "spec_id": spec_id, "value": value, }) - response = self._put_api_v1_task_id_annotations(task["id"], tmp_annotations) + response = self._put_api_v2_task_id_annotations(task["id"], tmp_annotations) self.assertEqual(response.status_code, status.HTTP_200_OK) def _create_annotations_in_job(self, task, job_id, name_ann, key_get_values): @@ -274,7 +274,7 @@ def _create_annotations_in_job(self, task, job_id, name_ann, key_get_values): "spec_id": spec_id, "value": value, }) - response = self._put_api_v1_job_id_annotations(job_id, tmp_annotations) + response = self._put_api_v2_job_id_annotations(job_id, tmp_annotations) self.assertEqual(response.status_code, status.HTTP_200_OK) def _download_file(self, url, data, user, file_name): @@ -330,7 +330,7 @@ def _delete_project(self, project_id, user): class TaskDumpUploadTest(_DbTestBase): - def test_api_v1_dump_and_upload_annotations_with_objects_type_is_shape(self): + def test_api_v2_dump_and_upload_annotations_with_objects_type_is_shape(self): test_name = self._testMethodName dump_formats = dm.views.get_export_formats() upload_formats = dm.views.get_import_formats() @@ -435,7 +435,7 @@ def test_api_v1_dump_and_upload_annotations_with_objects_type_is_shape(self): response = self._put_request_with_data(url, {}, user) self.assertEqual(response.status_code, edata['create code']) - def test_api_v1_dump_annotations_with_objects_type_is_track(self): + def test_api_v2_dump_annotations_with_objects_type_is_track(self): test_name = self._testMethodName dump_formats = dm.views.get_export_formats() @@ -539,7 +539,7 @@ def test_api_v1_dump_annotations_with_objects_type_is_track(self): response = self._put_request_with_data(url, {}, user) self.assertEqual(response.status_code, edata['create code']) - def test_api_v1_dump_tag_annotations(self): + def test_api_v2_dump_tag_annotations(self): dump_format_name = "CVAT for images 1.1" data = { "format": dump_format_name, @@ -592,7 +592,7 @@ def test_api_v1_dump_tag_annotations(self): f.write(content.getvalue()) self.assertEqual(osp.exists(file_zip_name), edata['file_exists']) - def test_api_v1_dump_and_upload_annotations_with_objects_are_different_images(self): + def test_api_v2_dump_and_upload_annotations_with_objects_are_different_images(self): test_name = self._testMethodName dump_format_name = "CVAT for images 1.1" upload_types = ["task", "job"] @@ -632,7 +632,7 @@ def test_api_v1_dump_and_upload_annotations_with_objects_are_different_images(se self.assertEqual(len(response.data["shapes"]), 2) self.assertEqual(len(response.data["tracks"]), 0) - def test_api_v1_dump_and_upload_annotations_with_objects_are_different_video(self): + def test_api_v2_dump_and_upload_annotations_with_objects_are_different_video(self): test_name = self._testMethodName dump_format_name = "CVAT for video 1.1" upload_types = ["task", "job"] @@ -674,7 +674,7 @@ def test_api_v1_dump_and_upload_annotations_with_objects_are_different_video(sel self.assertEqual(len(response.data["shapes"]), 0) self.assertEqual(len(response.data["tracks"]), 2) - def test_api_v1_dump_and_upload_with_objects_type_is_track_and_outside_property(self): + def test_api_v2_dump_and_upload_with_objects_type_is_track_and_outside_property(self): test_name = self._testMethodName dump_format_name = "CVAT for video 1.1" video = self._generate_task_videos(1) @@ -696,7 +696,7 @@ def test_api_v1_dump_and_upload_with_objects_type_is_track_and_outside_property( url = self._generate_url_upload_tasks_annotations(task_id, "CVAT 1.1") self._upload_file(url, binary_file, self.admin) - def test_api_v1_dump_and_upload_with_objects_type_is_track_and_keyframe_property(self): + def test_api_v2_dump_and_upload_with_objects_type_is_track_and_keyframe_property(self): test_name = self._testMethodName dump_format_name = "CVAT for video 1.1" @@ -720,7 +720,7 @@ def test_api_v1_dump_and_upload_with_objects_type_is_track_and_keyframe_property url = self._generate_url_upload_tasks_annotations(task_id, "CVAT 1.1") self._upload_file(url, binary_file, self.admin) - def test_api_v1_dump_upload_annotations_from_several_jobs(self): + def test_api_v2_dump_upload_annotations_from_several_jobs(self): test_name = self._testMethodName dump_format_name = "CVAT for images 1.1" @@ -747,7 +747,7 @@ def test_api_v1_dump_upload_annotations_from_several_jobs(self): with open(file_zip_name, 'rb') as binary_file: self._upload_file(url, binary_file, self.admin) - def test_api_v1_dump_annotations_with_objects_type_is_shape_from_several_jobs(self): + def test_api_v2_dump_annotations_with_objects_type_is_shape_from_several_jobs(self): test_name = self._testMethodName dump_format_name = "CVAT for images 1.1" test_cases = ['all', 'first'] @@ -781,7 +781,7 @@ def test_api_v1_dump_annotations_with_objects_type_is_shape_from_several_jobs(se with open(file_zip_name, 'rb') as binary_file: self._upload_file(url, binary_file, self.admin) - def test_api_v1_export_dataset(self): + def test_api_v2_export_dataset(self): test_name = self._testMethodName dump_formats = dm.views.get_export_formats() @@ -837,7 +837,7 @@ def test_api_v1_export_dataset(self): self.assertEqual(response.status_code, edata['code']) self.assertEqual(osp.exists(file_zip_name), edata['file_exists']) - def test_api_v1_dump_empty_frames(self): + def test_api_v2_dump_empty_frames(self): dump_formats = dm.views.get_export_formats() upload_formats = dm.views.get_import_formats() @@ -889,7 +889,7 @@ def test_api_v1_dump_empty_frames(self): self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertIsNone(response.data) - def test_api_v1_rewriting_annotations(self): + def test_api_v2_rewriting_annotations(self): test_name = self._testMethodName dump_formats = dm.views.get_export_formats() with TestDir() as test_dir: @@ -955,7 +955,7 @@ def test_api_v1_rewriting_annotations(self): task_ann_data = task_ann.data self.assertEqual(len(task_ann_data["shapes"]), len(task_ann_prev_data["shapes"])) - def test_api_v1_tasks_annotations_dump_and_upload_many_jobs_with_datumaro(self): + def test_api_v2_tasks_annotations_dump_and_upload_many_jobs_with_datumaro(self): test_name = self._testMethodName upload_format_name = "CVAT 1.1" include_images_params = (False, True) @@ -995,7 +995,7 @@ def test_api_v1_tasks_annotations_dump_and_upload_many_jobs_with_datumaro(self): data_from_task_after_upload = self._get_data_from_task(task_id, include_images) compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) - def test_api_v1_tasks_annotations_dump_and_upload_with_datumaro(self): + def test_api_v2_tasks_annotations_dump_and_upload_with_datumaro(self): test_name = self._testMethodName # get formats dump_formats = dm.views.get_export_formats() @@ -1072,7 +1072,7 @@ def test_api_v1_tasks_annotations_dump_and_upload_with_datumaro(self): data_from_task_after_upload = self._get_data_from_task(task_id, include_images) compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) - def test_api_v1_check_duplicated_polygon_points(self): + def test_api_v2_check_duplicated_polygon_points(self): test_name = self._testMethodName images = self._generate_task_images(10) task = self._create_task(tasks["main"], images) @@ -1102,7 +1102,7 @@ def test_api_v1_check_duplicated_polygon_points(self): polygon_points = [float(p) for p in polygon_points.split(";")] self.assertEqual(polygon_points, annotation_points) - def test_api_v1_check_widerface_with_all_attributes(self): + def test_api_v2_check_widerface_with_all_attributes(self): test_name = self._testMethodName dump_format_name = "WiderFace 1.0" upload_format_name = "WiderFace 1.0" @@ -1140,7 +1140,7 @@ def test_api_v1_check_widerface_with_all_attributes(self): data_from_task_after_upload = self._get_data_from_task(task_id, include_images) compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload)\ - def test_api_v1_check_attribute_import_in_tracks(self): + def test_api_v2_check_attribute_import_in_tracks(self): test_name = self._testMethodName dump_format_name = "CVAT for video 1.1" upload_format_name = "CVAT 1.1" @@ -1179,7 +1179,7 @@ def test_api_v1_check_attribute_import_in_tracks(self): compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) class ProjectDump(_DbTestBase): - def test_api_v1_export_dataset(self): + def test_api_v2_export_dataset(self): test_name = self._testMethodName dump_formats = dm.views.get_export_formats() @@ -1231,7 +1231,7 @@ def test_api_v1_export_dataset(self): self.assertEqual(response.status_code, edata['code']) self.assertEqual(osp.exists(file_zip_name), edata['file_exists']) - def test_api_v1_export_annotatios(self): + def test_api_v2_export_annotatios(self): test_name = self._testMethodName dump_formats = dm.views.get_export_formats() diff --git a/cvat/apps/dataset_repo/tests.py b/cvat/apps/dataset_repo/tests.py index 79c20ecda5a1..71611f0f4f6c 100644 --- a/cvat/apps/dataset_repo/tests.py +++ b/cvat/apps/dataset_repo/tests.py @@ -1,4 +1,4 @@ -# Copyright (C) 2018 Intel Corporation +# Copyright (C) 2018-2022 Intel Corporation # # SPDX-License-Identifier: MIT @@ -189,7 +189,7 @@ def setUpTestData(cls): ] } - def _run_api_v1_job_id_annotation(self, jid, data, user): + def _run_api_v2_job_id_annotation(self, jid, data, user): with ForceLogin(user, self.client): response = self.client.patch('/api/jobs/{}/annotations?action=create'.format(jid), data=data, format="json") @@ -507,6 +507,6 @@ def test_request_on_save(self): ], "tracks": [] } - self._run_api_v1_job_id_annotation(jobs[0]["id"], ann, self.user) + self._run_api_v2_job_id_annotation(jobs[0]["id"], ann, self.user) db_git = GitData() self.assertEqual(db_git.status, GitStatusChoice.NON_SYNCED) diff --git a/cvat/apps/engine/tests/test_rest_api.py b/cvat/apps/engine/tests/test_rest_api.py index daf4a151d641..c08158f1a9c2 100644 --- a/cvat/apps/engine/tests/test_rest_api.py +++ b/cvat/apps/engine/tests/test_rest_api.py @@ -263,7 +263,7 @@ def setUpTestData(cls): cls.job.assignee = cls.annotator cls.job.save() - def _run_api_v1_jobs_id(self, jid, user): + def _run_api_v2_jobs_id(self, jid, user): with ForceLogin(user, self.client): response = self.client.get('/api/jobs/{}'.format(jid)) @@ -276,40 +276,40 @@ def _check_request(self, response): self.assertEqual(response.data["start_frame"], self.job.segment.start_frame) self.assertEqual(response.data["stop_frame"], self.job.segment.stop_frame) - def test_api_v1_jobs_id_admin(self): - response = self._run_api_v1_jobs_id(self.job.id, self.admin) + def test_api_v2_jobs_id_admin(self): + response = self._run_api_v2_jobs_id(self.job.id, self.admin) self._check_request(response) - response = self._run_api_v1_jobs_id(self.job.id + 10, self.admin) + response = self._run_api_v2_jobs_id(self.job.id + 10, self.admin) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) - def test_api_v1_jobs_id_owner(self): - response = self._run_api_v1_jobs_id(self.job.id, self.owner) + def test_api_v2_jobs_id_owner(self): + response = self._run_api_v2_jobs_id(self.job.id, self.owner) self._check_request(response) - response = self._run_api_v1_jobs_id(self.job.id + 10, self.owner) + response = self._run_api_v2_jobs_id(self.job.id + 10, self.owner) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) - def test_api_v1_jobs_id_annotator(self): - response = self._run_api_v1_jobs_id(self.job.id, self.annotator) + def test_api_v2_jobs_id_annotator(self): + response = self._run_api_v2_jobs_id(self.job.id, self.annotator) self._check_request(response) - response = self._run_api_v1_jobs_id(self.job.id + 10, self.annotator) + response = self._run_api_v2_jobs_id(self.job.id + 10, self.annotator) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) - def test_api_v1_jobs_id_somebody(self): - response = self._run_api_v1_jobs_id(self.job.id, self.somebody) + def test_api_v2_jobs_id_somebody(self): + response = self._run_api_v2_jobs_id(self.job.id, self.somebody) self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) - response = self._run_api_v1_jobs_id(self.job.id + 10, self.somebody) + response = self._run_api_v2_jobs_id(self.job.id + 10, self.somebody) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) - def test_api_v1_jobs_id_user(self): - response = self._run_api_v1_jobs_id(self.job.id, self.user) + def test_api_v2_jobs_id_user(self): + response = self._run_api_v2_jobs_id(self.job.id, self.user) self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) - response = self._run_api_v1_jobs_id(self.job.id + 10, self.user) + response = self._run_api_v2_jobs_id(self.job.id + 10, self.user) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) - def test_api_v1_jobs_id_no_auth(self): - response = self._run_api_v1_jobs_id(self.job.id, None) + def test_api_v2_jobs_id_no_auth(self): + response = self._run_api_v2_jobs_id(self.job.id, None) self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) - response = self._run_api_v1_jobs_id(self.job.id + 10, None) + response = self._run_api_v2_jobs_id(self.job.id + 10, None) self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) @@ -325,7 +325,7 @@ def setUp(self): def setUpTestData(cls): create_db_users(cls) - def _run_api_v1_jobs_id(self, jid, user, data): + def _run_api_v2_jobs_id(self, jid, user, data): with ForceLogin(user, self.client): response = self.client.put('/api/jobs/{}'.format(jid), data=data, format='json') @@ -340,63 +340,63 @@ def _check_request(self, response, data): self.assertEqual(response.data["start_frame"], self.job.segment.start_frame) self.assertEqual(response.data["stop_frame"], self.job.segment.stop_frame) - def test_api_v1_jobs_id_admin(self): + def test_api_v2_jobs_id_admin(self): data = {"stage": StageChoice.ANNOTATION, "assignee": self.owner.id } - response = self._run_api_v1_jobs_id(self.job.id, self.admin, data) + response = self._run_api_v2_jobs_id(self.job.id, self.admin, data) self._check_request(response, data) - response = self._run_api_v1_jobs_id(self.job.id + 10, self.admin, data) + response = self._run_api_v2_jobs_id(self.job.id + 10, self.admin, data) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) - def test_api_v1_jobs_id_owner(self): + def test_api_v2_jobs_id_owner(self): data = {"stage": StageChoice.ANNOTATION, "assignee": self.owner.id} - response = self._run_api_v1_jobs_id(self.job.id, self.owner, data) + response = self._run_api_v2_jobs_id(self.job.id, self.owner, data) self._check_request(response, data) - response = self._run_api_v1_jobs_id(self.job.id + 10, self.owner, data) + response = self._run_api_v2_jobs_id(self.job.id + 10, self.owner, data) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) - def test_api_v1_jobs_id_annotator(self): + def test_api_v2_jobs_id_annotator(self): data = {"stage": StageChoice.ANNOTATION, "assignee": self.annotator.id} - response = self._run_api_v1_jobs_id(self.job.id, self.annotator, data) + response = self._run_api_v2_jobs_id(self.job.id, self.annotator, data) self._check_request(response, data) - response = self._run_api_v1_jobs_id(self.job.id + 10, self.annotator, data) + response = self._run_api_v2_jobs_id(self.job.id + 10, self.annotator, data) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) - def test_api_v1_jobs_id_somebody(self): + def test_api_v2_jobs_id_somebody(self): data = {"stage": StageChoice.ANNOTATION, "assignee": self.admin.id} - response = self._run_api_v1_jobs_id(self.job.id, self.somebody, data) + response = self._run_api_v2_jobs_id(self.job.id, self.somebody, data) self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) - response = self._run_api_v1_jobs_id(self.job.id + 10, self.somebody, data) + response = self._run_api_v2_jobs_id(self.job.id + 10, self.somebody, data) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) - def test_api_v1_jobs_id_user(self): + def test_api_v2_jobs_id_user(self): data = {"stage": StageChoice.ANNOTATION, "assignee": self.user.id} - response = self._run_api_v1_jobs_id(self.job.id, self.user, data) + response = self._run_api_v2_jobs_id(self.job.id, self.user, data) self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) - response = self._run_api_v1_jobs_id(self.job.id + 10, self.user, data) + response = self._run_api_v2_jobs_id(self.job.id + 10, self.user, data) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) - def test_api_v1_jobs_id_no_auth(self): + def test_api_v2_jobs_id_no_auth(self): data = {"stage": StageChoice.ANNOTATION, "assignee": self.user.id} - response = self._run_api_v1_jobs_id(self.job.id, None, data) + response = self._run_api_v2_jobs_id(self.job.id, None, data) self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) - response = self._run_api_v1_jobs_id(self.job.id + 10, None, data) + response = self._run_api_v2_jobs_id(self.job.id + 10, None, data) self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) class JobPartialUpdateAPITestCase(JobUpdateAPITestCase): - def _run_api_v1_jobs_id(self, jid, user, data): + def _run_api_v2_jobs_id(self, jid, user, data): with ForceLogin(user, self.client): response = self.client.patch('/api/jobs/{}'.format(jid), data=data, format='json') return response - def test_api_v1_jobs_id_annotator_partial(self): + def test_api_v2_jobs_id_annotator_partial(self): data = {"stage": StageChoice.ANNOTATION} - response = self._run_api_v1_jobs_id(self.job.id, self.owner, data) + response = self._run_api_v2_jobs_id(self.job.id, self.owner, data) self._check_request(response, data) - def test_api_v1_jobs_id_admin_partial(self): + def test_api_v2_jobs_id_admin_partial(self): data = {"assignee_id": self.user.id} - response = self._run_api_v1_jobs_id(self.job.id, self.owner, data) + response = self._run_api_v2_jobs_id(self.job.id, self.owner, data) self._check_request(response, data) class ServerAboutAPITestCase(APITestCase): @@ -409,7 +409,7 @@ def setUp(self): def setUpTestData(cls): create_db_users(cls) - def _run_api_v1_server_about(self, user): + def _run_api_v2_server_about(self, user): with ForceLogin(user, self.client): response = self.client.get('/api/server/about') @@ -430,16 +430,16 @@ def _check_request(self, response): self.assertIsNotNone(response.data.get("description", None)) self.assertIsNotNone(response.data.get("version", None)) - def test_api_v1_server_about_admin(self): - response = self._run_api_v1_server_about(self.admin) + def test_api_v2_server_about_admin(self): + response = self._run_api_v2_server_about(self.admin) self._check_request(response) - def test_api_v1_server_about_user(self): - response = self._run_api_v1_server_about(self.user) + def test_api_v2_server_about_user(self): + response = self._run_api_v2_server_about(self.user) self._check_request(response) - def test_api_v1_server_about_no_auth(self): - response = self._run_api_v1_server_about(None) + def test_api_v2_server_about_no_auth(self): + response = self._run_api_v2_server_about(None) self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) def test_api_server_about_versions_admin(self): @@ -469,7 +469,7 @@ def setUpTestData(cls): "stack": "" } - def _run_api_v1_server_exception(self, user): + def _run_api_v2_server_exception(self, user): with ForceLogin(user, self.client): #pylint: disable=unused-variable with mock.patch("cvat.apps.engine.views.clogger") as clogger: @@ -478,16 +478,16 @@ def _run_api_v1_server_exception(self, user): return response - def test_api_v1_server_exception_admin(self): - response = self._run_api_v1_server_exception(self.admin) + def test_api_v2_server_exception_admin(self): + response = self._run_api_v2_server_exception(self.admin) self.assertEqual(response.status_code, status.HTTP_201_CREATED) - def test_api_v1_server_exception_user(self): - response = self._run_api_v1_server_exception(self.user) + def test_api_v2_server_exception_user(self): + response = self._run_api_v2_server_exception(self.user) self.assertEqual(response.status_code, status.HTTP_201_CREATED) - def test_api_v1_server_exception_no_auth(self): - response = self._run_api_v1_server_exception(None) + def test_api_v2_server_exception_no_auth(self): + response = self._run_api_v2_server_exception(None) self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) @@ -517,7 +517,7 @@ def setUpTestData(cls): "is_active": True, }] - def _run_api_v1_server_logs(self, user): + def _run_api_v2_server_logs(self, user): with ForceLogin(user, self.client): #pylint: disable=unused-variable with mock.patch("cvat.apps.engine.views.clogger") as clogger: @@ -526,16 +526,16 @@ def _run_api_v1_server_logs(self, user): return response - def test_api_v1_server_logs_admin(self): - response = self._run_api_v1_server_logs(self.admin) + def test_api_v2_server_logs_admin(self): + response = self._run_api_v2_server_logs(self.admin) self.assertEqual(response.status_code, status.HTTP_201_CREATED) - def test_api_v1_server_logs_user(self): - response = self._run_api_v1_server_logs(self.user) + def test_api_v2_server_logs_user(self): + response = self._run_api_v2_server_logs(self.user) self.assertEqual(response.status_code, status.HTTP_201_CREATED) - def test_api_v1_server_logs_no_auth(self): - response = self._run_api_v1_server_logs(None) + def test_api_v2_server_logs_no_auth(self): + response = self._run_api_v2_server_logs(None) self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) @@ -563,7 +563,7 @@ def _check_data(self, user, data, is_full): extra_check("date_joined", data) class UserListAPITestCase(UserAPITestCase): - def _run_api_v1_users(self, user): + def _run_api_v2_users(self, user): with ForceLogin(user, self.client): response = self.client.get('/api/users') @@ -575,97 +575,97 @@ def _check_response(self, user, response, is_full=True): db_user = getattr(self, user_info['username']) self._check_data(db_user, user_info, is_full) - def test_api_v1_users_admin(self): - response = self._run_api_v1_users(self.admin) + def test_api_v2_users_admin(self): + response = self._run_api_v2_users(self.admin) self._check_response(self.admin, response, True) - def test_api_v1_users_user(self): - response = self._run_api_v1_users(self.user) + def test_api_v2_users_user(self): + response = self._run_api_v2_users(self.user) self._check_response(self.user, response, False) - def test_api_v1_users_annotator(self): - response = self._run_api_v1_users(self.annotator) + def test_api_v2_users_annotator(self): + response = self._run_api_v2_users(self.annotator) self._check_response(self.annotator, response, False) - def test_api_v1_users_somebody(self): - response = self._run_api_v1_users(self.somebody) + def test_api_v2_users_somebody(self): + response = self._run_api_v2_users(self.somebody) self._check_response(self.somebody, response, False) - def test_api_v1_users_no_auth(self): - response = self._run_api_v1_users(None) + def test_api_v2_users_no_auth(self): + response = self._run_api_v2_users(None) self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) class UserSelfAPITestCase(UserAPITestCase): - def _run_api_v1_users_self(self, user): + def _run_api_v2_users_self(self, user): with ForceLogin(user, self.client): response = self.client.get('/api/users/self') return response - def test_api_v1_users_self_admin(self): - response = self._run_api_v1_users_self(self.admin) + def test_api_v2_users_self_admin(self): + response = self._run_api_v2_users_self(self.admin) self._check_response(self.admin, response) - def test_api_v1_users_self_user(self): - response = self._run_api_v1_users_self(self.user) + def test_api_v2_users_self_user(self): + response = self._run_api_v2_users_self(self.user) self._check_response(self.user, response) - def test_api_v1_users_self_annotator(self): - response = self._run_api_v1_users_self(self.annotator) + def test_api_v2_users_self_annotator(self): + response = self._run_api_v2_users_self(self.annotator) self._check_response(self.annotator, response) - def test_api_v1_users_self_somebody(self): - response = self._run_api_v1_users_self(self.somebody) + def test_api_v2_users_self_somebody(self): + response = self._run_api_v2_users_self(self.somebody) self._check_response(self.somebody, response) - def test_api_v1_users_self_no_auth(self): - response = self._run_api_v1_users_self(None) + def test_api_v2_users_self_no_auth(self): + response = self._run_api_v2_users_self(None) self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) class UserGetAPITestCase(UserAPITestCase): - def _run_api_v1_users_id(self, user, user_id): + def _run_api_v2_users_id(self, user, user_id): with ForceLogin(user, self.client): response = self.client.get('/api/users/{}'.format(user_id)) return response - def test_api_v1_users_id_admin(self): - response = self._run_api_v1_users_id(self.admin, self.user.id) + def test_api_v2_users_id_admin(self): + response = self._run_api_v2_users_id(self.admin, self.user.id) self._check_response(self.user, response, True) - response = self._run_api_v1_users_id(self.admin, self.admin.id) + response = self._run_api_v2_users_id(self.admin, self.admin.id) self._check_response(self.admin, response, True) - response = self._run_api_v1_users_id(self.admin, self.owner.id) + response = self._run_api_v2_users_id(self.admin, self.owner.id) self._check_response(self.owner, response, True) - def test_api_v1_users_id_user(self): - response = self._run_api_v1_users_id(self.user, self.user.id) + def test_api_v2_users_id_user(self): + response = self._run_api_v2_users_id(self.user, self.user.id) self._check_response(self.user, response, True) - response = self._run_api_v1_users_id(self.user, self.owner.id) + response = self._run_api_v2_users_id(self.user, self.owner.id) self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) - def test_api_v1_users_id_annotator(self): - response = self._run_api_v1_users_id(self.annotator, self.annotator.id) + def test_api_v2_users_id_annotator(self): + response = self._run_api_v2_users_id(self.annotator, self.annotator.id) self._check_response(self.annotator, response, True) - response = self._run_api_v1_users_id(self.annotator, self.user.id) + response = self._run_api_v2_users_id(self.annotator, self.user.id) self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) - def test_api_v1_users_id_somebody(self): - response = self._run_api_v1_users_id(self.somebody, self.somebody.id) + def test_api_v2_users_id_somebody(self): + response = self._run_api_v2_users_id(self.somebody, self.somebody.id) self._check_response(self.somebody, response, True) - response = self._run_api_v1_users_id(self.somebody, self.user.id) + response = self._run_api_v2_users_id(self.somebody, self.user.id) self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) - def test_api_v1_users_id_no_auth(self): - response = self._run_api_v1_users_id(None, self.user.id) + def test_api_v2_users_id_no_auth(self): + response = self._run_api_v2_users_id(None, self.user.id) self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) class UserPartialUpdateAPITestCase(UserAPITestCase): - def _run_api_v1_users_id(self, user, user_id, data): + def _run_api_v2_users_id(self, user, user_id, data): with ForceLogin(user, self.client): response = self.client.patch('/api/users/{}'.format(user_id), data=data) @@ -678,75 +678,75 @@ def _check_response_with_data(self, user, response, data, is_full): self.assertEqual(response.data[k], v) self._check_response(user, response, is_full) - def test_api_v1_users_id_admin_partial(self): + def test_api_v2_users_id_admin_partial(self): data = {"username": "user09", "last_name": "my last name"} - response = self._run_api_v1_users_id(self.admin, self.user.id, data) + response = self._run_api_v2_users_id(self.admin, self.user.id, data) self._check_response_with_data(self.user, response, data, True) - def test_api_v1_users_id_user_partial(self): + def test_api_v2_users_id_user_partial(self): data = {"username": "user10", "first_name": "my name"} - response = self._run_api_v1_users_id(self.user, self.user.id, data) + response = self._run_api_v2_users_id(self.user, self.user.id, data) self._check_response_with_data(self.user, response, data, False) data = {"is_staff": True} - response = self._run_api_v1_users_id(self.user, self.user.id, data) + response = self._run_api_v2_users_id(self.user, self.user.id, data) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) data = {"username": "admin", "is_superuser": True} - response = self._run_api_v1_users_id(self.user, self.user.id, data) + response = self._run_api_v2_users_id(self.user, self.user.id, data) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) data = {"username": "non_active", "is_active": False} - response = self._run_api_v1_users_id(self.user, self.user.id, data) + response = self._run_api_v2_users_id(self.user, self.user.id, data) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) data = {"username": "annotator01", "first_name": "slave"} - response = self._run_api_v1_users_id(self.user, self.annotator.id, data) + response = self._run_api_v2_users_id(self.user, self.annotator.id, data) self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) - def test_api_v1_users_id_no_auth_partial(self): + def test_api_v2_users_id_no_auth_partial(self): data = {"username": "user12"} - response = self._run_api_v1_users_id(None, self.user.id, data) + response = self._run_api_v2_users_id(None, self.user.id, data) self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) class UserDeleteAPITestCase(UserAPITestCase): - def _run_api_v1_users_id(self, user, user_id): + def _run_api_v2_users_id(self, user, user_id): with ForceLogin(user, self.client): response = self.client.delete('/api/users/{}'.format(user_id)) return response - def test_api_v1_users_id_admin(self): - response = self._run_api_v1_users_id(self.admin, self.user.id) + def test_api_v2_users_id_admin(self): + response = self._run_api_v2_users_id(self.admin, self.user.id) self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) - response = self._run_api_v1_users_id(self.admin, self.admin.id) + response = self._run_api_v2_users_id(self.admin, self.admin.id) self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) - def test_api_v1_users_id_user(self): - response = self._run_api_v1_users_id(self.user, self.owner.id) + def test_api_v2_users_id_user(self): + response = self._run_api_v2_users_id(self.user, self.owner.id) self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) - response = self._run_api_v1_users_id(self.user, self.user.id) + response = self._run_api_v2_users_id(self.user, self.user.id) self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) - def test_api_v1_users_id_annotator(self): - response = self._run_api_v1_users_id(self.annotator, self.user.id) + def test_api_v2_users_id_annotator(self): + response = self._run_api_v2_users_id(self.annotator, self.user.id) self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) - response = self._run_api_v1_users_id(self.annotator, self.annotator.id) + response = self._run_api_v2_users_id(self.annotator, self.annotator.id) self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) - def test_api_v1_users_id_somebody(self): - response = self._run_api_v1_users_id(self.somebody, self.user.id) + def test_api_v2_users_id_somebody(self): + response = self._run_api_v2_users_id(self.somebody, self.user.id) self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) - response = self._run_api_v1_users_id(self.somebody, self.somebody.id) + response = self._run_api_v2_users_id(self.somebody, self.somebody.id) self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) - def test_api_v1_users_id_no_auth(self): - response = self._run_api_v1_users_id(None, self.user.id) + def test_api_v2_users_id_no_auth(self): + response = self._run_api_v2_users_id(None, self.user.id) self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) class ProjectListAPITestCase(APITestCase): @@ -758,35 +758,35 @@ def setUpTestData(cls): create_db_users(cls) cls.projects = create_dummy_db_projects(cls) - def _run_api_v1_projects(self, user, params=""): + def _run_api_v2_projects(self, user, params=""): with ForceLogin(user, self.client): response = self.client.get('/api/projects{}'.format(params)) return response - def test_api_v1_projects_admin(self): - response = self._run_api_v1_projects(self.admin) + def test_api_v2_projects_admin(self): + response = self._run_api_v2_projects(self.admin) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertListEqual( sorted([project.name for project in self.projects]), sorted([res["name"] for res in response.data["results"]])) - def test_api_v1_projects_user(self): - response = self._run_api_v1_projects(self.user) + def test_api_v2_projects_user(self): + response = self._run_api_v2_projects(self.user) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertListEqual( sorted([project.name for project in self.projects if self.user in [project.owner, project.assignee]]), sorted([res["name"] for res in response.data["results"]])) - def test_api_v1_projects_somebody(self): - response = self._run_api_v1_projects(self.somebody) + def test_api_v2_projects_somebody(self): + response = self._run_api_v2_projects(self.somebody) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertListEqual([], [res["name"] for res in response.data["results"]]) - def test_api_v1_projects_no_auth(self): - response = self._run_api_v1_projects(None) + def test_api_v2_projects_no_auth(self): + response = self._run_api_v2_projects(None) self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) class ProjectGetAPITestCase(APITestCase): @@ -798,7 +798,7 @@ def setUpTestData(cls): create_db_users(cls) cls.projects = create_dummy_db_projects(cls) - def _run_api_v1_projects_id(self, pid, user): + def _run_api_v2_projects_id(self, pid, user): with ForceLogin(user, self.client): response = self.client.get('/api/projects/{}'.format(pid)) @@ -816,9 +816,9 @@ def _check_response(self, response, db_project): self.assertEqual(response.data["status"], db_project.status) self.assertEqual(response.data["bug_tracker"], db_project.bug_tracker) - def _check_api_v1_projects_id(self, user): + def _check_api_v2_projects_id(self, user): for db_project in self.projects: - response = self._run_api_v1_projects_id(db_project.id, user) + response = self._run_api_v2_projects_id(db_project.id, user) if user is None: self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) elif user == db_project.owner or user == db_project.assignee or user.is_superuser: @@ -826,17 +826,17 @@ def _check_api_v1_projects_id(self, user): else: self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) - def test_api_v1_projects_id_admin(self): - self._check_api_v1_projects_id(self.admin) + def test_api_v2_projects_id_admin(self): + self._check_api_v2_projects_id(self.admin) - def test_api_v1_projects_id_user(self): - self._check_api_v1_projects_id(self.user) + def test_api_v2_projects_id_user(self): + self._check_api_v2_projects_id(self.user) - def test_api_v1_projects_id_somebody(self): - self._check_api_v1_projects_id(self.somebody) + def test_api_v2_projects_id_somebody(self): + self._check_api_v2_projects_id(self.somebody) - def test_api_v1_projects_id_no_auth(self): - self._check_api_v1_projects_id(None) + def test_api_v2_projects_id_no_auth(self): + self._check_api_v2_projects_id(None) class ProjectDeleteAPITestCase(APITestCase): def setUp(self): @@ -847,15 +847,15 @@ def setUpTestData(cls): create_db_users(cls) cls.projects = create_dummy_db_projects(cls) - def _run_api_v1_projects_id(self, pid, user): + def _run_api_v2_projects_id(self, pid, user): with ForceLogin(user, self.client): response = self.client.delete('/api/projects/{}'.format(pid), format="json") return response - def _check_api_v1_projects_id(self, user): + def _check_api_v2_projects_id(self, user): for db_project in self.projects: - response = self._run_api_v1_projects_id(db_project.id, user) + response = self._run_api_v2_projects_id(db_project.id, user) if user is None: self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) elif user == db_project.owner or user.is_superuser: @@ -864,17 +864,17 @@ def _check_api_v1_projects_id(self, user): self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) - def test_api_v1_projects_id_admin(self): - self._check_api_v1_projects_id(self.admin) + def test_api_v2_projects_id_admin(self): + self._check_api_v2_projects_id(self.admin) - def test_api_v1_projects_id_user(self): - self._check_api_v1_projects_id(self.user) + def test_api_v2_projects_id_user(self): + self._check_api_v2_projects_id(self.user) - def test_api_v1_projects_id_somebody(self): - self._check_api_v1_projects_id(self.somebody) + def test_api_v2_projects_id_somebody(self): + self._check_api_v2_projects_id(self.somebody) - def test_api_v1_projects_id_no_auth(self): - self._check_api_v1_projects_id(None) + def test_api_v2_projects_id_no_auth(self): + self._check_api_v2_projects_id(None) class ProjectCreateAPITestCase(APITestCase): def setUp(self): @@ -884,7 +884,7 @@ def setUp(self): def setUpTestData(cls): create_db_users(cls) - def _run_api_v1_projects(self, user, data): + def _run_api_v2_projects(self, user, data): with ForceLogin(user, self.client): response = self.client.post('/api/projects', data=data, format="json") @@ -903,32 +903,32 @@ def _check_response(self, response, user, data): [label["name"] for label in response.data["labels"]] ) - def _check_api_v1_projects(self, user, data): - response = self._run_api_v1_projects(user, data) + def _check_api_v2_projects(self, user, data): + response = self._run_api_v2_projects(user, data) if user: self._check_response(response, user, data) else: self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) - def test_api_v1_projects_admin(self): + def test_api_v2_projects_admin(self): data = { "name": "new name for the project", "bug_tracker": "http://example.com" } - self._check_api_v1_projects(self.admin, data) + self._check_api_v2_projects(self.admin, data) data = { "owner_id": self.owner.id, "assignee_id": self.assignee.id, "name": "new name for the project" } - self._check_api_v1_projects(self.admin, data) + self._check_api_v2_projects(self.admin, data) data = { "owner_id": self.admin.id, "name": "2" } - self._check_api_v1_projects(self.admin, data) + self._check_api_v2_projects(self.admin, data) data = { "name": "Project with labels", @@ -936,38 +936,38 @@ def test_api_v1_projects_admin(self): "name": "car", }] } - self._check_api_v1_projects(self.admin, data) + self._check_api_v2_projects(self.admin, data) - def test_api_v1_projects_user(self): + def test_api_v2_projects_user(self): data = { "name": "Dummy name", "bug_tracker": "it is just text" } - self._check_api_v1_projects(self.user, data) + self._check_api_v2_projects(self.user, data) data = { "owner_id": self.user.id, "assignee_id": self.user.id, "name": "My import project with data" } - self._check_api_v1_projects(self.user, data) + self._check_api_v2_projects(self.user, data) - def test_api_v1_projects_somebody(self): + def test_api_v2_projects_somebody(self): data = { "name": "My Project #1", "owner_id": self.somebody.id, "assignee_id": self.somebody.id } - self._check_api_v1_projects(self.somebody, data) + self._check_api_v2_projects(self.somebody, data) - def test_api_v1_projects_no_auth(self): + def test_api_v2_projects_no_auth(self): data = { "name": "My Project #2", "owner_id": self.admin.id, } - self._check_api_v1_projects(None, data) + self._check_api_v2_projects(None, data) class ProjectPartialUpdateAPITestCase(APITestCase): def setUp(self): @@ -978,7 +978,7 @@ def setUpTestData(cls): create_db_users(cls) cls.projects = create_dummy_db_projects(cls) - def _run_api_v1_projects_id(self, pid, user, data): + def _run_api_v2_projects_id(self, pid, user, data): with ForceLogin(user, self.client): response = self.client.patch('/api/projects/{}'.format(pid), data=data, format="json") @@ -1008,9 +1008,9 @@ def _check_response(self, response, db_project, data): [label["name"] for label in response.data["labels"]] ) - def _check_api_v1_projects_id(self, user, data): + def _check_api_v2_projects_id(self, user, data): for db_project in self.projects: - response = self._run_api_v1_projects_id(db_project.id, user, data) + response = self._run_api_v2_projects_id(db_project.id, user, data) if user and user.has_perm("engine.project.change", db_project): self._check_response(response, db_project, data) elif user: @@ -1018,7 +1018,7 @@ def _check_api_v1_projects_id(self, user, data): else: self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) - def test_api_v1_projects_id_admin(self): + def test_api_v2_projects_id_admin(self): data = { "name": "project with some labels", "owner_id": self.owner.id, @@ -1028,26 +1028,26 @@ def test_api_v1_projects_id_admin(self): {"name": "person"} ], } - self._check_api_v1_projects_id(self.admin, data) + self._check_api_v2_projects_id(self.admin, data) - def test_api_v1_projects_id_user(self): + def test_api_v2_projects_id_user(self): data = { "name": "new name for the project", "owner_id": self.assignee.id, } - self._check_api_v1_projects_id(self.user, data) + self._check_api_v2_projects_id(self.user, data) - def test_api_v1_projects_id_somebody(self): + def test_api_v2_projects_id_somebody(self): data = { "name": "new name for the project", } - self._check_api_v1_projects_id(self.somebody, data) + self._check_api_v2_projects_id(self.somebody, data) - def test_api_v1_projects_id_no_auth(self): + def test_api_v2_projects_id_no_auth(self): data = { "name": "new name for the project", } - self._check_api_v1_projects_id(None, data) + self._check_api_v2_projects_id(None, data) class UpdateLabelsAPITestCase(APITestCase): def setUp(self): @@ -1108,26 +1108,26 @@ def setUpTestData(cls): create_dummy_db_tasks(cls, db_project) cls.project = db_project - def _check_api_v1_project(self, data): - response = self._run_api_v1_project_id(self.project.id, self.admin, data) + def _check_api_v2_project(self, data): + response = self._run_api_v2_project_id(self.project.id, self.admin, data) self._check_response(response, self.project, data) - def _run_api_v1_project_id(self, pid, user, data): + def _run_api_v2_project_id(self, pid, user, data): with ForceLogin(user, self.client): response = self.client.patch('/api/projects/{}'.format(pid), data=data, format="json") return response - def test_api_v1_projects_create_label(self): + def test_api_v2_projects_create_label(self): data = { "labels": [{ "name": "new label", }], } - self._check_api_v1_project(data) + self._check_api_v2_project(data) - def test_api_v1_projects_edit_label(self): + def test_api_v2_projects_edit_label(self): data = { "labels": [{ "id": 1, @@ -1135,9 +1135,9 @@ def test_api_v1_projects_edit_label(self): "color": "#fefefe", }], } - self._check_api_v1_project(data) + self._check_api_v2_project(data) - def test_api_v1_projects_delete_label(self): + def test_api_v2_projects_delete_label(self): data = { "labels": [{ "id": 2, @@ -1145,7 +1145,7 @@ def test_api_v1_projects_delete_label(self): "deleted": True }] } - self._check_api_v1_project(data) + self._check_api_v2_project(data) class ProjectListOfTasksAPITestCase(APITestCase): def setUp(self): @@ -1156,36 +1156,36 @@ def setUpTestData(cls): create_db_users(cls) cls.projects = create_dummy_db_projects(cls) - def _run_api_v1_projects_id_tasks(self, user, pid): + def _run_api_v2_projects_id_tasks(self, user, pid): with ForceLogin(user, self.client): response = self.client.get('/api/projects/{}/tasks'.format(pid)) return response - def test_api_v1_projects_id_tasks_admin(self): + def test_api_v2_projects_id_tasks_admin(self): project = self.projects[1] - response = self._run_api_v1_projects_id_tasks(self.admin, project.id) + response = self._run_api_v2_projects_id_tasks(self.admin, project.id) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertListEqual( sorted([task.name for task in project.tasks.all()]), sorted([res["name"] for res in response.data["results"]])) - def test_api_v1_projects_id_tasks_user(self): + def test_api_v2_projects_id_tasks_user(self): project = self.projects[1] # the user is owner of the project - response = self._run_api_v1_projects_id_tasks(self.user, project.id) + response = self._run_api_v2_projects_id_tasks(self.user, project.id) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertListEqual( sorted([task.name for task in project.tasks.all()]), sorted([res["name"] for res in response.data["results"]])) - def test_api_v1_projects_id_tasks_somebody(self): + def test_api_v2_projects_id_tasks_somebody(self): project = self.projects[1] - response = self._run_api_v1_projects_id_tasks(self.somebody, project.id) + response = self._run_api_v2_projects_id_tasks(self.somebody, project.id) self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) - def test_api_v1_projects_id_tasks_no_auth(self): + def test_api_v2_projects_id_tasks_no_auth(self): project = self.projects[1] - response = self._run_api_v1_projects_id_tasks(None, project.id) + response = self._run_api_v2_projects_id_tasks(None, project.id) self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) class ProjectBackupAPITestCase(APITestCase): @@ -1480,25 +1480,25 @@ def _create_projects(cls): cls._create_tasks(db_project) cls.projects.append(db_project) - def _run_api_v1_projects_id_export(self, pid, user, query_params=""): + def _run_api_v2_projects_id_export(self, pid, user, query_params=""): with ForceLogin(user, self.client): response = self.client.get('/api/projects/{}/backup?{}'.format(pid, query_params), format="json") return response - def _run_api_v1_projects_import(self, user, data): + def _run_api_v2_projects_import(self, user, data): with ForceLogin(user, self.client): response = self.client.post('/api/projects/backup', data=data, format="multipart") return response - def _run_api_v1_projects_id(self, pid, user): + def _run_api_v2_projects_id(self, pid, user): with ForceLogin(user, self.client): response = self.client.get('/api/projects/{}'.format(pid), format="json") return response.data - def _run_api_v1_projects_id_export_import(self, user): + def _run_api_v2_projects_id_export_import(self, user): for project in self.projects: if user: if user in [project.assignee, project.owner, self.admin]: @@ -1515,13 +1515,13 @@ def _run_api_v1_projects_id_export_import(self, user): HTTP_201_CREATED = status.HTTP_401_UNAUTHORIZED pid = project.id - response = self._run_api_v1_projects_id_export(pid, user) + response = self._run_api_v2_projects_id_export(pid, user) self.assertEqual(response.status_code, HTTP_202_ACCEPTED) - response = self._run_api_v1_projects_id_export(pid, user) + response = self._run_api_v2_projects_id_export(pid, user) self.assertEqual(response.status_code, HTTP_201_CREATED) - response = self._run_api_v1_projects_id_export(pid, user, "action=download") + response = self._run_api_v2_projects_id_export(pid, user, "action=download") self.assertEqual(response.status_code, HTTP_200_OK) if response.status_code == status.HTTP_200_OK: @@ -1532,14 +1532,14 @@ def _run_api_v1_projects_id_export_import(self, user): uploaded_data = { "project_file": content, } - response = self._run_api_v1_projects_import(user, uploaded_data) + response = self._run_api_v2_projects_import(user, uploaded_data) self.assertEqual(response.status_code, HTTP_202_ACCEPTED) if response.status_code == status.HTTP_200_OK: rq_id = response.data["rq_id"] - response = self._run_api_v1_projects_import(user, {"rq_id": rq_id}) + response = self._run_api_v2_projects_import(user, {"rq_id": rq_id}) self.assertEqual(response.status_code, HTTP_201_CREATED) - original_project = self._run_api_v1_projects_id(pid, user) - imported_project = self._run_api_v1_projects_id(response.data["id"], user) + original_project = self._run_api_v2_projects_id(pid, user) + imported_project = self._run_api_v2_projects_id(response.data["id"], user) compare_objects( self=self, obj1=original_project, @@ -1558,17 +1558,17 @@ def _run_api_v1_projects_id_export_import(self, user): ), ) - def test_api_v1_projects_id_export_admin(self): - self._run_api_v1_projects_id_export_import(self.admin) + def test_api_v2_projects_id_export_admin(self): + self._run_api_v2_projects_id_export_import(self.admin) - def test_api_v1_projects_id_export_user(self): - self._run_api_v1_projects_id_export_import(self.user) + def test_api_v2_projects_id_export_user(self): + self._run_api_v2_projects_id_export_import(self.user) - def test_api_v1_projects_id_export_somebody(self): - self._run_api_v1_projects_id_export_import(self.somebody) + def test_api_v2_projects_id_export_somebody(self): + self._run_api_v2_projects_id_export_import(self.somebody) - def test_api_v1_projects_id_export_no_auth(self): - self._run_api_v1_projects_id_export_import(None) + def test_api_v2_projects_id_export_no_auth(self): + self._run_api_v2_projects_id_export_import(None) class ProjectExportAPITestCase(APITestCase): def setUp(self): @@ -1589,14 +1589,14 @@ def setUpTestData(cls): create_dummy_db_tasks(cls, db_project) cls.project = db_project - def _run_api_v1_project_id_export(self, pid, user, annotation_format=""): + def _run_api_v2_project_id_export(self, pid, user, annotation_format=""): with ForceLogin(user, self.client): response = self.client.get( '/api/projects/{}/annotations?format={}'.format(pid, annotation_format), format="json") return response - def _run_api_v1_tasks_id_delete(self, tid, user): + def _run_api_v2_tasks_id_delete(self, tid, user): with ForceLogin(user, self.client): response = self.client.delete('/api/tasks/{}'.format(tid), format="json") return response @@ -1607,14 +1607,14 @@ def _check_tasks_count(self, project, expected_result): def _check_xml(self, pid, user, expected_result): annotation_format = "CVAT for images 1.1" - response = self._run_api_v1_project_id_export(pid, user, annotation_format) + response = self._run_api_v2_project_id_export(pid, user, annotation_format) self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) - response = self._run_api_v1_project_id_export(pid, user, annotation_format) + response = self._run_api_v2_project_id_export(pid, user, annotation_format) self.assertEqual(response.status_code, status.HTTP_201_CREATED) annotation_format = "CVAT for images 1.1&action=download" - response = self._run_api_v1_project_id_export(pid, user, annotation_format) + response = self._run_api_v2_project_id_export(pid, user, annotation_format) self.assertEqual(response.status_code, status.HTTP_200_OK) content = io.BytesIO(b"".join(response.streaming_content)) @@ -1628,7 +1628,7 @@ def _check_xml(self, pid, user, expected_result): tasks = root.findall('meta/project/tasks/task/name') self.assertEqual(len(tasks), expected_result) - def test_api_v1_projects_remove_task_export(self): + def test_api_v2_projects_remove_task_export(self): project = self.project pid = project.id user = self.admin @@ -1637,7 +1637,7 @@ def test_api_v1_projects_remove_task_export(self): self._check_xml(pid, user, 4) tasks_id = [task.id for task in project.tasks.all()] - response = self._run_api_v1_tasks_id_delete(tasks_id[0], self.admin) + response = self._run_api_v2_tasks_id_delete(tasks_id[0], self.admin) self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) self._check_tasks_count(project, 3) @@ -1748,33 +1748,33 @@ def _create_project(project_data): for data in project_data: _create_project(data) - def _run_api_v1_projects_id_dataset_export(self, pid, user, query_params=""): + def _run_api_v2_projects_id_dataset_export(self, pid, user, query_params=""): with ForceLogin(user, self.client): response = self.client.get("/api/projects/{}/dataset?{}".format(pid, query_params), format="json") return response - def _run_api_v1_projects_id_dataset_import(self, pid, user, data, f): + def _run_api_v2_projects_id_dataset_import(self, pid, user, data, f): with ForceLogin(user, self.client): response = self.client.post("/api/projects/{}/dataset?format={}".format(pid, f), data=data, format="multipart") return response - def _run_api_v1_projects_id_dataset_import_status(self, pid, user): + def _run_api_v2_projects_id_dataset_import_status(self, pid, user): with ForceLogin(user, self.client): response = self.client.get("/api/projects/{}/dataset?action=import_status".format(pid), format="json") return response - def test_api_v1_projects_id_export_import(self): + def test_api_v2_projects_id_export_import(self): self._create_projects() self._create_tasks() pid_export, pid_import = self.projects[0]["id"], self.projects[1]["id"] - response = self._run_api_v1_projects_id_dataset_export(pid_export, self.owner, "format=CVAT for images 1.1") + response = self._run_api_v2_projects_id_dataset_export(pid_export, self.owner, "format=CVAT for images 1.1") self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) - response = self._run_api_v1_projects_id_dataset_export(pid_export, self.owner, "format=CVAT for images 1.1") + response = self._run_api_v2_projects_id_dataset_export(pid_export, self.owner, "format=CVAT for images 1.1") self.assertEqual(response.status_code, status.HTTP_201_CREATED) - response = self._run_api_v1_projects_id_dataset_export(pid_export, self.owner, "format=CVAT for images 1.1&action=download") + response = self._run_api_v2_projects_id_dataset_export(pid_export, self.owner, "format=CVAT for images 1.1&action=download") self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertTrue(response.streaming) @@ -1786,10 +1786,10 @@ def test_api_v1_projects_id_export_import(self): "dataset_file": tmp_file, } - response = self._run_api_v1_projects_id_dataset_import(pid_import, self.owner, import_data, "CVAT 1.1") + response = self._run_api_v2_projects_id_dataset_import(pid_import, self.owner, import_data, "CVAT 1.1") self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) - response = self._run_api_v1_projects_id_dataset_import_status(pid_import, self.owner) + response = self._run_api_v2_projects_id_dataset_import_status(pid_import, self.owner) self.assertEqual(response.status_code, status.HTTP_201_CREATED) def tearDown(self) -> None: @@ -1808,35 +1808,35 @@ def setUpTestData(cls): create_db_users(cls) cls.tasks = create_dummy_db_tasks(cls) - def _run_api_v1_tasks(self, user, params=""): + def _run_api_v2_tasks(self, user, params=""): with ForceLogin(user, self.client): response = self.client.get('/api/tasks{}'.format(params)) return response - def test_api_v1_tasks_admin(self): - response = self._run_api_v1_tasks(self.admin) + def test_api_v2_tasks_admin(self): + response = self._run_api_v2_tasks(self.admin) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertListEqual( sorted([task.name for task in self.tasks]), sorted([res["name"] for res in response.data["results"]])) - def test_api_v1_tasks_user(self): - response = self._run_api_v1_tasks(self.user) + def test_api_v2_tasks_user(self): + response = self._run_api_v2_tasks(self.user) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertListEqual( sorted([task.name for task in self.tasks if self.user in [task.owner, task.assignee]]), sorted([res["name"] for res in response.data["results"]])) - def test_api_v1_tasks_somebody(self): - response = self._run_api_v1_tasks(self.somebody) + def test_api_v2_tasks_somebody(self): + response = self._run_api_v2_tasks(self.somebody) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertListEqual([], [res["name"] for res in response.data["results"]]) - def test_api_v1_tasks_no_auth(self): - response = self._run_api_v1_tasks(None) + def test_api_v2_tasks_no_auth(self): + response = self._run_api_v2_tasks(None) self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) class TaskGetAPITestCase(APITestCase): @@ -1848,7 +1848,7 @@ def setUpTestData(cls): create_db_users(cls) cls.tasks = create_dummy_db_tasks(cls) - def _run_api_v1_tasks_id(self, tid, user): + def _run_api_v2_tasks_id(self, tid, user): with ForceLogin(user, self.client): response = self.client.get('/api/tasks/{}'.format(tid)) @@ -1874,9 +1874,9 @@ def _check_response(self, response, db_task): [label["name"] for label in response.data["labels"]] ) - def _check_api_v1_tasks_id(self, user): + def _check_api_v2_tasks_id(self, user): for db_task in self.tasks: - response = self._run_api_v1_tasks_id(db_task.id, user) + response = self._run_api_v2_tasks_id(db_task.id, user) if user is None: self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) elif user == db_task.owner or user.is_superuser: @@ -1885,17 +1885,17 @@ def _check_api_v1_tasks_id(self, user): self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) - def test_api_v1_tasks_id_admin(self): - self._check_api_v1_tasks_id(self.admin) + def test_api_v2_tasks_id_admin(self): + self._check_api_v2_tasks_id(self.admin) - def test_api_v1_tasks_id_user(self): - self._check_api_v1_tasks_id(self.user) + def test_api_v2_tasks_id_user(self): + self._check_api_v2_tasks_id(self.user) - def test_api_v1_tasks_id_somebody(self): - self._check_api_v1_tasks_id(self.somebody) + def test_api_v2_tasks_id_somebody(self): + self._check_api_v2_tasks_id(self.somebody) - def test_api_v1_tasks_id_no_auth(self): - self._check_api_v1_tasks_id(None) + def test_api_v2_tasks_id_no_auth(self): + self._check_api_v2_tasks_id(None) class TaskDeleteAPITestCase(APITestCase): def setUp(self): @@ -1906,15 +1906,15 @@ def setUpTestData(cls): create_db_users(cls) cls.tasks = create_dummy_db_tasks(cls) - def _run_api_v1_tasks_id(self, tid, user): + def _run_api_v2_tasks_id(self, tid, user): with ForceLogin(user, self.client): response = self.client.delete('/api/tasks/{}'.format(tid), format="json") return response - def _check_api_v1_tasks_id(self, user): + def _check_api_v2_tasks_id(self, user): for db_task in self.tasks: - response = self._run_api_v1_tasks_id(db_task.id, user) + response = self._run_api_v2_tasks_id(db_task.id, user) if user is None: self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) elif user == db_task.owner or user.is_superuser: @@ -1923,23 +1923,23 @@ def _check_api_v1_tasks_id(self, user): self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) - def test_api_v1_tasks_id_admin(self): - self._check_api_v1_tasks_id(self.admin) + def test_api_v2_tasks_id_admin(self): + self._check_api_v2_tasks_id(self.admin) - def test_api_v1_tasks_id_user(self): - self._check_api_v1_tasks_id(self.user) + def test_api_v2_tasks_id_user(self): + self._check_api_v2_tasks_id(self.user) - def test_api_v1_tasks_id_somebody(self): - self._check_api_v1_tasks_id(self.somebody) + def test_api_v2_tasks_id_somebody(self): + self._check_api_v2_tasks_id(self.somebody) - def test_api_v1_tasks_id_no_auth(self): - self._check_api_v1_tasks_id(None) + def test_api_v2_tasks_id_no_auth(self): + self._check_api_v2_tasks_id(None) - def test_api_v1_tasks_delete_task_data_after_delete_task(self): + def test_api_v2_tasks_delete_task_data_after_delete_task(self): for task in self.tasks: task_dir = task.get_task_dirname() self.assertTrue(os.path.exists(task_dir)) - self._check_api_v1_tasks_id(self.admin) + self._check_api_v2_tasks_id(self.admin) for task in self.tasks: task_dir = task.get_task_dirname() self.assertFalse(os.path.exists(task_dir)) @@ -1954,7 +1954,7 @@ def setUpTestData(cls): create_db_users(cls) cls.tasks = create_dummy_db_tasks(cls) - def _run_api_v1_tasks_id(self, tid, user, data): + def _run_api_v2_tasks_id(self, tid, user, data): with ForceLogin(user, self.client): response = self.client.put('/api/tasks/{}'.format(tid), data=data, format="json") @@ -1992,9 +1992,9 @@ def _check_response(self, response, db_task, data): [label["name"] for label in response.data["labels"]] ) - def _check_api_v1_tasks_id(self, user, data): + def _check_api_v2_tasks_id(self, user, data): for db_task in self.tasks: - response = self._run_api_v1_tasks_id(db_task.id, user, data) + response = self._run_api_v2_tasks_id(db_task.id, user, data) if user is None: self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) elif user == db_task.owner or user == db_task.assignee or user.is_superuser: @@ -2002,7 +2002,7 @@ def _check_api_v1_tasks_id(self, user, data): else: self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) - def test_api_v1_tasks_id_admin(self): + def test_api_v2_tasks_id_admin(self): data = { "name": "new name for the task", "owner_id": self.owner.id, @@ -2016,9 +2016,9 @@ def test_api_v1_tasks_id_admin(self): }] }] } - self._check_api_v1_tasks_id(self.admin, data) + self._check_api_v2_tasks_id(self.admin, data) - def test_api_v1_tasks_id_user(self): + def test_api_v2_tasks_id_user(self): data = { "name": "new name for the task", "owner_id": self.user.id, @@ -2033,50 +2033,50 @@ def test_api_v1_tasks_id_user(self): }] }] } - self._check_api_v1_tasks_id(self.user, data) + self._check_api_v2_tasks_id(self.user, data) - def test_api_v1_tasks_id_somebody(self): + def test_api_v2_tasks_id_somebody(self): data = { "name": "new name for the task", "labels": [{ "name": "test", }] } - self._check_api_v1_tasks_id(self.somebody, data) + self._check_api_v2_tasks_id(self.somebody, data) - def test_api_v1_tasks_id_no_auth(self): + def test_api_v2_tasks_id_no_auth(self): data = { "name": "new name for the task", "labels": [{ "name": "test", }] } - self._check_api_v1_tasks_id(None, data) + self._check_api_v2_tasks_id(None, data) class TaskPartialUpdateAPITestCase(TaskUpdateAPITestCase): - def _run_api_v1_tasks_id(self, tid, user, data): + def _run_api_v2_tasks_id(self, tid, user, data): with ForceLogin(user, self.client): response = self.client.patch('/api/tasks/{}'.format(tid), data=data, format="json") return response - def test_api_v1_tasks_id_admin_partial(self): + def test_api_v2_tasks_id_admin_partial(self): data = { "name": "new name for the task #2", } - self._check_api_v1_tasks_id(self.admin, data) + self._check_api_v2_tasks_id(self.admin, data) data = { "name": "new name for the task", "owner_id": self.owner.id } - self._check_api_v1_tasks_id(self.admin, data) + self._check_api_v2_tasks_id(self.admin, data) # Now owner is updated, but self.db_tasks are obsolete # We can't do any tests without owner in data below - def test_api_v1_tasks_id_user_partial(self): + def test_api_v2_tasks_id_user_partial(self): data = { "labels": [{ "name": "car", @@ -2089,29 +2089,29 @@ def test_api_v1_tasks_id_user_partial(self): }] }] } - self._check_api_v1_tasks_id(self.user, data) + self._check_api_v2_tasks_id(self.user, data) data = { "owner_id": self.user.id, "assignee_id": self.user.id } - self._check_api_v1_tasks_id(self.user, data) + self._check_api_v2_tasks_id(self.user, data) - def test_api_v1_tasks_id_somebody(self): + def test_api_v2_tasks_id_somebody(self): data = { "name": "my task #3" } - self._check_api_v1_tasks_id(self.somebody, data) + self._check_api_v2_tasks_id(self.somebody, data) - def test_api_v1_tasks_id_no_auth(self): + def test_api_v2_tasks_id_no_auth(self): data = { "name": "new name for the task", "labels": [{ "name": "test", }] } - self._check_api_v1_tasks_id(None, data) + self._check_api_v2_tasks_id(None, data) class TaskUpdateLabelsAPITestCase(UpdateLabelsAPITestCase): @classmethod @@ -2141,26 +2141,26 @@ def setUpTestData(cls): db_task = create_db_task(task_data) cls.task = db_task - def _check_api_v1_task(self, data): - response = self._run_api_v1_task_id(self.task.id, self.admin, data) + def _check_api_v2_task(self, data): + response = self._run_api_v2_task_id(self.task.id, self.admin, data) self._check_response(response, self.task, data) - def _run_api_v1_task_id(self, tid, user, data): + def _run_api_v2_task_id(self, tid, user, data): with ForceLogin(user, self.client): response = self.client.patch('/api/tasks/{}'.format(tid), data=data, format="json") return response - def test_api_v1_tasks_create_label(self): + def test_api_v2_tasks_create_label(self): data = { "labels": [{ "name": "new label", }], } - self._check_api_v1_task(data) + self._check_api_v2_task(data) - def test_api_v1_tasks_edit_label(self): + def test_api_v2_tasks_edit_label(self): data = { "labels": [{ "id": 1, @@ -2168,9 +2168,9 @@ def test_api_v1_tasks_edit_label(self): "color": "#fefefe", }], } - self._check_api_v1_task(data) + self._check_api_v2_task(data) - def test_api_v1_tasks_delete_label(self): + def test_api_v2_tasks_delete_label(self): data = { "labels": [{ "id": 2, @@ -2178,14 +2178,14 @@ def test_api_v1_tasks_delete_label(self): "deleted": True }] } - self._check_api_v1_task(data) + self._check_api_v2_task(data) class TaskMoveAPITestCase(APITestCase): def setUp(self): self.client = APIClient() - self._run_api_v1_job_id_annotation(self.task.segment_set.first().job_set.first().id, self.annotation_data) + self._run_api_v2_job_id_annotation(self.task.segment_set.first().job_set.first().id, self.annotation_data) @classmethod def setUpTestData(cls): @@ -2313,14 +2313,14 @@ def setUpTestData(cls): ] } - def _run_api_v1_tasks_id(self, tid, data): + def _run_api_v2_tasks_id(self, tid, data): with ForceLogin(self.admin, self.client): response = self.client.patch('/api/tasks/{}'.format(tid), data=data, format="json") return response - def _run_api_v1_job_id_annotation(self, jid, data): + def _run_api_v2_job_id_annotation(self, jid, data): with ForceLogin(self.admin, self.client): response = self.client.patch('/api/jobs/{}/annotations?action=create'.format(jid), data=data, format="json") @@ -2330,8 +2330,8 @@ def _run_api_v1_job_id_annotation(self, jid, data): def _check_response(self, response, data): self.assertEqual(response.data["project_id"], data["project_id"]) - def _check_api_v1_tasks(self, tid, data, expected_status=status.HTTP_200_OK): - response = self._run_api_v1_tasks_id(tid, data) + def _check_api_v2_tasks(self, tid, data, expected_status=status.HTTP_200_OK): + response = self._run_api_v2_tasks_id(tid, data) self.assertEqual(response.status_code, expected_status) if (expected_status == status.HTTP_200_OK): self._check_response(response, data) @@ -2345,14 +2345,14 @@ def test_move_task_bad_request(self): "name": "some.other.label" }] } - self._check_api_v1_tasks(self.task.id, data, status.HTTP_400_BAD_REQUEST) + self._check_api_v2_tasks(self.task.id, data, status.HTTP_400_BAD_REQUEST) def test_move_task(self): # Try to move single task to the project data = { "project_id": self.projects[0].id } - self._check_api_v1_tasks(self.task.id, data) + self._check_api_v2_tasks(self.task.id, data) # Try to move task from project to the other project data = { @@ -2362,7 +2362,7 @@ def test_move_task(self): "name": "test" }] } - self._check_api_v1_tasks(self.task.id, data) + self._check_api_v2_tasks(self.task.id, data) class TaskCreateAPITestCase(APITestCase): def setUp(self): @@ -2382,7 +2382,7 @@ def setUp(self): def setUpTestData(cls): create_db_users(cls) - def _run_api_v1_tasks(self, user, data): + def _run_api_v2_tasks(self, user, data): with ForceLogin(user, self.client): response = self.client.post('/api/tasks', data=data, format="json") @@ -2405,14 +2405,14 @@ def _check_response(self, response, user, data): [label["name"] for label in response.data["labels"]] ) - def _check_api_v1_tasks(self, user, data): - response = self._run_api_v1_tasks(user, data) + def _check_api_v2_tasks(self, user, data): + response = self._run_api_v2_tasks(user, data) if user is None: self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) else: self._check_response(response, user, data) - def test_api_v1_tasks_admin(self): + def test_api_v2_tasks_admin(self): data = { "name": "new name for the task", "labels": [{ @@ -2425,9 +2425,9 @@ def test_api_v1_tasks_admin(self): }] }] } - self._check_api_v1_tasks(self.admin, data) + self._check_api_v2_tasks(self.admin, data) - def test_api_v1_tasks_user(self): + def test_api_v2_tasks_user(self): data = { "name": "new name for the task", "owner_id": self.user.id, @@ -2442,36 +2442,36 @@ def test_api_v1_tasks_user(self): }] }] } - self._check_api_v1_tasks(self.user, data) + self._check_api_v2_tasks(self.user, data) def test_api_vi_tasks_user_project(self): data = { "name": "new name for the task", "project_id": self.project.id, } - response = self._run_api_v1_tasks(self.user, data) + response = self._run_api_v2_tasks(self.user, data) data["labels"] = [{ "name": "car" }] self._check_response(response, self.user, data) - def test_api_v1_tasks_somebody(self): + def test_api_v2_tasks_somebody(self): data = { "name": "new name for the task", "labels": [{ "name": "test", }] } - self._check_api_v1_tasks(self.somebody, data) + self._check_api_v2_tasks(self.somebody, data) - def test_api_v1_tasks_no_auth(self): + def test_api_v2_tasks_no_auth(self): data = { "name": "new name for the task", "labels": [{ "name": "test", }] } - self._check_api_v1_tasks(None, data) + self._check_api_v2_tasks(None, data) class TaskImportExportAPITestCase(APITestCase): @@ -2777,25 +2777,25 @@ def _create_task(task_data, media_data): for media in self.media_data: _create_task(data, media) - def _run_api_v1_tasks_id_export(self, tid, user, query_params=""): + def _run_api_v2_tasks_id_export(self, tid, user, query_params=""): with ForceLogin(user, self.client): response = self.client.get('/api/tasks/{}/backup?{}'.format(tid, query_params), format="json") return response - def _run_api_v1_tasks_id_import(self, user, data): + def _run_api_v2_tasks_id_import(self, user, data): with ForceLogin(user, self.client): response = self.client.post('/api/tasks/backup', data=data, format="multipart") return response - def _run_api_v1_tasks_id(self, tid, user): + def _run_api_v2_tasks_id(self, tid, user): with ForceLogin(user, self.client): response = self.client.get('/api/tasks/{}'.format(tid), format="json") return response.data - def _run_api_v1_tasks_id_export_import(self, user): + def _run_api_v2_tasks_id_export_import(self, user): if user: if user == self.owner or user.is_superuser: HTTP_200_OK = status.HTTP_200_OK @@ -2813,13 +2813,13 @@ def _run_api_v1_tasks_id_export_import(self, user): self._create_tasks() for task in self.tasks: tid = task["id"] - response = self._run_api_v1_tasks_id_export(tid, user) + response = self._run_api_v2_tasks_id_export(tid, user) self.assertEqual(response.status_code, HTTP_202_ACCEPTED) - response = self._run_api_v1_tasks_id_export(tid, user) + response = self._run_api_v2_tasks_id_export(tid, user) self.assertEqual(response.status_code, HTTP_201_CREATED) - response = self._run_api_v1_tasks_id_export(tid, user, "action=download") + response = self._run_api_v2_tasks_id_export(tid, user, "action=download") self.assertEqual(response.status_code, HTTP_200_OK) if user and user is not self.somebody and user is not self.user and user is not self.annotator: @@ -2830,14 +2830,14 @@ def _run_api_v1_tasks_id_export_import(self, user): uploaded_data = { "task_file": content, } - response = self._run_api_v1_tasks_id_import(user, uploaded_data) + response = self._run_api_v2_tasks_id_import(user, uploaded_data) self.assertEqual(response.status_code, HTTP_202_ACCEPTED) if user is not self.somebody and user is not self.user and user is not self.annotator: rq_id = response.data["rq_id"] - response = self._run_api_v1_tasks_id_import(user, {"rq_id": rq_id}) + response = self._run_api_v2_tasks_id_import(user, {"rq_id": rq_id}) self.assertEqual(response.status_code, HTTP_201_CREATED) - original_task = self._run_api_v1_tasks_id(tid, user) - imported_task = self._run_api_v1_tasks_id(response.data["id"], user) + original_task = self._run_api_v2_tasks_id(tid, user) + imported_task = self._run_api_v2_tasks_id(response.data["id"], user) compare_objects( self=self, obj1=original_task, @@ -2854,20 +2854,20 @@ def _run_api_v1_tasks_id_export_import(self, user): ), ) - def test_api_v1_tasks_id_export_admin(self): - self._run_api_v1_tasks_id_export_import(self.admin) + def test_api_v2_tasks_id_export_admin(self): + self._run_api_v2_tasks_id_export_import(self.admin) - def test_api_v1_tasks_id_export_user(self): - self._run_api_v1_tasks_id_export_import(self.user) + def test_api_v2_tasks_id_export_user(self): + self._run_api_v2_tasks_id_export_import(self.user) - def test_api_v1_tasks_id_export_annotator(self): - self._run_api_v1_tasks_id_export_import(self.annotator) + def test_api_v2_tasks_id_export_annotator(self): + self._run_api_v2_tasks_id_export_import(self.annotator) - def test_api_v1_tasks_id_export_somebody(self): - self._run_api_v1_tasks_id_export_import(self.somebody) + def test_api_v2_tasks_id_export_somebody(self): + self._run_api_v2_tasks_id_export_import(self.somebody) - def test_api_v1_tasks_id_export_no_auth(self): - self._run_api_v1_tasks_id_export_import(None) + def test_api_v2_tasks_id_export_no_auth(self): + self._run_api_v2_tasks_id_export_import(None) def generate_image_file(filename): f = BytesIO() @@ -3149,7 +3149,7 @@ def tearDownClass(cls): path = os.path.join(settings.SHARE_ROOT, "test_1.pdf") os.remove(path) - def _run_api_v1_tasks_id_data_post(self, tid, user, data): + def _run_api_v2_tasks_id_data_post(self, tid, user, data): with ForceLogin(user, self.client): response = self.client.post('/api/tasks/{}/data'.format(tid), data=data) @@ -3165,7 +3165,7 @@ def _get_task(self, user, tid): with ForceLogin(user, self.client): return self.client.get("/api/tasks/{}".format(tid)) - def _run_api_v1_task_id_data_get(self, tid, user, data_type, data_quality=None, data_number=None): + def _run_api_v2_task_id_data_get(self, tid, user, data_type, data_quality=None, data_number=None): url = '/api/tasks/{}/data?type={}'.format(tid, data_type) if data_quality is not None: url += '&quality={}'.format(data_quality) @@ -3175,19 +3175,19 @@ def _run_api_v1_task_id_data_get(self, tid, user, data_type, data_quality=None, return self.client.get(url) def _get_preview(self, tid, user): - return self._run_api_v1_task_id_data_get(tid, user, "preview") + return self._run_api_v2_task_id_data_get(tid, user, "preview") def _get_compressed_chunk(self, tid, user, number): - return self._run_api_v1_task_id_data_get(tid, user, "chunk", "compressed", number) + return self._run_api_v2_task_id_data_get(tid, user, "chunk", "compressed", number) def _get_original_chunk(self, tid, user, number): - return self._run_api_v1_task_id_data_get(tid, user, "chunk", "original", number) + return self._run_api_v2_task_id_data_get(tid, user, "chunk", "original", number) def _get_compressed_frame(self, tid, user, number): - return self._run_api_v1_task_id_data_get(tid, user, "frame", "compressed", number) + return self._run_api_v2_task_id_data_get(tid, user, "frame", "compressed", number) def _get_original_frame(self, tid, user, number): - return self._run_api_v1_task_id_data_get(tid, user, "frame", "original", number) + return self._run_api_v2_task_id_data_get(tid, user, "frame", "original", number) @staticmethod def _extract_zip_chunk(chunk_buffer, dimension=DimensionType.DIM_2D): @@ -3202,7 +3202,7 @@ def _extract_video_chunk(chunk_buffer): stream = container.streams.video[0] return [f.to_image() for f in container.decode(stream)] - def _test_api_v1_tasks_id_data_spec(self, user, spec, data, expected_compressed_type, expected_original_type, image_sizes, + def _test_api_v2_tasks_id_data_spec(self, user, spec, data, expected_compressed_type, expected_original_type, image_sizes, expected_storage_method=StorageMethodChoice.FILE_SYSTEM, expected_uploaded_data_location=StorageChoice.LOCAL, dimension=DimensionType.DIM_2D): # create task @@ -3212,7 +3212,7 @@ def _test_api_v1_tasks_id_data_spec(self, user, spec, data, expected_compressed_ task_id = response.data["id"] # post data for the task - response = self._run_api_v1_tasks_id_data_post(task_id, user, data) + response = self._run_api_v2_tasks_id_data_post(task_id, user, data) self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) response = self._get_task(user, task_id) @@ -3324,7 +3324,7 @@ def _test_api_v1_tasks_id_data_spec(self, user, spec, data, expected_compressed_ source_image = np.array(source_images[img_idx]) self.assertTrue(np.array_equal(source_image, server_image)) - def _test_api_v1_tasks_id_data(self, user): + def _test_api_v2_tasks_id_data(self, user): task_spec = { "name": "my task #1", "owner_id": user.id, @@ -3345,7 +3345,7 @@ def _test_api_v1_tasks_id_data(self, user): "image_quality": 75, } - self._test_api_v1_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.IMAGESET, self.ChunkType.IMAGESET, image_sizes) + self._test_api_v2_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.IMAGESET, self.ChunkType.IMAGESET, image_sizes) task_spec = { "name": "my task without copying #2", @@ -3371,12 +3371,12 @@ def _test_api_v1_tasks_id_data(self, user): self._image_sizes[task_data["server_files[2]"]], ] - self._test_api_v1_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.IMAGESET, self.ChunkType.IMAGESET, image_sizes, + self._test_api_v2_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.IMAGESET, self.ChunkType.IMAGESET, image_sizes, expected_uploaded_data_location=StorageChoice.SHARE) task_spec.update([('name', 'my task #3')]) task_data.update([('copy_data', True)]) - self._test_api_v1_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.IMAGESET, self.ChunkType.IMAGESET, + self._test_api_v2_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.IMAGESET, self.ChunkType.IMAGESET, image_sizes, expected_uploaded_data_location=StorageChoice.LOCAL) task_spec = { @@ -3394,7 +3394,7 @@ def _test_api_v1_tasks_id_data(self, user): "image_quality": 43, } - self._test_api_v1_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.VIDEO, self.ChunkType.VIDEO, image_sizes) + self._test_api_v2_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.VIDEO, self.ChunkType.VIDEO, image_sizes) task_spec = { "name": "my video task without copying #5", @@ -3412,12 +3412,12 @@ def _test_api_v1_tasks_id_data(self, user): } image_sizes = self._image_sizes[task_data["server_files[0]"]] - self._test_api_v1_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.VIDEO, self.ChunkType.VIDEO, image_sizes, + self._test_api_v2_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.VIDEO, self.ChunkType.VIDEO, image_sizes, expected_uploaded_data_location=StorageChoice.SHARE) task_spec.update([('name', 'my video task #6')]) task_data.update([('copy_data', True)]) - self._test_api_v1_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.VIDEO, self.ChunkType.VIDEO, + self._test_api_v2_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.VIDEO, self.ChunkType.VIDEO, image_sizes, expected_uploaded_data_location=StorageChoice.LOCAL) task_spec = { @@ -3435,12 +3435,12 @@ def _test_api_v1_tasks_id_data(self, user): } image_sizes = self._image_sizes[task_data["server_files[0]"]] - self._test_api_v1_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.VIDEO, self.ChunkType.VIDEO, image_sizes, + self._test_api_v2_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.VIDEO, self.ChunkType.VIDEO, image_sizes, expected_uploaded_data_location=StorageChoice.SHARE) task_spec.update([("name", "my video task #8")]) task_data.update([("copy_data", True)]) - self._test_api_v1_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.VIDEO, self.ChunkType.VIDEO, + self._test_api_v2_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.VIDEO, self.ChunkType.VIDEO, image_sizes, expected_uploaded_data_location=StorageChoice.LOCAL) task_spec = { @@ -3460,12 +3460,12 @@ def _test_api_v1_tasks_id_data(self, user): } image_sizes = self._image_sizes[task_data["server_files[0]"]] - self._test_api_v1_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.IMAGESET, self.ChunkType.VIDEO, image_sizes, + self._test_api_v2_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.IMAGESET, self.ChunkType.VIDEO, image_sizes, expected_uploaded_data_location=StorageChoice.SHARE) task_spec.update([('name', 'my video task #10')]) task_data.update([('copy_data', True)]) - self._test_api_v1_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.IMAGESET, self.ChunkType.VIDEO, + self._test_api_v2_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.IMAGESET, self.ChunkType.VIDEO, image_sizes, expected_uploaded_data_location=StorageChoice.LOCAL) task_spec = { @@ -3483,12 +3483,12 @@ def _test_api_v1_tasks_id_data(self, user): } image_sizes = self._image_sizes[task_data["server_files[0]"]] - self._test_api_v1_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.IMAGESET, self.ChunkType.IMAGESET, image_sizes, + self._test_api_v2_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.IMAGESET, self.ChunkType.IMAGESET, image_sizes, expected_uploaded_data_location=StorageChoice.LOCAL) task_spec.update([('name', 'my archive task #12')]) task_data.update([('copy_data', True)]) - self._test_api_v1_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.IMAGESET, self.ChunkType.IMAGESET, + self._test_api_v2_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.IMAGESET, self.ChunkType.IMAGESET, image_sizes, expected_uploaded_data_location=StorageChoice.LOCAL) task_spec = { @@ -3506,7 +3506,7 @@ def _test_api_v1_tasks_id_data(self, user): "image_quality": 100, } - self._test_api_v1_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.IMAGESET, self.ChunkType.IMAGESET, image_sizes) + self._test_api_v2_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.IMAGESET, self.ChunkType.IMAGESET, image_sizes) task_spec = { "name": "cached video task without copying #14", @@ -3526,12 +3526,12 @@ def _test_api_v1_tasks_id_data(self, user): image_sizes = self._image_sizes[task_data["server_files[0]"]] - self._test_api_v1_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.VIDEO, + self._test_api_v2_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.VIDEO, self.ChunkType.VIDEO, image_sizes, StorageMethodChoice.CACHE, StorageChoice.SHARE) task_spec.update([('name', 'cached video task #15')]) task_data.update([('copy_data', True)]) - self._test_api_v1_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.VIDEO, self.ChunkType.VIDEO, + self._test_api_v2_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.VIDEO, self.ChunkType.VIDEO, image_sizes, StorageMethodChoice.CACHE, StorageChoice.LOCAL) task_spec = { @@ -3557,12 +3557,12 @@ def _test_api_v1_tasks_id_data(self, user): self._image_sizes[task_data["server_files[1]"]], ] - self._test_api_v1_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.IMAGESET, + self._test_api_v2_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.IMAGESET, self.ChunkType.IMAGESET, image_sizes, StorageMethodChoice.CACHE, StorageChoice.SHARE) task_spec.update([('name', 'cached images task #17')]) task_data.update([('copy_data', True)]) - self._test_api_v1_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.IMAGESET, self.ChunkType.IMAGESET, + self._test_api_v2_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.IMAGESET, self.ChunkType.IMAGESET, image_sizes, StorageMethodChoice.CACHE, StorageChoice.LOCAL) task_spec = { @@ -3583,12 +3583,12 @@ def _test_api_v1_tasks_id_data(self, user): image_sizes = self._image_sizes[task_data["server_files[0]"]] - self._test_api_v1_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.IMAGESET, + self._test_api_v2_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.IMAGESET, self.ChunkType.IMAGESET, image_sizes, StorageMethodChoice.CACHE, StorageChoice.LOCAL) task_spec.update([('name', 'my cached zip archive task #19')]) task_data.update([('copy_data', True)]) - self._test_api_v1_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.IMAGESET, self.ChunkType.IMAGESET, + self._test_api_v2_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.IMAGESET, self.ChunkType.IMAGESET, image_sizes, StorageMethodChoice.CACHE, StorageChoice.LOCAL) task_spec = { @@ -3609,7 +3609,7 @@ def _test_api_v1_tasks_id_data(self, user): "use_cache": True } - self._test_api_v1_tasks_id_data_spec(user, task_spec, task_data, + self._test_api_v2_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.IMAGESET, self.ChunkType.IMAGESET, image_sizes, StorageMethodChoice.CACHE) @@ -3630,7 +3630,7 @@ def _test_api_v1_tasks_id_data(self, user): "image_quality": 70, } - self._test_api_v1_tasks_id_data_spec(user, task_spec, task_data, + self._test_api_v2_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.IMAGESET, self.ChunkType.IMAGESET, image_sizes) task_spec = { @@ -3650,13 +3650,13 @@ def _test_api_v1_tasks_id_data(self, user): } image_sizes = self._image_sizes[task_data['server_files[0]']] - self._test_api_v1_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.VIDEO, + self._test_api_v2_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.VIDEO, self.ChunkType.VIDEO, image_sizes, StorageMethodChoice.CACHE, StorageChoice.SHARE) task_spec.update([('name', 'my video with meta info task #23')]) task_data.update([('copy_data', True)]) - self._test_api_v1_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.VIDEO, self.ChunkType.VIDEO, + self._test_api_v2_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.VIDEO, self.ChunkType.VIDEO, image_sizes, StorageMethodChoice.CACHE, StorageChoice.LOCAL) task_spec = { @@ -3676,7 +3676,7 @@ def _test_api_v1_tasks_id_data(self, user): } image_sizes = self._image_sizes['test_rotated_90_video.mp4'] - self._test_api_v1_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.IMAGESET, + self._test_api_v2_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.IMAGESET, self.ChunkType.VIDEO, image_sizes, StorageMethodChoice.FILE_SYSTEM) task_spec = { @@ -3697,7 +3697,7 @@ def _test_api_v1_tasks_id_data(self, user): } image_sizes = self._image_sizes['test_rotated_90_video.mp4'] - self._test_api_v1_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.IMAGESET, + self._test_api_v2_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.IMAGESET, self.ChunkType.VIDEO, image_sizes, StorageMethodChoice.CACHE) task_spec = { @@ -3715,7 +3715,7 @@ def _test_api_v1_tasks_id_data(self, user): "image_quality": 51, } - self._test_api_v1_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.VIDEO, self.ChunkType.VIDEO, image_sizes) + self._test_api_v2_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.VIDEO, self.ChunkType.VIDEO, image_sizes) task_spec = { "name": "my archive task #24", @@ -3732,7 +3732,7 @@ def _test_api_v1_tasks_id_data(self, user): "image_quality": 100, } image_sizes = self._image_sizes["test_pointcloud_pcd.zip"] - self._test_api_v1_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.IMAGESET, + self._test_api_v2_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.IMAGESET, self.ChunkType.IMAGESET, image_sizes, dimension=DimensionType.DIM_3D) @@ -3752,7 +3752,7 @@ def _test_api_v1_tasks_id_data(self, user): "image_quality": 100, } image_sizes = self._image_sizes["test_velodyne_points.zip"] - self._test_api_v1_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.IMAGESET, + self._test_api_v2_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.IMAGESET, self.ChunkType.IMAGESET, image_sizes, dimension=DimensionType.DIM_3D) @@ -3780,12 +3780,12 @@ def _test_api_v1_tasks_id_data(self, user): self._image_sizes[task_data["server_files[2]"]], ] - self._test_api_v1_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.IMAGESET, self.ChunkType.IMAGESET, + self._test_api_v2_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.IMAGESET, self.ChunkType.IMAGESET, image_sizes, StorageMethodChoice.CACHE, StorageChoice.SHARE) task_spec.update([('name', 'my images+manifest #27')]) task_data.update([('copy_data', True)]) - self._test_api_v1_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.IMAGESET, self.ChunkType.IMAGESET, + self._test_api_v2_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.IMAGESET, self.ChunkType.IMAGESET, image_sizes, StorageMethodChoice.CACHE, StorageChoice.LOCAL) # test predefined sorting @@ -3804,7 +3804,7 @@ def _test_api_v1_tasks_id_data(self, user): self._image_sizes[task_data["server_files[2]"]], ] - self._test_api_v1_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.IMAGESET, self.ChunkType.IMAGESET, + self._test_api_v2_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.IMAGESET, self.ChunkType.IMAGESET, image_sizes, StorageMethodChoice.CACHE, StorageChoice.SHARE) # test a natural data sequence @@ -3823,7 +3823,7 @@ def _test_api_v1_tasks_id_data(self, user): self._image_sizes[task_data["server_files[0]"]], ] - self._test_api_v1_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.IMAGESET, self.ChunkType.IMAGESET, + self._test_api_v2_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.IMAGESET, self.ChunkType.IMAGESET, image_sizes, StorageMethodChoice.CACHE, StorageChoice.SHARE) task_spec.update([('name', 'task pdf in the shared folder #30')]) @@ -3835,19 +3835,19 @@ def _test_api_v1_tasks_id_data(self, user): } image_sizes = self._image_sizes[task_data["server_files[0]"]] - self._test_api_v1_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.IMAGESET, self.ChunkType.IMAGESET, + self._test_api_v2_tasks_id_data_spec(user, task_spec, task_data, self.ChunkType.IMAGESET, self.ChunkType.IMAGESET, image_sizes, StorageMethodChoice.CACHE, StorageChoice.LOCAL) - def test_api_v1_tasks_id_data_admin(self): - self._test_api_v1_tasks_id_data(self.admin) + def test_api_v2_tasks_id_data_admin(self): + self._test_api_v2_tasks_id_data(self.admin) - def test_api_v1_tasks_id_data_owner(self): - self._test_api_v1_tasks_id_data(self.owner) + def test_api_v2_tasks_id_data_owner(self): + self._test_api_v2_tasks_id_data(self.owner) - def test_api_v1_tasks_id_data_user(self): - self._test_api_v1_tasks_id_data(self.user) + def test_api_v2_tasks_id_data_user(self): + self._test_api_v2_tasks_id_data(self.user) - def test_api_v1_tasks_id_data_no_auth(self): + def test_api_v2_tasks_id_data_no_auth(self): data = { "name": "my task #3", "owner_id": self.owner.id, @@ -4088,27 +4088,27 @@ def _get_default_attr_values(task): default_attr_values[label["id"]]["all"].append(default_value) return default_attr_values - def _put_api_v1_jobs_id_data(self, jid, user, data): + def _put_api_v2_jobs_id_data(self, jid, user, data): with ForceLogin(user, self.client): response = self.client.put("/api/jobs/{}/annotations".format(jid), data=data, format="json") return response - def _get_api_v1_jobs_id_data(self, jid, user): + def _get_api_v2_jobs_id_data(self, jid, user): with ForceLogin(user, self.client): response = self.client.get("/api/jobs/{}/annotations".format(jid)) return response - def _delete_api_v1_jobs_id_data(self, jid, user): + def _delete_api_v2_jobs_id_data(self, jid, user): with ForceLogin(user, self.client): response = self.client.delete("/api/jobs/{}/annotations".format(jid), format="json") return response - def _patch_api_v1_jobs_id_data(self, jid, user, action, data): + def _patch_api_v2_jobs_id_data(self, jid, user, action, data): with ForceLogin(user, self.client): response = self.client.patch( "/api/jobs/{}/annotations?action={}".format(jid, action), @@ -4121,7 +4121,7 @@ def _check_response(self, response, data): status.HTTP_403_FORBIDDEN, status.HTTP_401_UNAUTHORIZED]: compare_objects(self, data, response.data, ignore_keys=["id"]) - def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): + def _run_api_v2_jobs_id_annotations(self, owner, assignee, annotator): task, jobs = self._create_task(owner, assignee) if annotator: HTTP_200_OK = status.HTTP_200_OK @@ -4139,7 +4139,7 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "shapes": [], "tracks": [] } - response = self._put_api_v1_jobs_id_data(job["id"], annotator, data) + response = self._put_api_v2_jobs_id_data(job["id"], annotator, data) self.assertEqual(response.status_code, HTTP_200_OK) data = { @@ -4241,19 +4241,19 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): } default_attr_values = self._get_default_attr_values(task) - response = self._put_api_v1_jobs_id_data(job["id"], annotator, data) + response = self._put_api_v2_jobs_id_data(job["id"], annotator, data) data["version"] += 1 # need to update the version self.assertEqual(response.status_code, HTTP_200_OK) self._check_response(response, data) - response = self._get_api_v1_jobs_id_data(job["id"], annotator) + response = self._get_api_v2_jobs_id_data(job["id"], annotator) self.assertEqual(response.status_code, HTTP_200_OK) # server should add default attribute values if puted data doesn't contain it data["tags"][0]["attributes"] = default_attr_values[data["tags"][0]["label_id"]]["all"] data["tracks"][0]["shapes"][1]["attributes"] = default_attr_values[data["tracks"][0]["label_id"]]["mutable"] self._check_response(response, data) - response = self._delete_api_v1_jobs_id_data(job["id"], annotator) + response = self._delete_api_v2_jobs_id_data(job["id"], annotator) data["version"] += 1 # need to update the version self.assertEqual(response.status_code, HTTP_204_NO_CONTENT) @@ -4263,7 +4263,7 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "shapes": [], "tracks": [] } - response = self._get_api_v1_jobs_id_data(job["id"], annotator) + response = self._get_api_v2_jobs_id_data(job["id"], annotator) self.assertEqual(response.status_code, HTTP_200_OK) self._check_response(response, data) @@ -4364,13 +4364,13 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): }, ] } - response = self._patch_api_v1_jobs_id_data(job["id"], annotator, + response = self._patch_api_v2_jobs_id_data(job["id"], annotator, "create", data) data["version"] += 1 self.assertEqual(response.status_code, HTTP_200_OK) self._check_response(response, data) - response = self._get_api_v1_jobs_id_data(job["id"], annotator) + response = self._get_api_v2_jobs_id_data(job["id"], annotator) self.assertEqual(response.status_code, HTTP_200_OK) # server should add default attribute values if puted data doesn't contain it data["tags"][0]["attributes"] = default_attr_values[data["tags"][0]["label_id"]]["all"] @@ -4387,17 +4387,17 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): data["tracks"][0]["shapes"][0]["outside"] = False data["tracks"][0]["shapes"][0]["occluded"] = False - response = self._patch_api_v1_jobs_id_data(job["id"], annotator, + response = self._patch_api_v2_jobs_id_data(job["id"], annotator, "update", data) data["version"] = data.get("version", 0) + 1 # need to update the version self.assertEqual(response.status_code, HTTP_200_OK) self._check_response(response, data) - response = self._get_api_v1_jobs_id_data(job["id"], annotator) + response = self._get_api_v2_jobs_id_data(job["id"], annotator) self.assertEqual(response.status_code, HTTP_200_OK) self._check_response(response, data) - response = self._patch_api_v1_jobs_id_data(job["id"], annotator, + response = self._patch_api_v2_jobs_id_data(job["id"], annotator, "delete", data) data["version"] += 1 # need to update the version self.assertEqual(response.status_code, HTTP_200_OK) @@ -4409,7 +4409,7 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): "shapes": [], "tracks": [] } - response = self._get_api_v1_jobs_id_data(job["id"], annotator) + response = self._get_api_v2_jobs_id_data(job["id"], annotator) self.assertEqual(response.status_code, HTTP_200_OK) self._check_response(response, data) @@ -4509,19 +4509,19 @@ def _run_api_v1_jobs_id_annotations(self, owner, assignee, annotator): }, ] } - response = self._patch_api_v1_jobs_id_data(job["id"], annotator, + response = self._patch_api_v2_jobs_id_data(job["id"], annotator, "create", data) self.assertEqual(response.status_code, HTTP_400_BAD_REQUEST) - def test_api_v1_jobs_id_annotations_admin(self): - self._run_api_v1_jobs_id_annotations(self.admin, self.assignee, + def test_api_v2_jobs_id_annotations_admin(self): + self._run_api_v2_jobs_id_annotations(self.admin, self.assignee, self.assignee) - def test_api_v1_jobs_id_annotations_user(self): - self._run_api_v1_jobs_id_annotations(self.user, self.user, + def test_api_v2_jobs_id_annotations_user(self): + self._run_api_v2_jobs_id_annotations(self.user, self.user, self.user) - def test_api_v1_jobs_id_annotations_somebody(self): + def test_api_v2_jobs_id_annotations_somebody(self): _, jobs = self._create_task(self.user, self.user) job = jobs[0] data = { @@ -4531,51 +4531,51 @@ def test_api_v1_jobs_id_annotations_somebody(self): "tracks": [] } - response = self._get_api_v1_jobs_id_data(job["id"], self.somebody) + response = self._get_api_v2_jobs_id_data(job["id"], self.somebody) self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) - response = self._put_api_v1_jobs_id_data(job["id"], self.somebody, data) + response = self._put_api_v2_jobs_id_data(job["id"], self.somebody, data) self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) - response = self._patch_api_v1_jobs_id_data(job["id"], self.somebody, "create", data) + response = self._patch_api_v2_jobs_id_data(job["id"], self.somebody, "create", data) self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) - response = self._delete_api_v1_jobs_id_data(job["id"], self.somebody) + response = self._delete_api_v2_jobs_id_data(job["id"], self.somebody) self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) - def test_api_v1_jobs_id_annotations_no_auth(self): - self._run_api_v1_jobs_id_annotations(self.user, self.user, None) + def test_api_v2_jobs_id_annotations_no_auth(self): + self._run_api_v2_jobs_id_annotations(self.user, self.user, None) class TaskAnnotationAPITestCase(JobAnnotationAPITestCase): - def _put_api_v1_tasks_id_annotations(self, pk, user, data): + def _put_api_v2_tasks_id_annotations(self, pk, user, data): with ForceLogin(user, self.client): response = self.client.put("/api/tasks/{}/annotations".format(pk), data=data, format="json") return response - def _get_api_v1_tasks_id_annotations(self, pk, user): + def _get_api_v2_tasks_id_annotations(self, pk, user): with ForceLogin(user, self.client): response = self.client.get("/api/tasks/{}/annotations".format(pk)) return response - def _delete_api_v1_tasks_id_annotations(self, pk, user): + def _delete_api_v2_tasks_id_annotations(self, pk, user): with ForceLogin(user, self.client): response = self.client.delete("/api/tasks/{}/annotations".format(pk), format="json") return response - def _dump_api_v1_tasks_id_annotations(self, pk, user, query_params=""): + def _dump_api_v2_tasks_id_annotations(self, pk, user, query_params=""): with ForceLogin(user, self.client): response = self.client.get( "/api/tasks/{0}/annotations{1}".format(pk, query_params)) return response - def _patch_api_v1_tasks_id_annotations(self, pk, user, action, data): + def _patch_api_v2_tasks_id_annotations(self, pk, user, action, data): with ForceLogin(user, self.client): response = self.client.patch( "/api/tasks/{}/annotations?action={}".format(pk, action), @@ -4583,7 +4583,7 @@ def _patch_api_v1_tasks_id_annotations(self, pk, user, action, data): return response - def _upload_api_v1_tasks_id_annotations(self, pk, user, data, query_params=""): + def _upload_api_v2_tasks_id_annotations(self, pk, user, data, query_params=""): with ForceLogin(user, self.client): response = self.client.put( path="/api/tasks/{0}/annotations?{1}".format(pk, query_params), @@ -4610,7 +4610,7 @@ def _check_response(self, response, data): print(e) raise - def _run_api_v1_tasks_id_annotations(self, owner, assignee): + def _run_api_v2_tasks_id_annotations(self, owner, assignee): task, _ = self._create_task(owner, assignee) HTTP_200_OK = status.HTTP_200_OK HTTP_204_NO_CONTENT = status.HTTP_204_NO_CONTENT @@ -4622,7 +4622,7 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee): "shapes": [], "tracks": [] } - response = self._put_api_v1_tasks_id_annotations(task["id"], owner, data) + response = self._put_api_v2_tasks_id_annotations(task["id"], owner, data) data["version"] += 1 self.assertEqual(response.status_code, HTTP_200_OK) @@ -4724,21 +4724,21 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee): }, ] } - response = self._put_api_v1_tasks_id_annotations(task["id"], owner, data) + response = self._put_api_v2_tasks_id_annotations(task["id"], owner, data) data["version"] += 1 self.assertEqual(response.status_code, HTTP_200_OK) self._check_response(response, data) default_attr_values = self._get_default_attr_values(task) - response = self._get_api_v1_tasks_id_annotations(task["id"], owner) + response = self._get_api_v2_tasks_id_annotations(task["id"], owner) # server should add default attribute values if puted data doesn't contain it data["tags"][0]["attributes"] = default_attr_values[data["tags"][0]["label_id"]]["all"] data["tracks"][0]["shapes"][1]["attributes"] = default_attr_values[data["tracks"][0]["label_id"]]["mutable"] self.assertEqual(response.status_code, HTTP_200_OK) self._check_response(response, data) - response = self._delete_api_v1_tasks_id_annotations(task["id"], owner) + response = self._delete_api_v2_tasks_id_annotations(task["id"], owner) data["version"] += 1 self.assertEqual(response.status_code, HTTP_204_NO_CONTENT) @@ -4748,7 +4748,7 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee): "shapes": [], "tracks": [] } - response = self._get_api_v1_tasks_id_annotations(task["id"], owner) + response = self._get_api_v2_tasks_id_annotations(task["id"], owner) self.assertEqual(response.status_code, HTTP_200_OK) self._check_response(response, data) @@ -4849,13 +4849,13 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee): }, ] } - response = self._patch_api_v1_tasks_id_annotations(task["id"], owner, + response = self._patch_api_v2_tasks_id_annotations(task["id"], owner, "create", data) data["version"] += 1 self.assertEqual(response.status_code, HTTP_200_OK) self._check_response(response, data) - response = self._get_api_v1_tasks_id_annotations(task["id"], owner) + response = self._get_api_v2_tasks_id_annotations(task["id"], owner) # server should add default attribute values if puted data doesn't contain it data["tags"][0]["attributes"] = default_attr_values[data["tags"][0]["label_id"]]["all"] data["tracks"][0]["shapes"][1]["attributes"] = default_attr_values[data["tracks"][0]["label_id"]]["mutable"] @@ -4872,17 +4872,17 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee): data["tracks"][0]["shapes"][0]["outside"] = False data["tracks"][0]["shapes"][0]["occluded"] = False - response = self._patch_api_v1_tasks_id_annotations(task["id"], owner, + response = self._patch_api_v2_tasks_id_annotations(task["id"], owner, "update", data) data["version"] = data.get("version", 0) + 1 self.assertEqual(response.status_code, HTTP_200_OK) self._check_response(response, data) - response = self._get_api_v1_tasks_id_annotations(task["id"], owner) + response = self._get_api_v2_tasks_id_annotations(task["id"], owner) self.assertEqual(response.status_code, HTTP_200_OK) self._check_response(response, data) - response = self._patch_api_v1_tasks_id_annotations(task["id"], owner, + response = self._patch_api_v2_tasks_id_annotations(task["id"], owner, "delete", data) data["version"] += 1 self.assertEqual(response.status_code, HTTP_200_OK) @@ -4894,7 +4894,7 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee): "shapes": [], "tracks": [] } - response = self._get_api_v1_tasks_id_annotations(task["id"], owner) + response = self._get_api_v2_tasks_id_annotations(task["id"], owner) self.assertEqual(response.status_code, HTTP_200_OK) self._check_response(response, data) @@ -4994,11 +4994,11 @@ def _run_api_v1_tasks_id_annotations(self, owner, assignee): }, ] } - response = self._patch_api_v1_tasks_id_annotations(task["id"], owner, + response = self._patch_api_v2_tasks_id_annotations(task["id"], owner, "create", data) self.assertEqual(response.status_code, HTTP_400_BAD_REQUEST) - def _run_api_v1_tasks_id_annotations_dump_load(self, owner): + def _run_api_v2_tasks_id_annotations_dump_load(self, owner): if owner: HTTP_200_OK = status.HTTP_200_OK HTTP_204_NO_CONTENT = status.HTTP_204_NO_CONTENT @@ -5550,14 +5550,14 @@ def _get_initial_annotation(annotation_format): # 2. add annotation data = _get_initial_annotation(export_format) - response = self._put_api_v1_tasks_id_annotations(task["id"], owner, data) + response = self._put_api_v2_tasks_id_annotations(task["id"], owner, data) data["version"] += 1 self.assertEqual(response.status_code, HTTP_200_OK) self._check_response(response, data) # 3. download annotation - response = self._dump_api_v1_tasks_id_annotations(task["id"], owner, + response = self._dump_api_v2_tasks_id_annotations(task["id"], owner, "?format={}".format(export_format)) if not export_formats[export_format]['enabled']: self.assertEqual(response.status_code, @@ -5566,11 +5566,11 @@ def _get_initial_annotation(annotation_format): else: self.assertEqual(response.status_code, HTTP_202_ACCEPTED) - response = self._dump_api_v1_tasks_id_annotations(task["id"], owner, + response = self._dump_api_v2_tasks_id_annotations(task["id"], owner, "?format={}".format(export_format)) self.assertEqual(response.status_code, HTTP_201_CREATED) - response = self._dump_api_v1_tasks_id_annotations(task["id"], owner, + response = self._dump_api_v2_tasks_id_annotations(task["id"], owner, "?format={}&action=download".format(export_format)) self.assertEqual(response.status_code, HTTP_200_OK) @@ -5581,7 +5581,7 @@ def _get_initial_annotation(annotation_format): content.seek(0) # 5. remove annotation form the task - response = self._delete_api_v1_tasks_id_annotations(task["id"], owner) + response = self._delete_api_v2_tasks_id_annotations(task["id"], owner) data["version"] += 1 self.assertEqual(response.status_code, HTTP_204_NO_CONTENT) @@ -5592,12 +5592,12 @@ def _get_initial_annotation(annotation_format): uploaded_data = { "annotation_file": content, } - response = self._upload_api_v1_tasks_id_annotations( + response = self._upload_api_v2_tasks_id_annotations( task["id"], owner, uploaded_data, "format={}".format(import_format)) self.assertEqual(response.status_code, HTTP_202_ACCEPTED) - response = self._upload_api_v1_tasks_id_annotations( + response = self._upload_api_v2_tasks_id_annotations( task["id"], owner, {}, "format={}".format(import_format)) self.assertEqual(response.status_code, HTTP_201_CREATED) @@ -5606,7 +5606,7 @@ def _get_initial_annotation(annotation_format): if export_format in {"Segmentation mask 1.1", "MOTS PNG 1.0", "CamVid 1.0", "ICDAR Segmentation 1.0"}: continue # can't really predict the result to check - response = self._get_api_v1_tasks_id_annotations(task["id"], owner) + response = self._get_api_v2_tasks_id_annotations(task["id"], owner) self.assertEqual(response.status_code, HTTP_200_OK) data["version"] += 2 # upload is delete + put @@ -5720,34 +5720,34 @@ def generate_coco_anno(): uploaded_data = { "annotation_file": content, } - response = self._upload_api_v1_tasks_id_annotations( + response = self._upload_api_v2_tasks_id_annotations( task["id"], user, uploaded_data, "format={}".format(format_name)) self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) - response = self._upload_api_v1_tasks_id_annotations( + response = self._upload_api_v2_tasks_id_annotations( task["id"], user, {}, "format={}".format(format_name)) self.assertEqual(response.status_code, status.HTTP_201_CREATED) - response = self._get_api_v1_tasks_id_annotations(task["id"], user) + response = self._get_api_v2_tasks_id_annotations(task["id"], user) self.assertEqual(response.status_code, status.HTTP_200_OK) - def test_api_v1_tasks_id_annotations_admin(self): - self._run_api_v1_tasks_id_annotations(self.admin, self.assignee) + def test_api_v2_tasks_id_annotations_admin(self): + self._run_api_v2_tasks_id_annotations(self.admin, self.assignee) - def test_api_v1_tasks_id_annotations_user(self): - self._run_api_v1_tasks_id_annotations(self.user, self.user) + def test_api_v2_tasks_id_annotations_user(self): + self._run_api_v2_tasks_id_annotations(self.user, self.user) - def test_api_v1_tasks_id_annotations_dump_load_admin(self): - self._run_api_v1_tasks_id_annotations_dump_load(self.admin) + def test_api_v2_tasks_id_annotations_dump_load_admin(self): + self._run_api_v2_tasks_id_annotations_dump_load(self.admin) - def test_api_v1_tasks_id_annotations_dump_load_user(self): - self._run_api_v1_tasks_id_annotations_dump_load(self.user) + def test_api_v2_tasks_id_annotations_dump_load_user(self): + self._run_api_v2_tasks_id_annotations_dump_load(self.user) - def test_api_v1_tasks_id_annotations_dump_load_no_auth(self): - self._run_api_v1_tasks_id_annotations_dump_load(self.user) + def test_api_v2_tasks_id_annotations_dump_load_no_auth(self): + self._run_api_v2_tasks_id_annotations_dump_load(self.user) - def test_api_v1_tasks_id_annotations_upload_coco_user(self): + def test_api_v2_tasks_id_annotations_upload_coco_user(self): self._run_coco_annotation_upload_test(self.user) class ServerShareAPITestCase(APITestCase): @@ -5784,21 +5784,21 @@ def tearDownClass(cls): path = os.path.join(settings.SHARE_ROOT, "test2") shutil.rmtree(path) - def _run_api_v1_server_share(self, user, directory): + def _run_api_v2_server_share(self, user, directory): with ForceLogin(user, self.client): response = self.client.get( '/api/server/share?directory={}'.format(directory)) return response - def _test_api_v1_server_share(self, user): + def _test_api_v2_server_share(self, user): data = [ {"name": "test1", "type": "DIR"}, {"name": "test2", "type": "DIR"}, {"name": "file0.txt", "type": "REG"}, ] - response = self._run_api_v1_server_share(user, "/") + response = self._run_api_v2_server_share(user, "/") self.assertEqual(response.status_code, status.HTTP_200_OK) compare_objects( self=self, @@ -5811,7 +5811,7 @@ def _test_api_v1_server_share(self, user): {"name": "file1.txt", "type": "REG"}, {"name": "test3", "type": "DIR"}, ] - response = self._run_api_v1_server_share(user, "/test1") + response = self._run_api_v2_server_share(user, "/test1") self.assertEqual(response.status_code, status.HTTP_200_OK) compare_objects( self=self, @@ -5821,7 +5821,7 @@ def _test_api_v1_server_share(self, user): ) data = [] - response = self._run_api_v1_server_share(user, "/test1/test3") + response = self._run_api_v2_server_share(user, "/test1/test3") self.assertEqual(response.status_code, status.HTTP_200_OK) compare_objects( self=self, @@ -5833,7 +5833,7 @@ def _test_api_v1_server_share(self, user): data = [ {"name": "file2.txt", "type": "REG"}, ] - response = self._run_api_v1_server_share(user, "/test2") + response = self._run_api_v2_server_share(user, "/test2") self.assertEqual(response.status_code, status.HTTP_200_OK) compare_objects( self=self, @@ -5842,29 +5842,29 @@ def _test_api_v1_server_share(self, user): ignore_keys=[] ) - response = self._run_api_v1_server_share(user, "/test4") + response = self._run_api_v2_server_share(user, "/test4") self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) - def test_api_v1_server_share_admin(self): - self._test_api_v1_server_share(self.admin) + def test_api_v2_server_share_admin(self): + self._test_api_v2_server_share(self.admin) - def test_api_v1_server_share_owner(self): - self._test_api_v1_server_share(self.owner) + def test_api_v2_server_share_owner(self): + self._test_api_v2_server_share(self.owner) - def test_api_v1_server_share_assignee(self): - self._test_api_v1_server_share(self.assignee) + def test_api_v2_server_share_assignee(self): + self._test_api_v2_server_share(self.assignee) - def test_api_v1_server_share_user(self): - self._test_api_v1_server_share(self.user) + def test_api_v2_server_share_user(self): + self._test_api_v2_server_share(self.user) - def test_api_v1_server_share_annotator(self): - self._test_api_v1_server_share(self.annotator) + def test_api_v2_server_share_annotator(self): + self._test_api_v2_server_share(self.annotator) - def test_api_v1_server_share_somebody(self): - self._test_api_v1_server_share(self.somebody) + def test_api_v2_server_share_somebody(self): + self._test_api_v2_server_share(self.somebody) - def test_api_v1_server_share_no_auth(self): - response = self._run_api_v1_server_share(None, "/") + def test_api_v2_server_share_no_auth(self): + response = self._run_api_v2_server_share(None, "/") self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) @@ -5890,7 +5890,7 @@ def _get_request(self, path): response = self.client.get(path) return response - def _run_api_v1_server_share(self, directory): + def _run_api_v2_server_share(self, directory): with ForceLogin(self.user, self.client): response = self.client.get( '/api/server/share?directory={}'.format(directory)) @@ -5911,13 +5911,13 @@ def _create_task(self, data, image_data): return task - def test_api_v1_combined_image_and_directory_extractors(self): + def test_api_v2_combined_image_and_directory_extractors(self): shared_images = ["data1/street.png", "data1/people.jpeg", "data1/street_1.jpeg", "data1/street_2.jpeg", "data1/street_3.jpeg", "data1/subdir/image_4.jpeg", "data1/subdir/image_5.jpeg", "data1/subdir/image_6.jpeg"] images_count = len(shared_images) self._create_shared_files(shared_images) - response = self._run_api_v1_server_share("/data1") + response = self._run_api_v2_server_share("/data1") self.assertEqual(response.status_code, status.HTTP_200_OK) shared_images = [img for img in shared_images if os.path.dirname(img) != "/data1/subdir"] diff --git a/cvat/apps/engine/tests/test_rest_api_3D.py b/cvat/apps/engine/tests/test_rest_api_3D.py index 1f9cabba6f43..f0a2afe56c9a 100644 --- a/cvat/apps/engine/tests/test_rest_api_3D.py +++ b/cvat/apps/engine/tests/test_rest_api_3D.py @@ -1,4 +1,4 @@ -# Copyright (C) 2020 Intel Corporation +# Copyright (C) 2020-2022 Intel Corporation # # SPDX-License-Identifier: MIT @@ -67,21 +67,21 @@ def create_db_users(cls): cls.admin = user_admin cls.user = user_dummy - def _put_api_v1_task_id_annotations(self, tid, data): + def _put_api_v2_task_id_annotations(self, tid, data): with ForceLogin(self.admin, self.client): response = self.client.put("/api/tasks/%s/annotations" % tid, data=data, format="json") return response - def _put_api_v1_job_id_annotations(self, jid, data): + def _put_api_v2_job_id_annotations(self, jid, data): with ForceLogin(self.admin, self.client): response = self.client.put("/api/jobs/%s/annotations" % jid, data=data, format="json") return response - def _patch_api_v1_task_id_annotations(self, tid, data, action, user): + def _patch_api_v2_task_id_annotations(self, tid, data, action, user): with ForceLogin(user, self.client): response = self.client.patch( "/api/tasks/{}/annotations?action={}".format(tid, action), @@ -89,7 +89,7 @@ def _patch_api_v1_task_id_annotations(self, tid, data, action, user): return response - def _patch_api_v1_job_id_annotations(self, jid, data, action, user): + def _patch_api_v2_job_id_annotations(self, jid, data, action, user): with ForceLogin(user, self.client): response = self.client.patch( "/api/jobs/{}/annotations?action={}".format(jid, action), @@ -383,7 +383,7 @@ def copy_pcd_file_and_get_task_data(self, test_dir): } return task_data - def test_api_v1_create_annotation_in_job(self): + def test_api_v2_create_annotation_in_job(self): with TestDir() as test_dir: task_data = self.copy_pcd_file_and_get_task_data(test_dir) task = self._create_task(self.task, task_data) @@ -391,7 +391,7 @@ def test_api_v1_create_annotation_in_job(self): annotation = self._get_tmp_annotation(task, self.cuboid_example) for user, edata in list(self.expected_action.items()): with self.subTest(format=edata["name"]): - response = self._patch_api_v1_task_id_annotations(task_id, annotation, CREATE_ACTION, user) + response = self._patch_api_v2_task_id_annotations(task_id, annotation, CREATE_ACTION, user) self.assertEqual(response.status_code, edata["code"]) if edata["annotation_changed"]: task_ann = TaskAnnotation(task_id) @@ -401,13 +401,13 @@ def test_api_v1_create_annotation_in_job(self): self.assertEqual(task_shape, annotation["shapes"][0]) self._remove_annotations(task_id) - def test_api_v1_update_annotation_in_task(self): + def test_api_v2_update_annotation_in_task(self): with TestDir() as test_dir: task_data = self.copy_pcd_file_and_get_task_data(test_dir) task = self._create_task(self.task, task_data) task_id = task["id"] annotation = self._get_tmp_annotation(task, self.cuboid_example) - response = self._put_api_v1_task_id_annotations(task_id, annotation) + response = self._put_api_v2_task_id_annotations(task_id, annotation) self.assertEqual(response.status_code, status.HTTP_200_OK) for user, edata in list(self.expected_action.items()): @@ -416,7 +416,7 @@ def test_api_v1_update_annotation_in_task(self): task_ann_prev.init_from_db() annotation["shapes"][0]["points"] = [x + 0.1 for x in annotation["shapes"][0]["points"]] annotation["shapes"][0]["id"] = task_ann_prev.data["shapes"][0]["id"] - response = self._patch_api_v1_task_id_annotations(task_id, annotation, UPDATE_ACTION, user) + response = self._patch_api_v2_task_id_annotations(task_id, annotation, UPDATE_ACTION, user) self.assertEqual(response.status_code, edata["code"], task_id) if edata["annotation_changed"]: @@ -424,7 +424,7 @@ def test_api_v1_update_annotation_in_task(self): task_ann.init_from_db() self.assertEqual(task_ann.data["shapes"], annotation["shapes"]) - def test_api_v1_remove_annotation_in_task(self): + def test_api_v2_remove_annotation_in_task(self): with TestDir() as test_dir: task_data = self.copy_pcd_file_and_get_task_data(test_dir) task = self._create_task(self.task, task_data) @@ -433,13 +433,13 @@ def test_api_v1_remove_annotation_in_task(self): for user, edata in list(self.expected_action.items()): with self.subTest(format=edata["name"]): - response = self._patch_api_v1_task_id_annotations(task_id, annotation, CREATE_ACTION, self.admin) + response = self._patch_api_v2_task_id_annotations(task_id, annotation, CREATE_ACTION, self.admin) self.assertEqual(response.status_code, status.HTTP_200_OK) task_ann_prev = TaskAnnotation(task_id) task_ann_prev.init_from_db() annotation["shapes"][0]["id"] = task_ann_prev.data["shapes"][0]["id"] - response = self._patch_api_v1_task_id_annotations(task_id, annotation, DELETE_ACTION, user) + response = self._patch_api_v2_task_id_annotations(task_id, annotation, DELETE_ACTION, user) self.assertEqual(response.status_code, edata["code"]) if edata["annotation_changed"]: @@ -447,7 +447,7 @@ def test_api_v1_remove_annotation_in_task(self): task_ann.init_from_db() self.assertTrue(len(task_ann.data["shapes"]) == 0) - def test_api_v1_create_annotation_in_jobs(self): + def test_api_v2_create_annotation_in_jobs(self): with TestDir() as test_dir: task_data = self.copy_pcd_file_and_get_task_data(test_dir) task = self._create_task(self.task, task_data) @@ -456,7 +456,7 @@ def test_api_v1_create_annotation_in_jobs(self): jobs = self._get_jobs(task_id) for user, edata in list(self.expected_action.items()): with self.subTest(format=edata["name"]): - response = self._patch_api_v1_job_id_annotations(jobs[0]["id"], annotation, CREATE_ACTION, user) + response = self._patch_api_v2_job_id_annotations(jobs[0]["id"], annotation, CREATE_ACTION, user) self.assertEqual(response.status_code, edata["code"]) task_ann = TaskAnnotation(task_id) @@ -467,7 +467,7 @@ def test_api_v1_create_annotation_in_jobs(self): self.assertEqual(task_shape, annotation["shapes"][0]) self._remove_annotations(task_id) - def test_api_v1_update_annotation_in_job(self): + def test_api_v2_update_annotation_in_job(self): with TestDir() as test_dir: task_data = self.copy_pcd_file_and_get_task_data(test_dir) task = self._create_task(self.task, task_data) @@ -475,7 +475,7 @@ def test_api_v1_update_annotation_in_job(self): jobs = self._get_jobs(task_id) annotation = self._get_tmp_annotation(task, self.cuboid_example) - response = self._put_api_v1_task_id_annotations(task_id, annotation) + response = self._put_api_v2_task_id_annotations(task_id, annotation) self.assertEqual(response.status_code, status.HTTP_200_OK) for user, edata in list(self.expected_action.items()): @@ -486,7 +486,7 @@ def test_api_v1_update_annotation_in_job(self): annotation["shapes"][0]["points"] = [x + 0.1 for x in annotation["shapes"][0]["points"]] annotation["shapes"][0]["id"] = task_ann_prev.data["shapes"][0]["id"] - response = self._patch_api_v1_job_id_annotations(jobs[0]["id"], annotation, UPDATE_ACTION, user) + response = self._patch_api_v2_job_id_annotations(jobs[0]["id"], annotation, UPDATE_ACTION, user) self.assertEqual(response.status_code, edata["code"]) if edata["annotation_changed"]: @@ -494,7 +494,7 @@ def test_api_v1_update_annotation_in_job(self): task_ann.init_from_db() self.assertEqual(task_ann.data["shapes"], annotation["shapes"]) - def test_api_v1_remove_annotation_in_job(self): + def test_api_v2_remove_annotation_in_job(self): with TestDir() as test_dir: task_data = self.copy_pcd_file_and_get_task_data(test_dir) task = self._create_task(self.task, task_data) @@ -504,13 +504,13 @@ def test_api_v1_remove_annotation_in_job(self): for user, edata in list(self.expected_action.items()): with self.subTest(format=edata["name"]): - response = self._patch_api_v1_job_id_annotations(jobs[0]["id"], annotation, CREATE_ACTION, self.admin) + response = self._patch_api_v2_job_id_annotations(jobs[0]["id"], annotation, CREATE_ACTION, self.admin) self.assertEqual(response.status_code, status.HTTP_200_OK) task_ann_prev = TaskAnnotation(task_id) task_ann_prev.init_from_db() annotation["shapes"][0]["id"] = task_ann_prev.data["shapes"][0]["id"] - response = self._patch_api_v1_job_id_annotations(jobs[0]["id"], annotation, DELETE_ACTION, user) + response = self._patch_api_v2_job_id_annotations(jobs[0]["id"], annotation, DELETE_ACTION, user) self.assertEqual(response.status_code, edata["code"]) if edata["annotation_changed"]: @@ -518,7 +518,7 @@ def test_api_v1_remove_annotation_in_job(self): task_ann.init_from_db() self.assertTrue(len(task_ann.data["shapes"]) == 0) - def test_api_v1_dump_and_upload_annotation(self): + def test_api_v2_dump_and_upload_annotation(self): with TestDir() as test_dir: task_data = self.copy_pcd_file_and_get_task_data(test_dir) task = self._create_task(self.task, task_data) @@ -526,7 +526,7 @@ def test_api_v1_dump_and_upload_annotation(self): for format_name in self.format_names: annotation = self._get_tmp_annotation(task, self.cuboid_example) - response = self._put_api_v1_task_id_annotations(task_id, annotation) + response = self._put_api_v2_task_id_annotations(task_id, annotation) self.assertEqual(response.status_code, status.HTTP_200_OK) task_ann_prev = TaskAnnotation(task_id) task_ann_prev.init_from_db() @@ -571,7 +571,7 @@ def test_api_v1_dump_and_upload_annotation(self): self.assertEqual(len(task_ann_prev.data["shapes"]), len(task_ann.data["shapes"])) self.assertEqual(task_ann_prev.data["shapes"], task_ann.data["shapes"]) - def test_api_v1_rewrite_annotation(self): + def test_api_v2_rewrite_annotation(self): with TestDir() as test_dir: task_data = self.copy_pcd_file_and_get_task_data(test_dir) task = self._create_task(self.task, task_data) @@ -579,7 +579,7 @@ def test_api_v1_rewrite_annotation(self): for format_name in self.format_names: with self.subTest(format=f"{format_name}"): annotation = self._get_tmp_annotation(task, self.cuboid_example) - response = self._put_api_v1_task_id_annotations(task_id, annotation) + response = self._put_api_v2_task_id_annotations(task_id, annotation) self.assertEqual(response.status_code, status.HTTP_200_OK) task_ann_prev = TaskAnnotation(task_id) task_ann_prev.init_from_db() @@ -596,7 +596,7 @@ def test_api_v1_rewrite_annotation(self): # rewrite annotation annotation_copy = copy.deepcopy(annotation) annotation_copy["shapes"][0]["points"] = [0] * 16 - response = self._put_api_v1_task_id_annotations(task_id, annotation_copy) + response = self._put_api_v2_task_id_annotations(task_id, annotation_copy) self.assertEqual(response.status_code, status.HTTP_200_OK) file_name = osp.join(test_dir, f"{format_name}.zip") @@ -612,7 +612,7 @@ def test_api_v1_rewrite_annotation(self): self.assertEqual(len(task_ann_prev.data["shapes"]), len(task_ann.data["shapes"])) self.assertEqual(task_ann_prev.data["shapes"], task_ann.data["shapes"]) - def test_api_v1_dump_and_upload_empty_annotation(self): + def test_api_v2_dump_and_upload_empty_annotation(self): with TestDir() as test_dir: task_data = self.copy_pcd_file_and_get_task_data(test_dir) task = self._create_task(self.task, task_data) @@ -643,7 +643,7 @@ def test_api_v1_dump_and_upload_empty_annotation(self): self.assertEqual(len(task_ann.data["shapes"]), 0) self.assertEqual(task_ann_prev.data["shapes"], task_ann.data["shapes"]) - def test_api_v1_dump_and_upload_several_jobs(self): + def test_api_v2_dump_and_upload_several_jobs(self): job_test_cases = ["first", "all"] with TestDir() as test_dir: task_data = self.copy_pcd_file_and_get_task_data(test_dir) @@ -656,10 +656,10 @@ def test_api_v1_dump_and_upload_several_jobs(self): jobs = self._get_jobs(task_id) if job_test_case == "all": for job in jobs: - response = self._put_api_v1_job_id_annotations(job["id"], annotation) + response = self._put_api_v2_job_id_annotations(job["id"], annotation) self.assertEqual(response.status_code, status.HTTP_200_OK) else: - response = self._put_api_v1_job_id_annotations(jobs[1]["id"], annotation) + response = self._put_api_v2_job_id_annotations(jobs[1]["id"], annotation) self.assertEqual(response.status_code, status.HTTP_200_OK) task_ann_prev = TaskAnnotation(task_id) task_ann_prev.init_from_db() @@ -673,7 +673,7 @@ def test_api_v1_dump_and_upload_several_jobs(self): self._remove_annotations(task_id) - def test_api_v1_upload_annotation_with_attributes(self): + def test_api_v2_upload_annotation_with_attributes(self): with TestDir() as test_dir: task_data = self.copy_pcd_file_and_get_task_data(test_dir) task = self._create_task(self.task_with_attributes, task_data) @@ -681,7 +681,7 @@ def test_api_v1_upload_annotation_with_attributes(self): for format_name in self.format_names: annotation = self._get_tmp_annotation(task, self.cuboid_example) - response = self._put_api_v1_task_id_annotations(task_id, annotation) + response = self._put_api_v2_task_id_annotations(task_id, annotation) self.assertEqual(response.status_code, status.HTTP_200_OK) task_ann_prev = TaskAnnotation(task_id) task_ann_prev.init_from_db() @@ -711,7 +711,7 @@ def test_api_v1_upload_annotation_with_attributes(self): self.assertEqual(task_ann_prev.data["shapes"][0]["attributes"], task_ann.data["shapes"][0]["attributes"]) - def test_api_v1_export_dataset(self): + def test_api_v2_export_dataset(self): with TestDir() as test_dir: task_data = self.copy_pcd_file_and_get_task_data(test_dir) task = self._create_task(self.task, task_data) @@ -719,7 +719,7 @@ def test_api_v1_export_dataset(self): for format_name in self.format_names: annotation = self._get_tmp_annotation(task, self.cuboid_example) - response = self._put_api_v1_task_id_annotations(task_id, annotation) + response = self._put_api_v2_task_id_annotations(task_id, annotation) self.assertEqual(response.status_code, status.HTTP_200_OK) task_ann_prev = TaskAnnotation(task_id) task_ann_prev.init_from_db() diff --git a/cvat/apps/iam/tests/test_rest_api.py b/cvat/apps/iam/tests/test_rest_api.py index 8716c36eca25..b02850a8d45e 100644 --- a/cvat/apps/iam/tests/test_rest_api.py +++ b/cvat/apps/iam/tests/test_rest_api.py @@ -1,4 +1,4 @@ -# Copyright (C) 2021 Intel Corporation +# Copyright (C) 2021-2022 Intel Corporation # # SPDX-License-Identifier: MIT @@ -28,7 +28,7 @@ class UserRegisterAPITestCase(APITestCase): def setUp(self): self.client = APIClient() - def _run_api_v1_user_register(self, data): + def _run_api_v2_user_register(self, data): url = reverse('rest_register') response = self.client.post(url, data, format='json') return response @@ -38,11 +38,11 @@ def _check_response(self, response, data): self.assertEqual(response.data, data) @override_settings(ACCOUNT_EMAIL_VERIFICATION='none') - def test_api_v1_user_register_with_email_verification_none(self): + def test_api_v2_user_register_with_email_verification_none(self): """ Ensure we can register a user and get auth token key when email verification is none """ - response = self._run_api_v1_user_register(self.user_data) + response = self._run_api_v2_user_register(self.user_data) user_token = Token.objects.get(user__username=response.data['username']) self._check_response(response, {'first_name': 'test_first', 'last_name': 'test_last', 'username': 'test_username', 'email': 'test_email@test.com', @@ -52,11 +52,11 @@ def test_api_v1_user_register_with_email_verification_none(self): # the tests and pass it using ROOT_URLCONF in the override settings decorator @override_settings(ACCOUNT_EMAIL_VERIFICATION='optional', ROOT_URLCONF=__name__) - def test_api_v1_user_register_with_email_verification_optional(self): + def test_api_v2_user_register_with_email_verification_optional(self): """ Ensure we can register a user and get auth token key when email verification is optional """ - response = self._run_api_v1_user_register(self.user_data) + response = self._run_api_v2_user_register(self.user_data) user_token = Token.objects.get(user__username=response.data['username']) self._check_response(response, {'first_name': 'test_first', 'last_name': 'test_last', 'username': 'test_username', 'email': 'test_email@test.com', @@ -68,7 +68,7 @@ def test_register_account_with_email_verification_mandatory(self): """ Ensure we can register a user and it does not return auth token key when email verification is mandatory """ - response = self._run_api_v1_user_register(self.user_data) + response = self._run_api_v2_user_register(self.user_data) self._check_response(response, {'first_name': 'test_first', 'last_name': 'test_last', 'username': 'test_username', 'email': 'test_email@test.com', 'email_verification_required': True, 'key': None}) diff --git a/cvat/apps/lambda_manager/tests/test_lambda.py b/cvat/apps/lambda_manager/tests/test_lambda.py index 98b29627be71..4a8699ea32c1 100644 --- a/cvat/apps/lambda_manager/tests/test_lambda.py +++ b/cvat/apps/lambda_manager/tests/test_lambda.py @@ -213,7 +213,7 @@ def __check_expected_keys_in_response_function(self, data): self.assertIn(key, data) - def test_api_v1_lambda_functions_list(self): + def test_api_v2_lambda_functions_list(self): response = self._get_request(LAMBDA_FUNCTIONS_PATH, self.admin) self.assertEqual(response.status_code, status.HTTP_200_OK) for data in response.data: @@ -229,7 +229,7 @@ def test_api_v1_lambda_functions_list(self): @mock.patch('cvat.apps.lambda_manager.views.LambdaGateway._http', return_value = {}) - def test_api_v1_lambda_functions_list_empty(self, mock_http): + def test_api_v2_lambda_functions_list_empty(self, mock_http): response = self._get_request(LAMBDA_FUNCTIONS_PATH, self.admin) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(len(response.data), 0) @@ -243,12 +243,12 @@ def test_api_v1_lambda_functions_list_empty(self, mock_http): @mock.patch('cvat.apps.lambda_manager.views.LambdaGateway._http', return_value = functions["negative"]) - def test_api_v1_lambda_functions_list_wrong(self, mock_http): + def test_api_v2_lambda_functions_list_wrong(self, mock_http): response = self._get_request(LAMBDA_FUNCTIONS_PATH, self.admin) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) - def test_api_v1_lambda_functions_read(self): + def test_api_v2_lambda_functions_read(self): ids_functions = [id_function_detector, id_function_interactor,\ id_function_tracker, id_function_reid_response_data, \ id_function_non_type, id_function_wrong_type, id_function_unknown_type] @@ -268,7 +268,7 @@ def test_api_v1_lambda_functions_read(self): self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) - def test_api_v1_lambda_functions_read_wrong_id(self): + def test_api_v2_lambda_functions_read_wrong_id(self): id_wrong_function = "test-functions-wrong-id" response = self._get_request(f'{LAMBDA_FUNCTIONS_PATH}/{id_wrong_function}', self.admin) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) @@ -281,13 +281,13 @@ def test_api_v1_lambda_functions_read_wrong_id(self): @mock.patch('cvat.apps.lambda_manager.views.LambdaGateway._http', return_value = functions["negative"][id_function_non_unique_labels]) - def test_api_v1_lambda_functions_read_non_unique_labels(self, mock_http): + def test_api_v2_lambda_functions_read_non_unique_labels(self, mock_http): response = self._get_request(f'{LAMBDA_FUNCTIONS_PATH}/{id_function_non_unique_labels}', self.admin) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) @skip("Fail: add mock") - def test_api_v1_lambda_requests_list(self): + def test_api_v2_lambda_requests_list(self): response = self._get_request(LAMBDA_REQUESTS_PATH, self.admin) self.assertEqual(response.status_code, status.HTTP_200_OK) for key in expected_keys_in_response_requests: @@ -302,7 +302,7 @@ def test_api_v1_lambda_requests_list(self): self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) - def test_api_v1_lambda_requests_list_empty(self): + def test_api_v2_lambda_requests_list_empty(self): response = self._get_request(LAMBDA_REQUESTS_PATH, self.admin) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(len(response.data), 0) @@ -315,7 +315,7 @@ def test_api_v1_lambda_requests_list_empty(self): self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) - def test_api_v1_lambda_requests_read(self): + def test_api_v2_lambda_requests_read(self): # create request data_main_task = { "function": id_function_detector, @@ -345,7 +345,7 @@ def test_api_v1_lambda_requests_read(self): self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) - def test_api_v1_lambda_requests_read_wrong_id(self): + def test_api_v2_lambda_requests_read_wrong_id(self): id_request = "cf343b95-afeb-475e-ab53-8d7e64991d30-wrong-id" response = self._get_request(f'{LAMBDA_REQUESTS_PATH}/{id_request}', self.admin) @@ -358,7 +358,7 @@ def test_api_v1_lambda_requests_read_wrong_id(self): self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) - def test_api_v1_lambda_requests_delete_finished_request(self): + def test_api_v2_lambda_requests_delete_finished_request(self): data = { "function": id_function_detector, "task": self.main_task["id"], @@ -387,11 +387,11 @@ def test_api_v1_lambda_requests_delete_finished_request(self): @skip("Fail: add mock") - def test_api_v1_lambda_requests_delete_not_finished_request(self): + def test_api_v2_lambda_requests_delete_not_finished_request(self): pass - def test_api_v1_lambda_requests_create(self): + def test_api_v2_lambda_requests_create(self): ids_functions = [id_function_detector, id_function_interactor, id_function_tracker, \ id_function_reid_response_data, id_function_detector, id_function_reid_response_no_data, \ id_function_non_type, id_function_wrong_type, id_function_unknown_type] @@ -436,7 +436,7 @@ def test_api_v1_lambda_requests_create(self): @mock.patch('cvat.apps.lambda_manager.views.LambdaGateway._http', return_value = functions["negative"]["test-model-has-non-unique-labels"]) - def test_api_v1_lambda_requests_create_non_unique_labels(self, mock_http): + def test_api_v2_lambda_requests_create_non_unique_labels(self, mock_http): data = { "function": id_function_non_unique_labels, "task": self.main_task["id"], @@ -450,13 +450,13 @@ def test_api_v1_lambda_requests_create_non_unique_labels(self, mock_http): self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) - def test_api_v1_lambda_requests_create_empty_data(self): + def test_api_v2_lambda_requests_create_empty_data(self): data = {} response = self._post_request(LAMBDA_REQUESTS_PATH, self.admin, data) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) - def test_api_v1_lambda_requests_create_without_function(self): + def test_api_v2_lambda_requests_create_without_function(self): data = { "task": self.main_task["id"], "cleanup": True, @@ -468,7 +468,7 @@ def test_api_v1_lambda_requests_create_without_function(self): self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) - def test_api_v1_lambda_requests_create_wrong_id_function(self): + def test_api_v2_lambda_requests_create_wrong_id_function(self): data = { "function": "test-requests-wrong-id", "task": self.main_task["id"], @@ -482,7 +482,7 @@ def test_api_v1_lambda_requests_create_wrong_id_function(self): @skip("Fail: add mock") - def test_api_v1_lambda_requests_create_two_requests(self): + def test_api_v2_lambda_requests_create_two_requests(self): data = { "function": id_function_detector, "task": self.main_task["id"], @@ -496,7 +496,7 @@ def test_api_v1_lambda_requests_create_two_requests(self): self.assertEqual(response.status_code, status.HTTP_409_CONFLICT) - def test_api_v1_lambda_requests_create_empty_mapping(self): + def test_api_v2_lambda_requests_create_empty_mapping(self): data = { "function": id_function_detector, "task": self.main_task["id"], @@ -509,7 +509,7 @@ def test_api_v1_lambda_requests_create_empty_mapping(self): self.assertIn(key, response.data) - def test_api_v1_lambda_requests_create_without_cleanup(self): + def test_api_v2_lambda_requests_create_without_cleanup(self): data = { "function": id_function_detector, "task": self.main_task["id"], @@ -523,7 +523,7 @@ def test_api_v1_lambda_requests_create_without_cleanup(self): self.assertIn(key, response.data) - def test_api_v1_lambda_requests_create_without_mapping(self): + def test_api_v2_lambda_requests_create_without_mapping(self): data = { "function": id_function_detector, "task": self.main_task["id"], @@ -535,7 +535,7 @@ def test_api_v1_lambda_requests_create_without_mapping(self): self.assertIn(key, response.data) - def test_api_v1_lambda_requests_create_without_task(self): + def test_api_v2_lambda_requests_create_without_task(self): data = { "function": id_function_detector, "cleanup": True, @@ -547,7 +547,7 @@ def test_api_v1_lambda_requests_create_without_task(self): self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) - def test_api_v1_lambda_requests_create_wrong_id_task(self): + def test_api_v2_lambda_requests_create_wrong_id_task(self): data = { "function": id_function_detector, "task": 12345, @@ -560,7 +560,7 @@ def test_api_v1_lambda_requests_create_wrong_id_task(self): self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) - def test_api_v1_lambda_requests_create_is_not_ready(self): + def test_api_v2_lambda_requests_create_is_not_ready(self): ids_functions = [id_function_state_building, id_function_state_error] for id_func in ids_functions: @@ -577,7 +577,7 @@ def test_api_v1_lambda_requests_create_is_not_ready(self): self.assertEqual(response.status_code, status.HTTP_500_INTERNAL_SERVER_ERROR) - def test_api_v1_lambda_functions_create_detector(self): + def test_api_v2_lambda_functions_create_detector(self): data_main_task = { "task": self.main_task["id"], "frame": 0, @@ -605,8 +605,8 @@ def test_api_v1_lambda_functions_create_detector(self): response = self._post_request(f"{LAMBDA_FUNCTIONS_PATH}/{id_function_detector}", None, data_main_task) self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) - @skip("Fail: expected result != actual result") # TODO move test to test_api_v1_lambda_functions_create - def test_api_v1_lambda_functions_create_user_assigned_to_no_user(self): + @skip("Fail: expected result != actual result") # TODO move test to test_api_v2_lambda_functions_create + def test_api_v2_lambda_functions_create_user_assigned_to_no_user(self): data = { "task": self.main_task["id"], "frame": 0, @@ -619,7 +619,7 @@ def test_api_v1_lambda_functions_create_user_assigned_to_no_user(self): self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) - def test_api_v1_lambda_functions_create_interactor(self): + def test_api_v2_lambda_functions_create_interactor(self): data_main_task = { "task": self.main_task["id"], "frame": 0, @@ -664,7 +664,7 @@ def test_api_v1_lambda_functions_create_interactor(self): self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) - def test_api_v1_lambda_functions_create_tracker(self): + def test_api_v2_lambda_functions_create_tracker(self): data_main_task = { "task": self.main_task["id"], "frame": 0, @@ -696,7 +696,7 @@ def test_api_v1_lambda_functions_create_tracker(self): self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) - def test_api_v1_lambda_functions_create_reid(self): + def test_api_v2_lambda_functions_create_reid(self): data_main_task = { "task": self.main_task["id"], "frame0": 0, @@ -747,7 +747,7 @@ def test_api_v1_lambda_functions_create_reid(self): self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) - def test_api_v1_lambda_functions_create_non_type(self): + def test_api_v2_lambda_functions_create_non_type(self): data = { "task": self.main_task["id"], "frame": 0, @@ -761,7 +761,7 @@ def test_api_v1_lambda_functions_create_non_type(self): self.assertEqual(response.status_code, status.HTTP_500_INTERNAL_SERVER_ERROR) - def test_api_v1_lambda_functions_create_wrong_type(self): + def test_api_v2_lambda_functions_create_wrong_type(self): data = { "task": self.main_task["id"], "frame": 0, @@ -775,7 +775,7 @@ def test_api_v1_lambda_functions_create_wrong_type(self): self.assertEqual(response.status_code, status.HTTP_500_INTERNAL_SERVER_ERROR) - def test_api_v1_lambda_functions_create_unknown_type(self): + def test_api_v2_lambda_functions_create_unknown_type(self): data = { "task": self.main_task["id"], "frame": 0, @@ -790,7 +790,7 @@ def test_api_v1_lambda_functions_create_unknown_type(self): @mock.patch('cvat.apps.lambda_manager.views.LambdaGateway._http', return_value = functions["negative"]["test-model-has-non-unique-labels"]) - def test_api_v1_lambda_functions_create_non_unique_labels(self, mock_http): + def test_api_v2_lambda_functions_create_non_unique_labels(self, mock_http): data = { "task": self.main_task["id"], "frame": 0, @@ -804,7 +804,7 @@ def test_api_v1_lambda_functions_create_non_unique_labels(self, mock_http): self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) - def test_api_v1_lambda_functions_create_quality(self): + def test_api_v2_lambda_functions_create_quality(self): qualities = [None, "original", "compressed"] for quality in qualities: @@ -835,13 +835,13 @@ def test_api_v1_lambda_functions_create_quality(self): self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) - def test_api_v1_lambda_functions_create_empty_data(self): + def test_api_v2_lambda_functions_create_empty_data(self): data = {} response = self._post_request(f"{LAMBDA_FUNCTIONS_PATH}/{id_function_detector}", self.admin, data) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) - def test_api_v1_lambda_functions_create_detector_empty_mapping(self): + def test_api_v2_lambda_functions_create_detector_empty_mapping(self): data = { "task": self.main_task["id"], "frame": 0, @@ -852,7 +852,7 @@ def test_api_v1_lambda_functions_create_detector_empty_mapping(self): self.assertEqual(response.status_code, status.HTTP_200_OK) - def test_api_v1_lambda_functions_create_detector_without_cleanup(self): + def test_api_v2_lambda_functions_create_detector_without_cleanup(self): data = { "task": self.main_task["id"], "frame": 0, @@ -864,7 +864,7 @@ def test_api_v1_lambda_functions_create_detector_without_cleanup(self): self.assertEqual(response.status_code, status.HTTP_200_OK) - def test_api_v1_lambda_functions_create_detector_without_mapping(self): + def test_api_v2_lambda_functions_create_detector_without_mapping(self): data = { "task": self.main_task["id"], "frame": 0, @@ -874,7 +874,7 @@ def test_api_v1_lambda_functions_create_detector_without_mapping(self): self.assertEqual(response.status_code, status.HTTP_200_OK) - def test_api_v1_lambda_functions_create_detector_without_task(self): + def test_api_v2_lambda_functions_create_detector_without_task(self): data = { "frame": 0, "cleanup": True, @@ -886,7 +886,7 @@ def test_api_v1_lambda_functions_create_detector_without_task(self): self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) - def test_api_v1_lambda_functions_create_detector_without_id_frame(self): + def test_api_v2_lambda_functions_create_detector_without_id_frame(self): data = { "task": self.main_task["id"], "cleanup": True, @@ -898,7 +898,7 @@ def test_api_v1_lambda_functions_create_detector_without_id_frame(self): self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) - def test_api_v1_lambda_functions_create_wrong_id_function(self): + def test_api_v2_lambda_functions_create_wrong_id_function(self): data = { "task": self.main_task["id"], "frame": 0, @@ -911,7 +911,7 @@ def test_api_v1_lambda_functions_create_wrong_id_function(self): self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) - def test_api_v1_lambda_functions_create_wrong_id_task(self): + def test_api_v2_lambda_functions_create_wrong_id_task(self): data = { "task": 12345, "frame": 0, @@ -925,7 +925,7 @@ def test_api_v1_lambda_functions_create_wrong_id_task(self): @skip("Fail: expected result != actual result, issue #2770") - def test_api_v1_lambda_functions_create_detector_wrong_id_frame(self): + def test_api_v2_lambda_functions_create_detector_wrong_id_frame(self): data = { "task": self.main_task["id"], "frame": 12345, @@ -939,7 +939,7 @@ def test_api_v1_lambda_functions_create_detector_wrong_id_frame(self): @skip("Fail: add mock and expected result != actual result") - def test_api_v1_lambda_functions_create_two_functions(self): + def test_api_v2_lambda_functions_create_two_functions(self): data = { "task": self.main_task["id"], "frame": 0, @@ -953,7 +953,7 @@ def test_api_v1_lambda_functions_create_two_functions(self): self.assertEqual(response.status_code, status.HTTP_409_CONFLICT) - def test_api_v1_lambda_functions_create_function_is_not_ready(self): + def test_api_v2_lambda_functions_create_function_is_not_ready(self): data = { "task": self.main_task["id"], "frame": 0, diff --git a/utils/cli/cli.py b/utils/cli/cli.py index 52f60ee1e4bc..9b4183b9b827 100755 --- a/utils/cli/cli.py +++ b/utils/cli/cli.py @@ -5,7 +5,7 @@ import requests import sys from http.client import HTTPConnection -from core.core import CLI, CVAT_API_V1 +from core.core import CLI, CVAT_API_V2 from core.definition import parser log = logging.getLogger(__name__) @@ -32,7 +32,7 @@ def main(): args = parser.parse_args() config_log(args.loglevel) with requests.Session() as session: - api = CVAT_API_V1('%s:%s' % (args.server_host, args.server_port), args.https) + api = CVAT_API_V2('%s:%s' % (args.server_host, args.server_port), args.https) cli = CLI(session, api, args.auth) try: actions[args.action](cli, **args.__dict__) diff --git a/utils/cli/core/__init__.py b/utils/cli/core/__init__.py index c5319fc62bc7..c97e610a4396 100644 --- a/utils/cli/core/__init__.py +++ b/utils/cli/core/__init__.py @@ -1,3 +1,3 @@ # SPDX-License-Identifier: MIT from .definition import parser, ResourceType # noqa -from .core import CLI, CVAT_API_V1 # noqa +from .core import CLI, CVAT_API_V2 # noqa diff --git a/utils/cli/core/core.py b/utils/cli/core/core.py index 43e349299f23..c2c0d3bd7170 100644 --- a/utils/cli/core/core.py +++ b/utils/cli/core/core.py @@ -1,4 +1,4 @@ -# Copyright (C) 2020-2021 Intel Corporation +# Copyright (C) 2020-2022 Intel Corporation # # SPDX-License-Identifier: MIT @@ -269,7 +269,7 @@ def login(self, credentials): self.session.headers['X-CSRFToken'] = response.cookies['csrftoken'] -class CVAT_API_V1(): +class CVAT_API_V2(): """ Build parameterized API URLs """ def __init__(self, host, https=False): diff --git a/utils/cli/tests/test_cli.py b/utils/cli/tests/test_cli.py index 1f1ca3309710..84698c042d56 100644 --- a/utils/cli/tests/test_cli.py +++ b/utils/cli/tests/test_cli.py @@ -1,4 +1,4 @@ -# Copyright (C) 2020 Intel Corporation +# Copyright (C) 2020-2022 Intel Corporation # # SPDX-License-Identifier: MIT @@ -14,7 +14,7 @@ from cvat.apps.engine.tests.test_rest_api import (create_db_users, generate_image_file) -from utils.cli.core import CLI, CVAT_API_V1, ResourceType +from utils.cli.core import CLI, CVAT_API_V2, ResourceType class TestCLI(APITestCase): @@ -22,7 +22,7 @@ class TestCLI(APITestCase): def setUp(self, mock_stdout): self.client = RequestsClient() self.credentials = ('admin', 'admin') - self.api = CVAT_API_V1('testserver') + self.api = CVAT_API_V2('testserver') self.cli = CLI(self.client, self.api, self.credentials) self.taskname = 'test_task' self.cli.tasks_create(self.taskname,