We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Subscription.pull() fails with KeyError
Hi,

My code below fails with a KeyError coming from the library:

``` python
  sub = Subscription(SUBSCRIPTION_NAME, Topic(INCOMING_TOPIC_NAME))

  while True:
    try:
      msgs = sub.pull()
      ...
    except:
      msg = 'poll %s: %s' % (SUBSCRIPTION_NAME, traceback.format_exc())
      print msg
```

Fails with the message:

```
poll extractors: Traceback (most recent call last):
  File "main.py", line 46, in main
    msgs = sub.pull()
  File "/usr/local/lib/python2.7/dist-packages/gcloud/pubsub/subscription.py", line 176, in pull
    for info in response['receivedMessages']]
KeyError: 'receivedMessages'
```

This seems like a bug on the pubsub library code.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `gcloud/pubsub/subscription.py`
Content:
```
1 # Copyright 2015 Google Inc. All rights reserved.
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 #     http://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 """Define API Subscriptions."""
16 
17 from gcloud.exceptions import NotFound
18 from gcloud.pubsub.message import Message
19 from gcloud.pubsub.topic import Topic
20 from gcloud.pubsub._implicit_environ import _require_connection
21 
22 
23 class Subscription(object):
24     """Subscriptions receive messages published to their topics.
25 
26     See:
27     https://cloud.google.com/pubsub/reference/rest/v1beta2/projects/subscriptions
28 
29     :type name: string
30     :param name: the name of the subscription
31 
32     :type topic: :class:`gcloud.pubsub.topic.Topic`
33     :param topic: the topic to which the subscription belongs..
34 
35     :type ack_deadline: int
36     :param ack_deadline: the deadline (in seconds) by which messages pulled
37                          from the back-end must be acknowledged.
38 
39     :type push_endpoint: string
40     :param push_endpoint: URL to which messages will be pushed by the back-end.
41                           If not set, the application must pull messages.
42     """
43     def __init__(self, name, topic, ack_deadline=None, push_endpoint=None):
44         self.name = name
45         self.topic = topic
46         self.ack_deadline = ack_deadline
47         self.push_endpoint = push_endpoint
48 
49     @classmethod
50     def from_api_repr(cls, resource, topics=None):
51         """Factory:  construct a topic given its API representation
52 
53         :type resource: dict
54         :param resource: topic resource representation returned from the API
55 
56         :type topics: dict or None
57         :param topics: A mapping of topic names -> topics.  If not passed,
58                        the subscription will have a newly-created topic.
59 
60         :rtype: :class:`gcloud.pubsub.subscription.Subscription`
61         """
62         if topics is None:
63             topics = {}
64         t_name = resource['topic']
65         topic = topics.get(t_name)
66         if topic is None:
67             topic = topics[t_name] = Topic.from_api_repr({'name': t_name})
68         _, _, _, name = resource['name'].split('/')
69         ack_deadline = resource.get('ackDeadlineSeconds')
70         push_config = resource.get('pushConfig', {})
71         push_endpoint = push_config.get('pushEndpoint')
72         return cls(name, topic, ack_deadline, push_endpoint)
73 
74     @property
75     def path(self):
76         """URL path for the subscription's APIs"""
77         project = self.topic.project
78         return '/projects/%s/subscriptions/%s' % (project, self.name)
79 
80     def create(self, connection=None):
81         """API call:  create the subscription via a PUT request
82 
83         See:
84         https://cloud.google.com/pubsub/reference/rest/v1beta2/projects/subscriptions/create
85 
86         :type connection: :class:`gcloud.pubsub.connection.Connection` or None
87         :param connection: the connection to use.  If not passed,
88                            falls back to the topic's connection.
89         """
90         data = {'topic': self.topic.full_name}
91 
92         if self.ack_deadline is not None:
93             data['ackDeadline'] = self.ack_deadline
94 
95         if self.push_endpoint is not None:
96             data['pushConfig'] = {'pushEndpoint': self.push_endpoint}
97 
98         connection = _require_connection(connection)
99         connection.api_request(method='PUT', path=self.path, data=data)
100 
101     def exists(self, connection=None):
102         """API call:  test existence of the subscription via a GET request
103 
104         See
105         https://cloud.google.com/pubsub/reference/rest/v1beta2/projects/subscriptions/get
106 
107         :type connection: :class:`gcloud.pubsub.connection.Connection` or None
108         :param connection: the connection to use.  If not passed,
109                            falls back to the topic's connection.
110         """
111         connection = _require_connection(connection)
112         try:
113             connection.api_request(method='GET', path=self.path)
114         except NotFound:
115             return False
116         else:
117             return True
118 
119     def reload(self, connection=None):
120         """API call:  sync local subscription configuration via a GET request
121 
122         See
123         https://cloud.google.com/pubsub/reference/rest/v1beta2/projects/subscriptions/get
124 
125         :type connection: :class:`gcloud.pubsub.connection.Connection` or None
126         :param connection: the connection to use.  If not passed,
127                            falls back to the topic's connection.
128         """
129         connection = _require_connection(connection)
130         data = connection.api_request(method='GET', path=self.path)
131         self.ack_deadline = data.get('ackDeadline')
132         push_config = data.get('pushConfig', {})
133         self.push_endpoint = push_config.get('pushEndpoint')
134 
135     def modify_push_configuration(self, push_endpoint, connection=None):
136         """API call:  update the push endpoint for the subscription.
137 
138         See:
139         https://cloud.google.com/pubsub/reference/rest/v1beta2/projects/subscriptions/modifyPushConfig
140 
141         :type push_endpoint: string
142         :param push_endpoint: URL to which messages will be pushed by the
143                               back-end.  If None, the application must pull
144                               messages.
145 
146         :type connection: :class:`gcloud.pubsub.connection.Connection` or None
147         :param connection: the connection to use.  If not passed,
148                            falls back to the topic's connection.
149         """
150         connection = _require_connection(connection)
151         data = {}
152         config = data['pushConfig'] = {}
153         if push_endpoint is not None:
154             config['pushEndpoint'] = push_endpoint
155         connection.api_request(method='POST',
156                                path='%s:modifyPushConfig' % self.path,
157                                data=data)
158         self.push_endpoint = push_endpoint
159 
160     def pull(self, return_immediately=False, max_messages=1, connection=None):
161         """API call:  retrieve messages for the subscription.
162 
163         See:
164         https://cloud.google.com/pubsub/reference/rest/v1beta2/projects/subscriptions/pull
165 
166         :type return_immediately: boolean
167         :param return_immediately: if True, the back-end returns even if no
168                                    messages are available;  if False, the API
169                                    call blocks until one or more messages are
170                                    available.
171 
172         :type max_messages: int
173         :param max_messages: the maximum number of messages to return.
174 
175         :type connection: :class:`gcloud.pubsub.connection.Connection` or None
176         :param connection: the connection to use.  If not passed,
177                            falls back to the topic's connection.
178 
179         :rtype: list of (ack_id, message) tuples
180         :returns: sequence of tuples: ``ack_id`` is the ID to be used in a
181                   subsequent call to :meth:`acknowledge`, and ``message``
182                   is an instance of :class:`gcloud.pubsub.message.Message`.
183         """
184         connection = _require_connection(connection)
185         data = {'returnImmediately': return_immediately,
186                 'maxMessages': max_messages}
187         response = connection.api_request(method='POST',
188                                           path='%s:pull' % self.path,
189                                           data=data)
190         return [(info['ackId'], Message.from_api_repr(info['message']))
191                 for info in response['receivedMessages']]
192 
193     def acknowledge(self, ack_ids, connection=None):
194         """API call:  acknowledge retrieved messages for the subscription.
195 
196         See:
197         https://cloud.google.com/pubsub/reference/rest/v1beta2/projects/subscriptions/acknowledge
198 
199         :type ack_ids: list of string
200         :param ack_ids: ack IDs of messages being acknowledged
201 
202         :type connection: :class:`gcloud.pubsub.connection.Connection` or None
203         :param connection: the connection to use.  If not passed,
204                            falls back to the topic's connection.
205         """
206         connection = _require_connection(connection)
207         data = {'ackIds': ack_ids}
208         connection.api_request(method='POST',
209                                path='%s:acknowledge' % self.path,
210                                data=data)
211 
212     def modify_ack_deadline(self, ack_id, ack_deadline, connection=None):
213         """API call:  update acknowledgement deadline for a retrieved message.
214 
215         See:
216         https://cloud.google.com/pubsub/reference/rest/v1beta2/projects/subscriptions/acknowledge
217 
218         :type ack_id: string
219         :param ack_id: ack ID of message being updated
220 
221         :type ack_deadline: int
222         :param ack_deadline: new deadline for the message, in seconds
223 
224         :type connection: :class:`gcloud.pubsub.connection.Connection` or None
225         :param connection: the connection to use.  If not passed,
226                            falls back to the topic's connection.
227         """
228         connection = _require_connection(connection)
229         data = {'ackId': ack_id, 'ackDeadlineSeconds': ack_deadline}
230         connection.api_request(method='POST',
231                                path='%s:modifyAckDeadline' % self.path,
232                                data=data)
233 
234     def delete(self, connection=None):
235         """API call:  delete the subscription via a DELETE request.
236 
237         See:
238         https://cloud.google.com/pubsub/reference/rest/v1beta2/projects/subscriptions/delete
239 
240         :type connection: :class:`gcloud.pubsub.connection.Connection` or None
241         :param connection: the connection to use.  If not passed,
242                            falls back to the topic's connection.
243         """
244         connection = _require_connection(connection)
245         connection.api_request(method='DELETE', path=self.path)
246
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/gcloud/pubsub/subscription.py b/gcloud/pubsub/subscription.py
--- a/gcloud/pubsub/subscription.py
+++ b/gcloud/pubsub/subscription.py
@@ -188,7 +188,7 @@
                                           path='%s:pull' % self.path,
                                           data=data)
         return [(info['ackId'], Message.from_api_repr(info['message']))
-                for info in response['receivedMessages']]
+                for info in response.get('receivedMessages', ())]
 
     def acknowledge(self, ack_ids, connection=None):
         """API call:  acknowledge retrieved messages for the subscription.

{"golden_diff": "diff --git a/gcloud/pubsub/subscription.py b/gcloud/pubsub/subscription.py\n--- a/gcloud/pubsub/subscription.py\n+++ b/gcloud/pubsub/subscription.py\n@@ -188,7 +188,7 @@\n                                           path='%s:pull' % self.path,\n                                           data=data)\n         return [(info['ackId'], Message.from_api_repr(info['message']))\n-                for info in response['receivedMessages']]\n+                for info in response.get('receivedMessages', ())]\n \n     def acknowledge(self, ack_ids, connection=None):\n         \"\"\"API call:  acknowledge retrieved messages for the subscription.\n", "issue": "Subscription.pull() fails with KeyError\nHi,\n\nMy code below fails with a KeyError coming from the library:\n\n``` python\n  sub = Subscription(SUBSCRIPTION_NAME, Topic(INCOMING_TOPIC_NAME))\n\n  while True:\n    try:\n      msgs = sub.pull()\n      ...\n    except:\n      msg = 'poll %s: %s' % (SUBSCRIPTION_NAME, traceback.format_exc())\n      print msg\n```\n\nFails with the message:\n\n```\npoll extractors: Traceback (most recent call last):\n  File \"main.py\", line 46, in main\n    msgs = sub.pull()\n  File \"/usr/local/lib/python2.7/dist-packages/gcloud/pubsub/subscription.py\", line 176, in pull\n    for info in response['receivedMessages']]\nKeyError: 'receivedMessages'\n```\n\nThis seems like a bug on the pubsub library code.\n\n", "before_files": [{"content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\"\"\"Define API Subscriptions.\"\"\"\n\nfrom gcloud.exceptions import NotFound\nfrom gcloud.pubsub.message import Message\nfrom gcloud.pubsub.topic import Topic\nfrom gcloud.pubsub._implicit_environ import _require_connection\n\n\nclass Subscription(object):\n    \"\"\"Subscriptions receive messages published to their topics.\n\n    See:\n    https://cloud.google.com/pubsub/reference/rest/v1beta2/projects/subscriptions\n\n    :type name: string\n    :param name: the name of the subscription\n\n    :type topic: :class:`gcloud.pubsub.topic.Topic`\n    :param topic: the topic to which the subscription belongs..\n\n    :type ack_deadline: int\n    :param ack_deadline: the deadline (in seconds) by which messages pulled\n                         from the back-end must be acknowledged.\n\n    :type push_endpoint: string\n    :param push_endpoint: URL to which messages will be pushed by the back-end.\n                          If not set, the application must pull messages.\n    \"\"\"\n    def __init__(self, name, topic, ack_deadline=None, push_endpoint=None):\n        self.name = name\n        self.topic = topic\n        self.ack_deadline = ack_deadline\n        self.push_endpoint = push_endpoint\n\n    @classmethod\n    def from_api_repr(cls, resource, topics=None):\n        \"\"\"Factory:  construct a topic given its API representation\n\n        :type resource: dict\n        :param resource: topic resource representation returned from the API\n\n        :type topics: dict or None\n        :param topics: A mapping of topic names -> topics.  If not passed,\n                       the subscription will have a newly-created topic.\n\n        :rtype: :class:`gcloud.pubsub.subscription.Subscription`\n        \"\"\"\n        if topics is None:\n            topics = {}\n        t_name = resource['topic']\n        topic = topics.get(t_name)\n        if topic is None:\n            topic = topics[t_name] = Topic.from_api_repr({'name': t_name})\n        _, _, _, name = resource['name'].split('/')\n        ack_deadline = resource.get('ackDeadlineSeconds')\n        push_config = resource.get('pushConfig', {})\n        push_endpoint = push_config.get('pushEndpoint')\n        return cls(name, topic, ack_deadline, push_endpoint)\n\n    @property\n    def path(self):\n        \"\"\"URL path for the subscription's APIs\"\"\"\n        project = self.topic.project\n        return '/projects/%s/subscriptions/%s' % (project, self.name)\n\n    def create(self, connection=None):\n        \"\"\"API call:  create the subscription via a PUT request\n\n        See:\n        https://cloud.google.com/pubsub/reference/rest/v1beta2/projects/subscriptions/create\n\n        :type connection: :class:`gcloud.pubsub.connection.Connection` or None\n        :param connection: the connection to use.  If not passed,\n                           falls back to the topic's connection.\n        \"\"\"\n        data = {'topic': self.topic.full_name}\n\n        if self.ack_deadline is not None:\n            data['ackDeadline'] = self.ack_deadline\n\n        if self.push_endpoint is not None:\n            data['pushConfig'] = {'pushEndpoint': self.push_endpoint}\n\n        connection = _require_connection(connection)\n        connection.api_request(method='PUT', path=self.path, data=data)\n\n    def exists(self, connection=None):\n        \"\"\"API call:  test existence of the subscription via a GET request\n\n        See\n        https://cloud.google.com/pubsub/reference/rest/v1beta2/projects/subscriptions/get\n\n        :type connection: :class:`gcloud.pubsub.connection.Connection` or None\n        :param connection: the connection to use.  If not passed,\n                           falls back to the topic's connection.\n        \"\"\"\n        connection = _require_connection(connection)\n        try:\n            connection.api_request(method='GET', path=self.path)\n        except NotFound:\n            return False\n        else:\n            return True\n\n    def reload(self, connection=None):\n        \"\"\"API call:  sync local subscription configuration via a GET request\n\n        See\n        https://cloud.google.com/pubsub/reference/rest/v1beta2/projects/subscriptions/get\n\n        :type connection: :class:`gcloud.pubsub.connection.Connection` or None\n        :param connection: the connection to use.  If not passed,\n                           falls back to the topic's connection.\n        \"\"\"\n        connection = _require_connection(connection)\n        data = connection.api_request(method='GET', path=self.path)\n        self.ack_deadline = data.get('ackDeadline')\n        push_config = data.get('pushConfig', {})\n        self.push_endpoint = push_config.get('pushEndpoint')\n\n    def modify_push_configuration(self, push_endpoint, connection=None):\n        \"\"\"API call:  update the push endpoint for the subscription.\n\n        See:\n        https://cloud.google.com/pubsub/reference/rest/v1beta2/projects/subscriptions/modifyPushConfig\n\n        :type push_endpoint: string\n        :param push_endpoint: URL to which messages will be pushed by the\n                              back-end.  If None, the application must pull\n                              messages.\n\n        :type connection: :class:`gcloud.pubsub.connection.Connection` or None\n        :param connection: the connection to use.  If not passed,\n                           falls back to the topic's connection.\n        \"\"\"\n        connection = _require_connection(connection)\n        data = {}\n        config = data['pushConfig'] = {}\n        if push_endpoint is not None:\n            config['pushEndpoint'] = push_endpoint\n        connection.api_request(method='POST',\n                               path='%s:modifyPushConfig' % self.path,\n                               data=data)\n        self.push_endpoint = push_endpoint\n\n    def pull(self, return_immediately=False, max_messages=1, connection=None):\n        \"\"\"API call:  retrieve messages for the subscription.\n\n        See:\n        https://cloud.google.com/pubsub/reference/rest/v1beta2/projects/subscriptions/pull\n\n        :type return_immediately: boolean\n        :param return_immediately: if True, the back-end returns even if no\n                                   messages are available;  if False, the API\n                                   call blocks until one or more messages are\n                                   available.\n\n        :type max_messages: int\n        :param max_messages: the maximum number of messages to return.\n\n        :type connection: :class:`gcloud.pubsub.connection.Connection` or None\n        :param connection: the connection to use.  If not passed,\n                           falls back to the topic's connection.\n\n        :rtype: list of (ack_id, message) tuples\n        :returns: sequence of tuples: ``ack_id`` is the ID to be used in a\n                  subsequent call to :meth:`acknowledge`, and ``message``\n                  is an instance of :class:`gcloud.pubsub.message.Message`.\n        \"\"\"\n        connection = _require_connection(connection)\n        data = {'returnImmediately': return_immediately,\n                'maxMessages': max_messages}\n        response = connection.api_request(method='POST',\n                                          path='%s:pull' % self.path,\n                                          data=data)\n        return [(info['ackId'], Message.from_api_repr(info['message']))\n                for info in response['receivedMessages']]\n\n    def acknowledge(self, ack_ids, connection=None):\n        \"\"\"API call:  acknowledge retrieved messages for the subscription.\n\n        See:\n        https://cloud.google.com/pubsub/reference/rest/v1beta2/projects/subscriptions/acknowledge\n\n        :type ack_ids: list of string\n        :param ack_ids: ack IDs of messages being acknowledged\n\n        :type connection: :class:`gcloud.pubsub.connection.Connection` or None\n        :param connection: the connection to use.  If not passed,\n                           falls back to the topic's connection.\n        \"\"\"\n        connection = _require_connection(connection)\n        data = {'ackIds': ack_ids}\n        connection.api_request(method='POST',\n                               path='%s:acknowledge' % self.path,\n                               data=data)\n\n    def modify_ack_deadline(self, ack_id, ack_deadline, connection=None):\n        \"\"\"API call:  update acknowledgement deadline for a retrieved message.\n\n        See:\n        https://cloud.google.com/pubsub/reference/rest/v1beta2/projects/subscriptions/acknowledge\n\n        :type ack_id: string\n        :param ack_id: ack ID of message being updated\n\n        :type ack_deadline: int\n        :param ack_deadline: new deadline for the message, in seconds\n\n        :type connection: :class:`gcloud.pubsub.connection.Connection` or None\n        :param connection: the connection to use.  If not passed,\n                           falls back to the topic's connection.\n        \"\"\"\n        connection = _require_connection(connection)\n        data = {'ackId': ack_id, 'ackDeadlineSeconds': ack_deadline}\n        connection.api_request(method='POST',\n                               path='%s:modifyAckDeadline' % self.path,\n                               data=data)\n\n    def delete(self, connection=None):\n        \"\"\"API call:  delete the subscription via a DELETE request.\n\n        See:\n        https://cloud.google.com/pubsub/reference/rest/v1beta2/projects/subscriptions/delete\n\n        :type connection: :class:`gcloud.pubsub.connection.Connection` or None\n        :param connection: the connection to use.  If not passed,\n                           falls back to the topic's connection.\n        \"\"\"\n        connection = _require_connection(connection)\n        connection.api_request(method='DELETE', path=self.path)\n", "path": "gcloud/pubsub/subscription.py"}], "after_files": [{"content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\"\"\"Define API Subscriptions.\"\"\"\n\nfrom gcloud.exceptions import NotFound\nfrom gcloud.pubsub.message import Message\nfrom gcloud.pubsub.topic import Topic\nfrom gcloud.pubsub._implicit_environ import _require_connection\n\n\nclass Subscription(object):\n    \"\"\"Subscriptions receive messages published to their topics.\n\n    See:\n    https://cloud.google.com/pubsub/reference/rest/v1beta2/projects/subscriptions\n\n    :type name: string\n    :param name: the name of the subscription\n\n    :type topic: :class:`gcloud.pubsub.topic.Topic`\n    :param topic: the topic to which the subscription belongs..\n\n    :type ack_deadline: int\n    :param ack_deadline: the deadline (in seconds) by which messages pulled\n                         from the back-end must be acknowledged.\n\n    :type push_endpoint: string\n    :param push_endpoint: URL to which messages will be pushed by the back-end.\n                          If not set, the application must pull messages.\n    \"\"\"\n    def __init__(self, name, topic, ack_deadline=None, push_endpoint=None):\n        self.name = name\n        self.topic = topic\n        self.ack_deadline = ack_deadline\n        self.push_endpoint = push_endpoint\n\n    @classmethod\n    def from_api_repr(cls, resource, topics=None):\n        \"\"\"Factory:  construct a topic given its API representation\n\n        :type resource: dict\n        :param resource: topic resource representation returned from the API\n\n        :type topics: dict or None\n        :param topics: A mapping of topic names -> topics.  If not passed,\n                       the subscription will have a newly-created topic.\n\n        :rtype: :class:`gcloud.pubsub.subscription.Subscription`\n        \"\"\"\n        if topics is None:\n            topics = {}\n        t_name = resource['topic']\n        topic = topics.get(t_name)\n        if topic is None:\n            topic = topics[t_name] = Topic.from_api_repr({'name': t_name})\n        _, _, _, name = resource['name'].split('/')\n        ack_deadline = resource.get('ackDeadlineSeconds')\n        push_config = resource.get('pushConfig', {})\n        push_endpoint = push_config.get('pushEndpoint')\n        return cls(name, topic, ack_deadline, push_endpoint)\n\n    @property\n    def path(self):\n        \"\"\"URL path for the subscription's APIs\"\"\"\n        project = self.topic.project\n        return '/projects/%s/subscriptions/%s' % (project, self.name)\n\n    def create(self, connection=None):\n        \"\"\"API call:  create the subscription via a PUT request\n\n        See:\n        https://cloud.google.com/pubsub/reference/rest/v1beta2/projects/subscriptions/create\n\n        :type connection: :class:`gcloud.pubsub.connection.Connection` or None\n        :param connection: the connection to use.  If not passed,\n                           falls back to the topic's connection.\n        \"\"\"\n        data = {'topic': self.topic.full_name}\n\n        if self.ack_deadline is not None:\n            data['ackDeadline'] = self.ack_deadline\n\n        if self.push_endpoint is not None:\n            data['pushConfig'] = {'pushEndpoint': self.push_endpoint}\n\n        connection = _require_connection(connection)\n        connection.api_request(method='PUT', path=self.path, data=data)\n\n    def exists(self, connection=None):\n        \"\"\"API call:  test existence of the subscription via a GET request\n\n        See\n        https://cloud.google.com/pubsub/reference/rest/v1beta2/projects/subscriptions/get\n\n        :type connection: :class:`gcloud.pubsub.connection.Connection` or None\n        :param connection: the connection to use.  If not passed,\n                           falls back to the topic's connection.\n        \"\"\"\n        connection = _require_connection(connection)\n        try:\n            connection.api_request(method='GET', path=self.path)\n        except NotFound:\n            return False\n        else:\n            return True\n\n    def reload(self, connection=None):\n        \"\"\"API call:  sync local subscription configuration via a GET request\n\n        See\n        https://cloud.google.com/pubsub/reference/rest/v1beta2/projects/subscriptions/get\n\n        :type connection: :class:`gcloud.pubsub.connection.Connection` or None\n        :param connection: the connection to use.  If not passed,\n                           falls back to the topic's connection.\n        \"\"\"\n        connection = _require_connection(connection)\n        data = connection.api_request(method='GET', path=self.path)\n        self.ack_deadline = data.get('ackDeadline')\n        push_config = data.get('pushConfig', {})\n        self.push_endpoint = push_config.get('pushEndpoint')\n\n    def modify_push_configuration(self, push_endpoint, connection=None):\n        \"\"\"API call:  update the push endpoint for the subscription.\n\n        See:\n        https://cloud.google.com/pubsub/reference/rest/v1beta2/projects/subscriptions/modifyPushConfig\n\n        :type push_endpoint: string\n        :param push_endpoint: URL to which messages will be pushed by the\n                              back-end.  If None, the application must pull\n                              messages.\n\n        :type connection: :class:`gcloud.pubsub.connection.Connection` or None\n        :param connection: the connection to use.  If not passed,\n                           falls back to the topic's connection.\n        \"\"\"\n        connection = _require_connection(connection)\n        data = {}\n        config = data['pushConfig'] = {}\n        if push_endpoint is not None:\n            config['pushEndpoint'] = push_endpoint\n        connection.api_request(method='POST',\n                               path='%s:modifyPushConfig' % self.path,\n                               data=data)\n        self.push_endpoint = push_endpoint\n\n    def pull(self, return_immediately=False, max_messages=1, connection=None):\n        \"\"\"API call:  retrieve messages for the subscription.\n\n        See:\n        https://cloud.google.com/pubsub/reference/rest/v1beta2/projects/subscriptions/pull\n\n        :type return_immediately: boolean\n        :param return_immediately: if True, the back-end returns even if no\n                                   messages are available;  if False, the API\n                                   call blocks until one or more messages are\n                                   available.\n\n        :type max_messages: int\n        :param max_messages: the maximum number of messages to return.\n\n        :type connection: :class:`gcloud.pubsub.connection.Connection` or None\n        :param connection: the connection to use.  If not passed,\n                           falls back to the topic's connection.\n\n        :rtype: list of (ack_id, message) tuples\n        :returns: sequence of tuples: ``ack_id`` is the ID to be used in a\n                  subsequent call to :meth:`acknowledge`, and ``message``\n                  is an instance of :class:`gcloud.pubsub.message.Message`.\n        \"\"\"\n        connection = _require_connection(connection)\n        data = {'returnImmediately': return_immediately,\n                'maxMessages': max_messages}\n        response = connection.api_request(method='POST',\n                                          path='%s:pull' % self.path,\n                                          data=data)\n        return [(info['ackId'], Message.from_api_repr(info['message']))\n                for info in response.get('receivedMessages', ())]\n\n    def acknowledge(self, ack_ids, connection=None):\n        \"\"\"API call:  acknowledge retrieved messages for the subscription.\n\n        See:\n        https://cloud.google.com/pubsub/reference/rest/v1beta2/projects/subscriptions/acknowledge\n\n        :type ack_ids: list of string\n        :param ack_ids: ack IDs of messages being acknowledged\n\n        :type connection: :class:`gcloud.pubsub.connection.Connection` or None\n        :param connection: the connection to use.  If not passed,\n                           falls back to the topic's connection.\n        \"\"\"\n        connection = _require_connection(connection)\n        data = {'ackIds': ack_ids}\n        connection.api_request(method='POST',\n                               path='%s:acknowledge' % self.path,\n                               data=data)\n\n    def modify_ack_deadline(self, ack_id, ack_deadline, connection=None):\n        \"\"\"API call:  update acknowledgement deadline for a retrieved message.\n\n        See:\n        https://cloud.google.com/pubsub/reference/rest/v1beta2/projects/subscriptions/acknowledge\n\n        :type ack_id: string\n        :param ack_id: ack ID of message being updated\n\n        :type ack_deadline: int\n        :param ack_deadline: new deadline for the message, in seconds\n\n        :type connection: :class:`gcloud.pubsub.connection.Connection` or None\n        :param connection: the connection to use.  If not passed,\n                           falls back to the topic's connection.\n        \"\"\"\n        connection = _require_connection(connection)\n        data = {'ackId': ack_id, 'ackDeadlineSeconds': ack_deadline}\n        connection.api_request(method='POST',\n                               path='%s:modifyAckDeadline' % self.path,\n                               data=data)\n\n    def delete(self, connection=None):\n        \"\"\"API call:  delete the subscription via a DELETE request.\n\n        See:\n        https://cloud.google.com/pubsub/reference/rest/v1beta2/projects/subscriptions/delete\n\n        :type connection: :class:`gcloud.pubsub.connection.Connection` or None\n        :param connection: the connection to use.  If not passed,\n                           falls back to the topic's connection.\n        \"\"\"\n        connection = _require_connection(connection)\n        connection.api_request(method='DELETE', path=self.path)\n", "path": "gcloud/pubsub/subscription.py"}]}