|
15 | 15 | """Define API Subscriptions.""" |
16 | 16 |
|
17 | 17 | from gcloud.exceptions import NotFound |
| 18 | +from gcloud.pubsub.message import Message |
| 19 | +from gcloud.pubsub.topic import Topic |
18 | 20 |
|
19 | 21 |
|
20 | 22 | class Subscription(object): |
@@ -43,6 +45,37 @@ def __init__(self, name, topic, ack_deadline=None, push_endpoint=None): |
43 | 45 | self.ack_deadline = ack_deadline |
44 | 46 | self.push_endpoint = push_endpoint |
45 | 47 |
|
| 48 | + @classmethod |
| 49 | + def from_api_repr(cls, resource, connection=None, topics=None): |
| 50 | + """Factory: construct a topic given its API representation |
| 51 | +
|
| 52 | + :type resource: dict |
| 53 | + :param resource: topic resource representation returned from the API |
| 54 | +
|
| 55 | + :type connection: :class:`gcloud.pubsub.connection.Connection` or None |
| 56 | + :param connection: the connection to use. If not passed, |
| 57 | + falls back to the default inferred from the |
| 58 | + environment. |
| 59 | +
|
| 60 | + :type topics: dict or None |
| 61 | + :param topics: A mapping of topic names -> topics. If not passed, |
| 62 | + the subscription will have a newly-created topic. |
| 63 | +
|
| 64 | + :rtype: :class:`gcloud.pubsub.subscription.Subscription` |
| 65 | + """ |
| 66 | + if topics is None: |
| 67 | + topics = {} |
| 68 | + t_name = resource['topic'] |
| 69 | + topic = topics.get(t_name) |
| 70 | + if topic is None: |
| 71 | + topic = topics[t_name] = Topic.from_api_repr({'name': t_name}, |
| 72 | + connection) |
| 73 | + _, _, _, name = resource['name'].split('/') |
| 74 | + ack_deadline = resource.get('ackDeadlineSeconds') |
| 75 | + push_config = resource.get('pushConfig', {}) |
| 76 | + push_endpoint = push_config.get('pushEndpoint') |
| 77 | + return cls(name, topic, ack_deadline, push_endpoint) |
| 78 | + |
46 | 79 | @property |
47 | 80 | def path(self): |
48 | 81 | """URL path for the subscription's APIs""" |
@@ -130,18 +163,19 @@ def pull(self, return_immediately=False, max_messages=1): |
130 | 163 | :type max_messages: int |
131 | 164 | :param max_messages: the maximum number of messages to return. |
132 | 165 |
|
133 | | - :rtype: list of dict |
134 | | - :returns: sequence of mappings, each containing keys ``ackId`` (the |
135 | | - ID to be used in a subsequent call to :meth:`acknowledge`) |
136 | | - and ``message``. |
| 166 | + :rtype: list of (ack_id, message) tuples |
| 167 | + :returns: sequence of tuples: ``ack_id`` is the ID to be used in a |
| 168 | + subsequent call to :meth:`acknowledge`, and ``message`` |
| 169 | + is an instance of :class:`gcloud.pubsub.message.Message`. |
137 | 170 | """ |
138 | 171 | data = {'returnImmediately': return_immediately, |
139 | 172 | 'maxMessages': max_messages} |
140 | 173 | conn = self.topic.connection |
141 | 174 | response = conn.api_request(method='POST', |
142 | 175 | path='%s:pull' % self.path, |
143 | 176 | data=data) |
144 | | - return response['receivedMessages'] |
| 177 | + return [(info['ackId'], Message.from_api_repr(info['message'])) |
| 178 | + for info in response['receivedMessages']] |
145 | 179 |
|
146 | 180 | def acknowledge(self, ack_ids): |
147 | 181 | """API call: acknowledge retrieved messages for the subscription. |
|
0 commit comments