Skip to content

Commit 1fe6ba1

Browse files
committed
Allow 'topic' passed to 'Subscription' to be None.
In that case (representing subscriptions whose topic has been deleted), caller must pass in an explicit 'client' (which is otherwised not allowed). Addresses: #1671 (comment)
1 parent dd0774d commit 1fe6ba1

File tree

2 files changed

+272
-345
lines changed

2 files changed

+272
-345
lines changed

gcloud/pubsub/subscription.py

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,9 @@ class Subscription(object):
2929
:type name: string
3030
:param name: the name of the subscription
3131
32-
:type topic: :class:`gcloud.pubsub.topic.Topic`
33-
:param topic: the topic to which the subscription belongs..
32+
:type topic: :class:`gcloud.pubsub.topic.Topic` or ``NoneType``
33+
:param topic: the topic to which the subscription belongs; if ``None``,
34+
the subscription's topic has been deleted.
3435
3536
:type ack_deadline: int
3637
:param ack_deadline: the deadline (in seconds) by which messages pulled
@@ -39,6 +40,10 @@ class Subscription(object):
3940
:type push_endpoint: string
4041
:param push_endpoint: URL to which messages will be pushed by the back-end.
4142
If not set, the application must pull messages.
43+
44+
:type client: :class:`gcloud.pubsub.client.Client` or ``NoneType``
45+
:param client: the client to use. If not passed, falls back to the
46+
``client`` stored on the topic.
4247
"""
4348

4449
_DELETED_TOPIC_PATH = '_deleted-topic_'
@@ -48,9 +53,19 @@ class Subscription(object):
4853
https://cloud.google.com/pubsub/reference/rest/v1/projects.subscriptions#Subscription.FIELDS.topic
4954
"""
5055

51-
def __init__(self, name, topic, ack_deadline=None, push_endpoint=None):
56+
def __init__(self, name, topic=None, ack_deadline=None, push_endpoint=None,
57+
client=None):
58+
59+
if client is None and topic is None:
60+
raise TypeError("Pass only one of 'topic' or 'client'.")
61+
62+
if client is not None and topic is not None:
63+
raise TypeError("Pass only one of 'topic' or 'client'.")
64+
5265
self.name = name
5366
self.topic = topic
67+
self._client = client or topic._client
68+
self._project = self._client.project
5469
self.ack_deadline = ack_deadline
5570
self.push_endpoint = push_endpoint
5671

@@ -76,7 +91,7 @@ def from_api_repr(cls, resource, client, topics=None):
7691
topics = {}
7792
topic_path = resource['topic']
7893
if topic_path == cls._DELETED_TOPIC_PATH:
79-
topic = client.topic(name=None)
94+
topic = None
8095
else:
8196
topic = topics.get(topic_path)
8297
if topic is None:
@@ -88,13 +103,20 @@ def from_api_repr(cls, resource, client, topics=None):
88103
ack_deadline = resource.get('ackDeadlineSeconds')
89104
push_config = resource.get('pushConfig', {})
90105
push_endpoint = push_config.get('pushEndpoint')
106+
if topic is None:
107+
return cls(name, ack_deadline=ack_deadline,
108+
push_endpoint=push_endpoint, client=client)
91109
return cls(name, topic, ack_deadline, push_endpoint)
92110

111+
@property
112+
def project(self):
113+
"""Project bound to the subscription."""
114+
return self._client.project
115+
93116
@property
94117
def path(self):
95118
"""URL path for the subscription's APIs"""
96-
project = self.topic.project
97-
return '/projects/%s/subscriptions/%s' % (project, self.name)
119+
return '/projects/%s/subscriptions/%s' % (self.project, self.name)
98120

99121
def _require_client(self, client):
100122
"""Check client or verify over-ride.

0 commit comments

Comments
 (0)