Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: resource tags in dataset #2090

Merged
merged 24 commits into from
Jan 14, 2025
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
66e09af
feat: resource tags in dataset
keunsoopark Dec 19, 2024
120abc8
fix: fix unittets
keunsoopark Dec 19, 2024
3d03e73
Delete dataset/pyvenv.cfg
Linchin Dec 20, 2024
c56d005
Update google/cloud/bigquery/dataset.py
keunsoopark Dec 23, 2024
d26539f
Update google/cloud/bigquery/dataset.py
keunsoopark Dec 23, 2024
c647485
added system tests & fix unittest for none
keunsoopark Dec 23, 2024
3d317d1
add missing assert
keunsoopark Dec 23, 2024
359a9e1
remove venv
keunsoopark Dec 23, 2024
32ce734
Merge branch 'main' into feat/resource_tags_in_dataset
Linchin Jan 2, 2025
ae83228
Merge branch 'main' into feat/resource_tags_in_dataset
Linchin Jan 2, 2025
a780412
Merge branch 'main' into feat/resource_tags_in_dataset
Linchin Jan 3, 2025
ddb3bf6
include resourcemanager in noxfile.py
keunsoopark Jan 7, 2025
d38e99a
Merge branch 'main' into feat/resource_tags_in_dataset
keunsoopark Jan 7, 2025
14e3e47
fix fixture for tag keys
keunsoopark Jan 8, 2025
8c48758
register tags before using in tests
keunsoopark Jan 8, 2025
5a22c33
Merge branch 'main' into feat/resource_tags_in_dataset
keunsoopark Jan 9, 2025
34e4857
Merge branch 'main' into feat/resource_tags_in_dataset
keunsoopark Jan 9, 2025
7e75599
handle alreadyexist error
keunsoopark Jan 9, 2025
6883dc2
Merge branch 'main' into feat/resource_tags_in_dataset
Linchin Jan 10, 2025
dd823a7
fix: tag keys & values creation & deletion
keunsoopark Jan 10, 2025
eb85e24
fix comment
keunsoopark Jan 10, 2025
233f276
make tag keys unique
keunsoopark Jan 14, 2025
fed4570
remove unused import
keunsoopark Jan 14, 2025
3fd848b
Merge branch 'main' into feat/resource_tags_in_dataset
Linchin Jan 14, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions google/cloud/bigquery/dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,7 @@ class Dataset(object):
"storage_billing_model": "storageBillingModel",
"max_time_travel_hours": "maxTimeTravelHours",
"default_rounding_mode": "defaultRoundingMode",
"resource_tags": "resourceTags",
}

def __init__(self, dataset_ref) -> None:
Expand Down Expand Up @@ -801,6 +802,26 @@ def labels(self, value):
raise ValueError("Pass a dict")
self._properties["labels"] = value

@property
def resource_tags(self):
"""Dict[str, str]: Resource tags of the dataset.

This method always returns a dict. To change a dataset's resource tags,
modify the dict, then call
:meth:`google.cloud.bigquery.client.Client.update_dataset`. To delete
a resource tag, set its value to :data:`None` before updating.
keunsoopark marked this conversation as resolved.
Show resolved Hide resolved

Raises:
ValueError: for invalid value types.
"""
return self._properties.setdefault("resourceTags", {})

@resource_tags.setter
def resource_tags(self, value):
if not isinstance(value, dict):
keunsoopark marked this conversation as resolved.
Show resolved Hide resolved
raise ValueError("Pass a dict")
self._properties["resourceTags"] = value

@property
def default_encryption_configuration(self):
"""google.cloud.bigquery.encryption_configuration.EncryptionConfiguration: Custom
Expand Down
6 changes: 6 additions & 0 deletions tests/unit/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -2028,6 +2028,7 @@ def test_update_dataset(self):
LABELS = {"priority": "high"}
ACCESS = [{"role": "OWNER", "userByEmail": "phred@example.com"}]
EXP = 17
RESOURCE_TAGS = {"123456789012/key": "value"}
RESOURCE = {
"datasetReference": {"projectId": self.PROJECT, "datasetId": self.DS_ID},
"etag": "etag",
Expand All @@ -2037,6 +2038,7 @@ def test_update_dataset(self):
"defaultTableExpirationMs": EXP,
"labels": LABELS,
"access": ACCESS,
"resourceTags": RESOURCE_TAGS,
}
creds = _make_credentials()
client = self._make_one(project=self.PROJECT, credentials=creds)
Expand All @@ -2048,12 +2050,14 @@ def test_update_dataset(self):
ds.default_table_expiration_ms = EXP
ds.labels = LABELS
ds.access_entries = [AccessEntry("OWNER", "userByEmail", "phred@example.com")]
ds.resource_tags = RESOURCE_TAGS
fields = [
"description",
"friendly_name",
"location",
"labels",
"access_entries",
"resource_tags",
]

with mock.patch(
Expand All @@ -2077,6 +2081,7 @@ def test_update_dataset(self):
"location": LOCATION,
"labels": LABELS,
"access": ACCESS,
"resourceTags": RESOURCE_TAGS,
},
path="/" + PATH,
timeout=7.5,
Expand All @@ -2086,6 +2091,7 @@ def test_update_dataset(self):
self.assertEqual(ds2.location, ds.location)
self.assertEqual(ds2.labels, ds.labels)
self.assertEqual(ds2.access_entries, ds.access_entries)
self.assertEqual(ds2.resource_tags, ds.resource_tags)

# ETag becomes If-Match header.
ds._properties["etag"] = "etag"
Expand Down
5 changes: 5 additions & 0 deletions tests/unit/test_create_dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ def test_create_dataset_w_attrs(client, PROJECT, DS_ID):
"tableId": "northern-hemisphere",
}
DEFAULT_ROUNDING_MODE = "ROUND_HALF_EVEN"
RESOURCE_TAGS = {"123456789012/foo": "bar"}
RESOURCE = {
"datasetReference": {"projectId": PROJECT, "datasetId": DS_ID},
"etag": "etag",
Expand All @@ -76,6 +77,7 @@ def test_create_dataset_w_attrs(client, PROJECT, DS_ID):
"labels": LABELS,
"access": [{"role": "OWNER", "userByEmail": USER_EMAIL}, {"view": VIEW}],
"defaultRoundingMode": DEFAULT_ROUNDING_MODE,
"resourceTags": RESOURCE_TAGS,
}
conn = client._connection = make_connection(RESOURCE)
entries = [
Expand All @@ -91,6 +93,7 @@ def test_create_dataset_w_attrs(client, PROJECT, DS_ID):
before.default_table_expiration_ms = 3600
before.location = LOCATION
before.labels = LABELS
before.resource_tags = RESOURCE_TAGS
before.default_rounding_mode = DEFAULT_ROUNDING_MODE
after = client.create_dataset(before)
assert after.dataset_id == DS_ID
Expand All @@ -103,6 +106,7 @@ def test_create_dataset_w_attrs(client, PROJECT, DS_ID):
assert after.default_table_expiration_ms == 3600
assert after.labels == LABELS
assert after.default_rounding_mode == DEFAULT_ROUNDING_MODE
assert after.resource_tags == RESOURCE_TAGS

conn.api_request.assert_called_once_with(
method="POST",
Expand All @@ -119,6 +123,7 @@ def test_create_dataset_w_attrs(client, PROJECT, DS_ID):
{"view": VIEW, "role": None},
],
"labels": LABELS,
"resourceTags": RESOURCE_TAGS,
},
timeout=DEFAULT_TIMEOUT,
)
Expand Down
20 changes: 20 additions & 0 deletions tests/unit/test_dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -894,6 +894,26 @@ def test_location_setter(self):
dataset.location = "LOCATION"
self.assertEqual(dataset.location, "LOCATION")

def test_resource_tags_update_in_place(self):
dataset = self._make_one(self.DS_REF)
tags = dataset.resource_tags
tags["123456789012/foo"] = "bar" # update in place
self.assertEqual(dataset.resource_tags, {"123456789012/foo": "bar"})

def test_resource_tags_setter(self):
dataset = self._make_one(self.DS_REF)
dataset.resource_tags = {"123456789012/foo": "bar"}
self.assertEqual(dataset.resource_tags, {"123456789012/foo": "bar"})

def test_resource_tags_setter_bad_value(self):
dataset = self._make_one(self.DS_REF)
with self.assertRaises(ValueError):
dataset.resource_tags = None

def test_resource_tags_getter_missing_value(self):
dataset = self._make_one(self.DS_REF)
self.assertEqual(dataset.resource_tags, {})

def test_labels_update_in_place(self):
dataset = self._make_one(self.DS_REF)
del dataset._properties["labels"] # don't start w/ existing dict
Expand Down