From b029bc9da885196cbbc8880dc5f0581c99c90ae4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A0=D0=BE=D0=BC=D0=B0=D0=BD=20=D0=94=D0=BE=D0=BD=D1=87?= =?UTF-8?q?=D0=B5=D0=BD=D0=BA=D0=BE?= Date: Fri, 7 Oct 2022 14:58:54 +0300 Subject: [PATCH] cvat-sdk: Fix creating tasks with non-local files (#5058) * Move the test file share contents to tests/share This way, it can be reused between tests. * cvat-sdk: Fix creating tasks with non-local files Forcing the `Content-Type` for the `upload_data` API call to `multipart/form-data` does not work, because the current logic for converting Python values to parts (`ApiClient._convert_body_to_post_params`) does not encode them in a way that Django REST Framework can understand (it JSON-encodes each part). Fortunately, we don't actually need to do that, since when we create a task with non-local files, we don't need to upload any files, and so we can just post the original JSON, so do just that. I couldn't add a test for the remote image case, because CVAT rejects all URLs with non-public IP addressses. However, I did test this case manually. --- CHANGELOG.md | 2 ++ cvat-sdk/cvat_sdk/core/proxies/tasks.py | 5 ++--- tests/docker-compose.file_share.yml | 4 ++-- .../image_case_107_1.png | Bin .../image_case_107_2.png | Bin .../image_case_107_3.png | Bin tests/python/sdk/test_tasks.py | 17 +++++++++++++++++ tests/python/shared/fixtures/init.py | 1 + 8 files changed, 24 insertions(+), 5 deletions(-) rename tests/{cypress/integration/actions_tasks3/assets/case_107 => mounted_file_share}/image_case_107_1.png (100%) rename tests/{cypress/integration/actions_tasks3/assets/case_107 => mounted_file_share}/image_case_107_2.png (100%) rename tests/{cypress/integration/actions_tasks3/assets/case_107 => mounted_file_share}/image_case_107_3.png (100%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 52938473..2a5a9362 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,8 @@ non-ascii paths while adding files from "Connected file share" (issue #4428) - Invisible label item in label constructor when label color background is white, or close to it () - Fixed cvat-core ESlint problems () +- Fixed task creation with non-local files via the SDK/CLI + () ### Security - TDB diff --git a/cvat-sdk/cvat_sdk/core/proxies/tasks.py b/cvat-sdk/cvat_sdk/core/proxies/tasks.py index b0510c78..b5ae0c57 100644 --- a/cvat-sdk/cvat_sdk/core/proxies/tasks.py +++ b/cvat-sdk/cvat_sdk/core/proxies/tasks.py @@ -77,9 +77,9 @@ class Task( if resource_type is ResourceType.LOCAL: pass # handled later elif resource_type is ResourceType.REMOTE: - data = {f"remote_files[{i}]": f for i, f in enumerate(resources)} + data["remote_files"] = resources elif resource_type is ResourceType.SHARE: - data = {f"server_files[{i}]": f for i, f in enumerate(resources)} + data["server_files"] = resources data["image_quality"] = 70 data.update( @@ -104,7 +104,6 @@ class Task( self.api.create_data( self.id, data_request=models.DataRequest(**data), - _content_type="multipart/form-data", ) elif resource_type == ResourceType.LOCAL: url = self._client.api_map.make_endpoint_url( diff --git a/tests/docker-compose.file_share.yml b/tests/docker-compose.file_share.yml index 3d00e023..e9328d0d 100644 --- a/tests/docker-compose.file_share.yml +++ b/tests/docker-compose.file_share.yml @@ -3,7 +3,7 @@ version: '3.3' services: cvat_worker_default: volumes: - - ./tests/cypress/integration/actions_tasks3/assets/case_107:/home/django/share:rw + - ./tests/mounted_file_share:/home/django/share:rw cvat_server: volumes: - - ./tests/cypress/integration/actions_tasks3/assets/case_107:/home/django/share:rw + - ./tests/mounted_file_share:/home/django/share:rw diff --git a/tests/cypress/integration/actions_tasks3/assets/case_107/image_case_107_1.png b/tests/mounted_file_share/image_case_107_1.png similarity index 100% rename from tests/cypress/integration/actions_tasks3/assets/case_107/image_case_107_1.png rename to tests/mounted_file_share/image_case_107_1.png diff --git a/tests/cypress/integration/actions_tasks3/assets/case_107/image_case_107_2.png b/tests/mounted_file_share/image_case_107_2.png similarity index 100% rename from tests/cypress/integration/actions_tasks3/assets/case_107/image_case_107_2.png rename to tests/mounted_file_share/image_case_107_2.png diff --git a/tests/cypress/integration/actions_tasks3/assets/case_107/image_case_107_3.png b/tests/mounted_file_share/image_case_107_3.png similarity index 100% rename from tests/cypress/integration/actions_tasks3/assets/case_107/image_case_107_3.png rename to tests/mounted_file_share/image_case_107_3.png diff --git a/tests/python/sdk/test_tasks.py b/tests/python/sdk/test_tasks.py index 1a926a06..5bedc107 100644 --- a/tests/python/sdk/test_tasks.py +++ b/tests/python/sdk/test_tasks.py @@ -126,6 +126,23 @@ class TestTaskUsecases: assert "100%" in pbar_out.getvalue().strip("\r").split("\r")[-1] assert self.stdout.getvalue() == "" + def test_can_create_task_with_remote_data(self): + task = self.client.tasks.create_from_data( + spec={ + "name": "test_task", + "labels": [{"name": "car"}, {"name": "person"}], + }, + resource_type=ResourceType.SHARE, + resources=["image_case_107_2.png", "image_case_107_1.png"], + # make sure string fields are transferred correctly; + # see https://github.com/opencv/cvat/issues/4962 + data_params={"sorting_method": "lexicographical"}, + ) + + assert task.size == 2 + assert task.get_frames_info()[0].name == "image_case_107_1.png" + assert self.stdout.getvalue() == "" + def test_cant_create_task_with_no_data(self): pbar_out = io.StringIO() pbar = make_pbar(file=pbar_out) diff --git a/tests/python/shared/fixtures/init.py b/tests/python/shared/fixtures/init.py index 06090bd3..cbcd7abe 100644 --- a/tests/python/shared/fixtures/init.py +++ b/tests/python/shared/fixtures/init.py @@ -30,6 +30,7 @@ DC_FILES = [ osp.join(CVAT_ROOT_DIR, dc_file) for dc_file in ( "docker-compose.dev.yml", + "tests/docker-compose.file_share.yml", "tests/docker-compose.minio.yml", "tests/docker-compose.webhook.yml", )