Skip to content

Commit de954fc

Browse files
committed
feat(bigquery): add dataplex_get_data_profile_scan sample to get a Dataplex data profile scan and latest results
Problem: The Dataplex documentation (https://cloud.google.com/dataplex/docs/use-data-profiling#most-recent-scan) needs a standalone, tested Python code sample demonstrating how to get a Dataplex data profile scan and latest results (region tag `dataplex_get_data_profile_scan`). Solution: - Add `get_data_profile_scan(project_id: str, location: str, data_scan_id: str) -> None` in `bigquery/data_profile_scan/dataplex_get_data_profile_scan.py` (Retrieve a Dataplex DataScan resource with DataScanView.FULL to inspect its configuration and most recent profile scan results.) - Add unit tests (`bigquery/data_profile_scan/dataplex_get_data_profile_scan_test.py`) covering both the success path and API error handling (`GoogleAPICallError`)
1 parent 186be98 commit de954fc

5 files changed

Lines changed: 169 additions & 0 deletions

File tree

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# Copyright 2026 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
# [START dataplex_get_data_profile_scan]
16+
import sys
17+
18+
from google.api_core import exceptions
19+
from google.cloud import dataplex_v1
20+
21+
22+
def get_data_profile_scan(
23+
project_id: str,
24+
location: str,
25+
data_scan_id: str,
26+
) -> None:
27+
"""Retrieves a Dataplex data profile scan and its latest profile results.
28+
29+
Args:
30+
project_id: Google Cloud project ID (for example, 'example-project').
31+
location: Google Cloud region where the data scan resides
32+
(for example, 'us-central1').
33+
data_scan_id: Dataplex data profile scan ID
34+
(for example, 'example-profile-scan').
35+
"""
36+
client = dataplex_v1.DataScanServiceClient()
37+
scan_name = f"projects/{project_id}/locations/{location}/dataScans/{data_scan_id}"
38+
# Request DataScanView.FULL so the response includes data_profile_result metrics.
39+
request = dataplex_v1.GetDataScanRequest(
40+
name=scan_name,
41+
view=dataplex_v1.GetDataScanRequest.DataScanView.FULL,
42+
)
43+
44+
try:
45+
scan = client.get_data_scan(request=request)
46+
except exceptions.NotFound as err:
47+
print(
48+
f"error: data profile scan '{data_scan_id}' not found in location "
49+
f"'{location}' for project '{project_id}': {err.message}",
50+
file=sys.stderr,
51+
)
52+
return
53+
except exceptions.GoogleAPICallError as err:
54+
print(
55+
f"error: failed to retrieve data profile scan '{data_scan_id}' in location "
56+
f"'{location}' for project '{project_id}': {err.message}",
57+
file=sys.stderr,
58+
)
59+
return
60+
61+
row_count = scan.data_profile_result.row_count
62+
print(f"Resource ID: {scan.name}")
63+
print(f"Data Resource: {scan.data.resource}")
64+
print(f"Row Count: {row_count}")
65+
print(f"Scan State: {scan.state.name}")
66+
67+
68+
# [END dataplex_get_data_profile_scan]
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# Copyright 2026 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
from unittest import mock
16+
17+
import dataplex_get_data_profile_scan
18+
from google.api_core import exceptions
19+
import pytest
20+
21+
22+
def test_get_data_profile_scan_success(
23+
monkeypatch: pytest.MonkeyPatch,
24+
capsys: pytest.CaptureFixture[str],
25+
) -> None:
26+
mock_client = mock.MagicMock()
27+
mock_scan = mock.MagicMock()
28+
mock_scan.name = (
29+
"projects/example-project/locations/us-central1/dataScans/example-profile-scan"
30+
)
31+
mock_scan.data.resource = "//bigquery.googleapis.com/projects/bigquery-public-data/datasets/samples/tables/shakespeare"
32+
mock_scan.data_profile_result.row_count = 164656
33+
mock_scan.state.name = "ACTIVE"
34+
mock_client.get_data_scan.return_value = mock_scan
35+
monkeypatch.setattr(
36+
dataplex_get_data_profile_scan.dataplex_v1,
37+
"DataScanServiceClient",
38+
lambda: mock_client,
39+
)
40+
41+
dataplex_get_data_profile_scan.get_data_profile_scan(
42+
project_id="example-project",
43+
location="us-central1",
44+
data_scan_id="example-profile-scan",
45+
)
46+
47+
captured = capsys.readouterr()
48+
assert (
49+
"Resource ID: projects/example-project/locations/us-central1/dataScans/example-profile-scan"
50+
in captured.out
51+
)
52+
assert "Row Count: 164656" in captured.out
53+
assert "Scan State: ACTIVE" in captured.out
54+
55+
56+
def test_get_data_profile_scan_error(
57+
monkeypatch: pytest.MonkeyPatch,
58+
capsys: pytest.CaptureFixture[str],
59+
) -> None:
60+
mock_client = mock.MagicMock()
61+
mock_client.get_data_scan.side_effect = exceptions.NotFound("scan not found")
62+
monkeypatch.setattr(
63+
dataplex_get_data_profile_scan.dataplex_v1,
64+
"DataScanServiceClient",
65+
lambda: mock_client,
66+
)
67+
68+
dataplex_get_data_profile_scan.get_data_profile_scan(
69+
project_id="example-project",
70+
location="us-central1",
71+
data_scan_id="example-profile-scan",
72+
)
73+
74+
captured = capsys.readouterr()
75+
assert "error:" in captured.err
76+
assert "example-profile-scan" in captured.err
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Copyright 2026 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
TEST_CONFIG_OVERRIDE = {
16+
# You can opt out from the test for specific Python versions.
17+
"ignored_versions": ["2.7", "3.7", "3.8", "3.9", "3.10", "3.11"],
18+
# Enforce type hints on new samples.
19+
"enforce_type_hints": True,
20+
"gcloud_project_env": "GOOGLE_CLOUD_PROJECT",
21+
"pip_version_override": None,
22+
"envs": {},
23+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pytest==9.0.3; python_version >= "3.10"
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
google-cloud-dataplex==2.20.0

0 commit comments

Comments
 (0)