From ce061f6fe71eb9eb7107bbb10b6f6537b21f0e83 Mon Sep 17 00:00:00 2001 From: Jennifer Davis Date: Tue, 3 Nov 2026 02:43:57 +0000 Subject: [PATCH] feat(bigquery): add dataplex_delete_data_profile_scan sample to delete a Dataplex data profile scan Problem: The Dataplex documentation (https://cloud.google.com/dataplex/docs/use-data-profiling#delete-scans) needs a standalone, tested Python code sample demonstrating how to delete a Dataplex data profile scan (region tag `dataplex_delete_data_profile_scan`). Solution: - Add `delete_data_profile_scan(project_id: str, location: str, data_scan_id: str) -> None` in `bigquery/data_profile_scan/dataplex_delete_data_profile_scan.py` (Delete a Dataplex data profile scan resource using DataScanServiceClient.delete_data_scan and await completion.) - Add unit tests (`bigquery/data_profile_scan/dataplex_delete_data_profile_scan_test.py`) covering both the success path and API error handling (`GoogleAPICallError`) --- .../dataplex_delete_data_profile_scan.py | 65 +++++++++++++++++ .../dataplex_delete_data_profile_scan_test.py | 72 +++++++++++++++++++ bigquery/data_profile_scan/noxfile_config.py | 23 ++++++ .../data_profile_scan/requirements-test.txt | 1 + bigquery/data_profile_scan/requirements.txt | 1 + 5 files changed, 162 insertions(+) create mode 100644 bigquery/data_profile_scan/dataplex_delete_data_profile_scan.py create mode 100644 bigquery/data_profile_scan/dataplex_delete_data_profile_scan_test.py create mode 100644 bigquery/data_profile_scan/noxfile_config.py create mode 100644 bigquery/data_profile_scan/requirements-test.txt create mode 100644 bigquery/data_profile_scan/requirements.txt diff --git a/bigquery/data_profile_scan/dataplex_delete_data_profile_scan.py b/bigquery/data_profile_scan/dataplex_delete_data_profile_scan.py new file mode 100644 index 00000000000..6e9ba19b76b --- /dev/null +++ b/bigquery/data_profile_scan/dataplex_delete_data_profile_scan.py @@ -0,0 +1,65 @@ +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# [START dataplex_delete_data_profile_scan] +import sys + +from google.api_core import exceptions +from google.cloud import dataplex_v1 + + +def delete_data_profile_scan( + project_id: str, + location: str, + data_scan_id: str, +) -> None: + """Deletes a Dataplex data profile scan resource. + + Args: + project_id: Google Cloud project ID (for example, 'example-project'). + location: Google Cloud region where the data scan resides + (for example, 'us-central1'). + data_scan_id: Dataplex data profile scan ID to delete + (for example, 'example-profile-scan'). + """ + client = dataplex_v1.DataScanServiceClient() + scan_name = f"projects/{project_id}/locations/{location}/dataScans/{data_scan_id}" + # Deleting a DataScan is a long-running operation that removes the scan configuration. + request = dataplex_v1.DeleteDataScanRequest(name=scan_name) + + try: + print(f"Deleting Dataplex data profile scan: {scan_name}") + operation = client.delete_data_scan(request=request) + operation.result() + except exceptions.NotFound as err: + print( + f"error: data profile scan '{data_scan_id}' not found in location " + f"'{location}' for project '{project_id}': {err.message}", + file=sys.stderr, + ) + return + except exceptions.GoogleAPICallError as err: + print( + f"error: failed to delete data profile scan '{data_scan_id}' in location " + f"'{location}' for project '{project_id}': {err.message}", + file=sys.stderr, + ) + return + + print(f"Resource ID: {scan_name}") + print("Deleted: True") + print(f"Operation Completed: {operation.done()}") + + +# [END dataplex_delete_data_profile_scan] diff --git a/bigquery/data_profile_scan/dataplex_delete_data_profile_scan_test.py b/bigquery/data_profile_scan/dataplex_delete_data_profile_scan_test.py new file mode 100644 index 00000000000..f05cf4bba07 --- /dev/null +++ b/bigquery/data_profile_scan/dataplex_delete_data_profile_scan_test.py @@ -0,0 +1,72 @@ +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from unittest import mock + +import dataplex_delete_data_profile_scan +from google.api_core import exceptions +import pytest + + +def test_delete_data_profile_scan_success( + monkeypatch: pytest.MonkeyPatch, + capsys: pytest.CaptureFixture[str], +) -> None: + mock_client = mock.MagicMock() + mock_op = mock.MagicMock() + mock_op.result.return_value = None + mock_op.done.return_value = True + mock_client.delete_data_scan.return_value = mock_op + monkeypatch.setattr( + dataplex_delete_data_profile_scan.dataplex_v1, + "DataScanServiceClient", + lambda: mock_client, + ) + + dataplex_delete_data_profile_scan.delete_data_profile_scan( + project_id="example-project", + location="us-central1", + data_scan_id="example-profile-scan", + ) + + captured = capsys.readouterr() + assert ( + "Resource ID: projects/example-project/locations/us-central1/dataScans/example-profile-scan" + in captured.out + ) + assert "Deleted: True" in captured.out + assert "Operation Completed: True" in captured.out + + +def test_delete_data_profile_scan_error( + monkeypatch: pytest.MonkeyPatch, + capsys: pytest.CaptureFixture[str], +) -> None: + mock_client = mock.MagicMock() + mock_client.delete_data_scan.side_effect = exceptions.NotFound("scan not found") + monkeypatch.setattr( + dataplex_delete_data_profile_scan.dataplex_v1, + "DataScanServiceClient", + lambda: mock_client, + ) + + dataplex_delete_data_profile_scan.delete_data_profile_scan( + project_id="example-project", + location="us-central1", + data_scan_id="example-profile-scan", + ) + + captured = capsys.readouterr() + assert "error:" in captured.err + assert "example-profile-scan" in captured.err diff --git a/bigquery/data_profile_scan/noxfile_config.py b/bigquery/data_profile_scan/noxfile_config.py new file mode 100644 index 00000000000..63902aa8c7f --- /dev/null +++ b/bigquery/data_profile_scan/noxfile_config.py @@ -0,0 +1,23 @@ +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +TEST_CONFIG_OVERRIDE = { + # You can opt out from the test for specific Python versions. + "ignored_versions": ["2.7", "3.7", "3.8", "3.9", "3.10", "3.11"], + # Enforce type hints on new samples. + "enforce_type_hints": True, + "gcloud_project_env": "GOOGLE_CLOUD_PROJECT", + "pip_version_override": None, + "envs": {}, +} diff --git a/bigquery/data_profile_scan/requirements-test.txt b/bigquery/data_profile_scan/requirements-test.txt new file mode 100644 index 00000000000..c9e154ba440 --- /dev/null +++ b/bigquery/data_profile_scan/requirements-test.txt @@ -0,0 +1 @@ +pytest==9.0.3; python_version >= "3.10" diff --git a/bigquery/data_profile_scan/requirements.txt b/bigquery/data_profile_scan/requirements.txt new file mode 100644 index 00000000000..07ce35f2031 --- /dev/null +++ b/bigquery/data_profile_scan/requirements.txt @@ -0,0 +1 @@ +google-cloud-dataplex==2.20.0