Skip to content

Commit f602252

Browse files
feat(storage): add get notification method (#77)
* feat(storage): add get notification method * feat(storage): address comments * feat(storage): add an example * feat(storage): remove an extra blank Co-authored-by: Frank Natividad <frankyn@users.noreply.github.com>
1 parent 4abeb1c commit f602252

File tree

4 files changed

+118
-6
lines changed

4 files changed

+118
-6
lines changed

google/cloud/storage/bucket.py

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -617,12 +617,13 @@ def blob(
617617

618618
def notification(
619619
self,
620-
topic_name,
620+
topic_name=None,
621621
topic_project=None,
622622
custom_attributes=None,
623623
event_types=None,
624624
blob_name_prefix=None,
625625
payload_format=NONE_PAYLOAD_FORMAT,
626+
notification_id=None,
626627
):
627628
"""Factory: create a notification resource for the bucket.
628629
@@ -632,12 +633,13 @@ def notification(
632633
"""
633634
return BucketNotification(
634635
self,
635-
topic_name,
636+
topic_name=topic_name,
636637
topic_project=topic_project,
637638
custom_attributes=custom_attributes,
638639
event_types=event_types,
639640
blob_name_prefix=blob_name_prefix,
640641
payload_format=payload_format,
642+
notification_id=notification_id,
641643
)
642644

643645
def exists(self, client=None, timeout=_DEFAULT_TIMEOUT):
@@ -1021,6 +1023,44 @@ def list_notifications(self, client=None, timeout=_DEFAULT_TIMEOUT):
10211023
iterator.bucket = self
10221024
return iterator
10231025

1026+
def get_notification(self, notification_id, client=None, timeout=_DEFAULT_TIMEOUT):
1027+
"""Get Pub / Sub notification for this bucket.
1028+
1029+
See:
1030+
https://cloud.google.com/storage/docs/json_api/v1/notifications/get
1031+
1032+
If :attr:`user_project` is set, bills the API request to that project.
1033+
1034+
:type notification_id: str
1035+
:param notification_id: The notification id to retrieve the notification configuration.
1036+
1037+
:type client: :class:`~google.cloud.storage.client.Client` or
1038+
``NoneType``
1039+
:param client: (optional) The client to use. If not passed, falls back
1040+
to the ``client`` stored on the current bucket.
1041+
:type timeout: float or tuple
1042+
:param timeout: (optional) The amount of time, in seconds, to wait
1043+
for the server response.
1044+
1045+
Can also be passed as a tuple (connect_timeout, read_timeout).
1046+
See :meth:`requests.Session.request` documentation for details.
1047+
1048+
:rtype: :class:`.BucketNotification`
1049+
:returns: notification instance.
1050+
1051+
Example:
1052+
Get notification using notification id.
1053+
1054+
>>> from google.cloud import storage
1055+
>>> client = storage.Client()
1056+
>>> bucket = client.get_bucket('my-bucket-name') # API request.
1057+
>>> notification = bucket.get_notification(notification_id='id') # API request.
1058+
1059+
"""
1060+
notification = self.notification(notification_id=notification_id)
1061+
notification.reload(client=client, timeout=timeout)
1062+
return notification
1063+
10241064
def delete(self, force=False, client=None, timeout=_DEFAULT_TIMEOUT):
10251065
"""Delete this bucket.
10261066

google/cloud/storage/notification.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ class BucketNotification(object):
5050
:param bucket: Bucket to which the notification is bound.
5151
5252
:type topic_name: str
53-
:param topic_name: Topic name to which notifications are published.
53+
:param topic_name:
54+
(Optional) Topic name to which notifications are published.
5455
5556
:type topic_project: str
5657
:param topic_project:
@@ -63,7 +64,7 @@ class BucketNotification(object):
6364
6465
:type event_types: list(str)
6566
:param event_types:
66-
(Optional) event types for which notificatin events are published.
67+
(Optional) event types for which notification events are published.
6768
6869
:type blob_name_prefix: str
6970
:param blob_name_prefix:
@@ -73,17 +74,22 @@ class BucketNotification(object):
7374
:type payload_format: str
7475
:param payload_format:
7576
(Optional) format of payload for notification events.
77+
78+
:type notification_id: str
79+
:param notification_id:
80+
(Optional) The ID of the notification.
7681
"""
7782

7883
def __init__(
7984
self,
8085
bucket,
81-
topic_name,
86+
topic_name=None,
8287
topic_project=None,
8388
custom_attributes=None,
8489
event_types=None,
8590
blob_name_prefix=None,
8691
payload_format=NONE_PAYLOAD_FORMAT,
92+
notification_id=None,
8793
):
8894
self._bucket = bucket
8995
self._topic_name = topic_name
@@ -107,6 +113,9 @@ def __init__(
107113
if blob_name_prefix is not None:
108114
self._properties["object_name_prefix"] = blob_name_prefix
109115

116+
if notification_id is not None:
117+
self._properties["id"] = notification_id
118+
110119
self._properties["payload_format"] = payload_format
111120

112121
@classmethod

tests/system/test_system.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1433,6 +1433,7 @@ def test_notification_minimal(self):
14331433
bucket = retry_429_503(Config.CLIENT.create_bucket)(new_bucket_name)
14341434
self.case_buckets_to_delete.append(new_bucket_name)
14351435
self.assertEqual(list(bucket.list_notifications()), [])
1436+
14361437
notification = bucket.notification(self.TOPIC_NAME)
14371438
retry_429_503(notification.create)()
14381439
try:
@@ -1449,7 +1450,7 @@ def test_notification_explicit(self):
14491450
bucket = retry_429_503(Config.CLIENT.create_bucket)(new_bucket_name)
14501451
self.case_buckets_to_delete.append(new_bucket_name)
14511452
notification = bucket.notification(
1452-
self.TOPIC_NAME,
1453+
topic_name=self.TOPIC_NAME,
14531454
custom_attributes=self.CUSTOM_ATTRIBUTES,
14541455
event_types=self.event_types(),
14551456
blob_name_prefix=self.BLOB_NAME_PREFIX,
@@ -1463,6 +1464,7 @@ def test_notification_explicit(self):
14631464
self.assertEqual(notification.event_types, self.event_types())
14641465
self.assertEqual(notification.blob_name_prefix, self.BLOB_NAME_PREFIX)
14651466
self.assertEqual(notification.payload_format, self.payload_format())
1467+
14661468
finally:
14671469
notification.delete()
14681470

@@ -1486,6 +1488,28 @@ def test_notification_w_user_project(self):
14861488
finally:
14871489
notification.delete()
14881490

1491+
def test_get_notification(self):
1492+
new_bucket_name = "get-notification" + unique_resource_id("-")
1493+
bucket = retry_429_503(Config.CLIENT.create_bucket)(new_bucket_name)
1494+
self.case_buckets_to_delete.append(new_bucket_name)
1495+
1496+
notification = bucket.notification(
1497+
topic_name=self.TOPIC_NAME,
1498+
custom_attributes=self.CUSTOM_ATTRIBUTES,
1499+
payload_format=self.payload_format(),
1500+
)
1501+
retry_429_503(notification.create)()
1502+
try:
1503+
self.assertTrue(notification.exists())
1504+
self.assertIsNotNone(notification.notification_id)
1505+
notification_id = notification.notification_id
1506+
notification = bucket.get_notification(notification_id)
1507+
self.assertEqual(notification.notification_id, notification_id)
1508+
self.assertEqual(notification.custom_attributes, self.CUSTOM_ATTRIBUTES)
1509+
self.assertEqual(notification.payload_format, self.payload_format())
1510+
finally:
1511+
notification.delete()
1512+
14891513

14901514
class TestAnonymousClient(unittest.TestCase):
14911515

tests/unit/test_bucket.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -826,6 +826,45 @@ def test_list_notifications(self):
826826
notification.payload_format, resource.get("payload_format")
827827
)
828828

829+
def test_get_notification(self):
830+
from google.cloud.storage.notification import _TOPIC_REF_FMT
831+
from google.cloud.storage.notification import JSON_API_V1_PAYLOAD_FORMAT
832+
833+
NAME = "name"
834+
ETAG = "FACECABB"
835+
NOTIFICATION_ID = "1"
836+
SELF_LINK = "https://example.com/notification/1"
837+
resources = {
838+
"topic": _TOPIC_REF_FMT.format("my-project-123", "topic-1"),
839+
"id": NOTIFICATION_ID,
840+
"etag": ETAG,
841+
"selfLink": SELF_LINK,
842+
"payload_format": JSON_API_V1_PAYLOAD_FORMAT,
843+
}
844+
845+
connection = _make_connection(resources)
846+
client = _Client(connection, project="my-project-123")
847+
bucket = self._make_one(client=client, name=NAME)
848+
notification = bucket.get_notification(notification_id=NOTIFICATION_ID)
849+
850+
self.assertEqual(notification.notification_id, NOTIFICATION_ID)
851+
self.assertEqual(notification.etag, ETAG)
852+
self.assertEqual(notification.self_link, SELF_LINK)
853+
self.assertIsNone(notification.custom_attributes)
854+
self.assertIsNone(notification.event_types)
855+
self.assertIsNone(notification.blob_name_prefix)
856+
self.assertEqual(notification.payload_format, JSON_API_V1_PAYLOAD_FORMAT)
857+
858+
def test_get_notification_miss(self):
859+
from google.cloud.exceptions import NotFound
860+
861+
response = NotFound("testing")
862+
connection = _make_connection(response)
863+
client = _Client(connection, project="my-project-123")
864+
bucket = self._make_one(client=client, name="name")
865+
with self.assertRaises(NotFound):
866+
bucket.get_notification(notification_id="1")
867+
829868
def test_delete_miss(self):
830869
from google.cloud.exceptions import NotFound
831870

0 commit comments

Comments
 (0)