diff --git a/cognite/client/_api/vision.py b/cognite/client/_api/vision.py index 70cb142b21..caa51ad1a5 100644 --- a/cognite/client/_api/vision.py +++ b/cognite/client/_api/vision.py @@ -18,6 +18,16 @@ class VisionAPI(APIClient): _RESOURCE_PATH = "/context/vision" + @staticmethod + def _deprecation_warning() -> None: + warnings.warn( + "The Vision API will be removed in a future version of the SDK. " + "Please migrate to the recommended alternative. " + "Read more at: https://docs.cognite.com/cdf/deprecated#deprecated-and-retired-features", + UserWarning, + stacklevel=3, + ) + @staticmethod def _process_file_ids(ids: list[int] | int | None, external_ids: list[str] | str | None) -> list: """ @@ -90,6 +100,7 @@ def extract( >>> # Save predictions in CDF using Annotations API: >>> extract_job.save_predictions() """ + VisionAPI._deprecation_warning() # Sanitize input(s) assert_type(features, "features", [VisionFeature, list], allow_none=False) if isinstance(features, list): @@ -136,6 +147,7 @@ def get_extract_job(self, job_id: int) -> VisionExtractJob: ... predictions = item.predictions ... # do something with the predictions """ + VisionAPI._deprecation_warning() job = VisionExtractJob( job_id=job_id, status_path=f"{self._RESOURCE_PATH}/extract/", diff --git a/docs/source/contextualization.rst b/docs/source/contextualization.rst index 4cc0108a6d..b07b996c69 100644 --- a/docs/source/contextualization.rst +++ b/docs/source/contextualization.rst @@ -43,8 +43,11 @@ Convert to an interactive SVG where the provided annotations are highlighted .. automethod:: cognite.client._api.diagrams.DiagramsAPI.convert -Vision ------- +Vision (deprecated) +------------------- + +.. warning:: + The Vision API will be removed in a future version of the SDK. Please migrate to the recommended alternative. See the :doc:`deprecated` page for details. The Vision API enable extraction of information from imagery data based on their visual content. For example, you can can extract features such as text, asset tags or industrial objects from images using this service. diff --git a/docs/source/deprecated.rst b/docs/source/deprecated.rst index 563d6d33a6..906bf015d5 100644 --- a/docs/source/deprecated.rst +++ b/docs/source/deprecated.rst @@ -1,6 +1,18 @@ Deprecated ========== +Vision +------ +Start vision extract job +^^^^^^^^^^^^^^^^^^^^^^^^ +.. automethod:: cognite.client._api.vision.VisionAPI.extract + :noindex: + +Retrieve vision extract job +^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. automethod:: cognite.client._api.vision.VisionAPI.get_extract_job + :noindex: + Templates --------- Create Template groups diff --git a/tests/tests_unit/test_api/test_vision_extract.py b/tests/tests_unit/test_api/test_vision_extract.py index 2aea07d771..3f33223c00 100644 --- a/tests/tests_unit/test_api/test_vision_extract.py +++ b/tests/tests_unit/test_api/test_vision_extract.py @@ -166,7 +166,7 @@ def test_extract_unit( error_message: str | None, cognite_client: CogniteClient, ) -> None: - VAPI = cognite_client.vision + vision_api = cognite_client.vision file_ids = [1, 2, 3] file_external_ids = [] if error_message is not None: @@ -174,13 +174,13 @@ def test_extract_unit( # GET request will not be executed due to invalid parameters in POST # thus relax the assertion requirements mock_post_extract.assert_all_requests_are_fired = False - VAPI.extract(features=features, file_ids=file_ids, file_external_ids=file_external_ids) + vision_api.extract(features=features, file_ids=file_ids, file_external_ids=file_external_ids) else: is_beta_feature: bool = len([f for f in features if f in VisionFeature.beta_features()]) > 0 error_handling = UserWarning if is_beta_feature else does_not_raise() # Job should be queued immediately after a successfully POST with error_handling: - job = VAPI.extract( + job = vision_api.extract( features=features, file_ids=file_ids, file_external_ids=file_external_ids, parameters=parameters ) assert isinstance(job, VisionExtractJob) @@ -226,16 +226,16 @@ def test_extract_unit( def test_get_extract( self, mock_post_extract: RequestsMock, mock_get_extract: RequestsMock, cognite_client: CogniteClient ) -> None: - VAPI = cognite_client.vision + vision_api = cognite_client.vision file_ids = [1, 2, 3] file_external_ids = [] - job = VAPI.extract( + job = vision_api.extract( features=VisionFeature.TEXT_DETECTION, file_ids=file_ids, file_external_ids=file_external_ids ) # retrieved job should correspond to the started job: - retrieved_job = VAPI.get_extract_job(job_id=job.job_id) + retrieved_job = vision_api.get_extract_job(job_id=job.job_id) assert isinstance(retrieved_job, VisionExtractJob) assert retrieved_job.job_id == job.job_id @@ -247,22 +247,41 @@ def test_get_extract( assert f"/{job.job_id}" in call.request.url assert 1 == num_get_requests + def test_extract_emits_deprecation_warning( + self, mock_post_extract: RequestsMock, mock_get_extract: RequestsMock, cognite_client: CogniteClient + ) -> None: + mock_get_extract.assert_all_requests_are_fired = False # only POST (extract) is called + vision_api = cognite_client.vision + with pytest.warns(UserWarning, match=r"Vision API will be removed"): + job = vision_api.extract(features=VisionFeature.TEXT_DETECTION, file_ids=[1], file_external_ids=[]) + assert isinstance(job, VisionExtractJob) + + def test_get_extract_job_emits_deprecation_warning( + self, mock_post_extract: RequestsMock, mock_get_extract: RequestsMock, cognite_client: CogniteClient + ) -> None: + mock_post_extract.assert_all_requests_are_fired = False # only GET (get_extract_job) is called + vision_api = cognite_client.vision + with pytest.warns(UserWarning, match=r"Vision API will be removed"): + job = vision_api.get_extract_job(job_id=1) + assert isinstance(job, VisionExtractJob) + assert job.job_id == 1 + def test_save_empty_predictions( self, mock_post_extract: RequestsMock, mock_get_extract_empty_predictions: RequestsMock, cognite_client: CogniteClient, ) -> None: - VAPI = cognite_client.vision + vision_api = cognite_client.vision file_ids = [1] file_external_ids = [] - job = VAPI.extract( + job = vision_api.extract( features=VisionFeature.ASSET_TAG_DETECTION, file_ids=file_ids, file_external_ids=file_external_ids ) # retrieved job should correspond to the started job: - retrieved_job = VAPI.get_extract_job(job_id=job.job_id) + retrieved_job = vision_api.get_extract_job(job_id=job.job_id) assert isinstance(retrieved_job, VisionExtractJob) assert retrieved_job.job_id == job.job_id