We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
PubSub: add ack_id property accessor to subscriber Message class
Version: google-cloud-pubsub 0.35.4

This is a feature request to add a property accessor for ack_id in `google.cloud.pubsub_v1.subscriber.message.Message`.

Currently the `_ack_id` field is 'private', and only gets used via the `ack()` method (plus other related methods).

We find it useful to log the ack ID so that we can manually ack the ID using the Google Cloud SDK (`gcloud` command line interface). This helps us get out of situations where the message is stuck in a (virtually) infinite retry loop because of some error.

We can just access the 'private' field, but it doesn't seem very nice to have to do that.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `pubsub/google/cloud/pubsub_v1/subscriber/message.py`
Content:
```
1 # Copyright 2017, Google LLC 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 from __future__ import absolute_import
16 
17 import datetime
18 import json
19 import math
20 import time
21 
22 from google.api_core import datetime_helpers
23 from google.cloud.pubsub_v1.subscriber._protocol import requests
24 
25 
26 _MESSAGE_REPR = """\
27 Message {{
28   data: {!r}
29   attributes: {}
30 }}"""
31 
32 
33 def _indent(lines, prefix='  '):
34     """Indent some text.
35 
36     Note that this is present as ``textwrap.indent``, but not in Python 2.
37 
38     Args:
39         lines (str): The newline delimited string to be indented.
40         prefix (Optional[str]): The prefix to indent each line with. Default
41             to two spaces.
42 
43     Returns:
44         str: The newly indented content.
45     """
46     indented = []
47     for line in lines.split('\n'):
48         indented.append(prefix + line)
49     return '\n'.join(indented)
50 
51 
52 class Message(object):
53     """A representation of a single Pub/Sub message.
54 
55     The common way to interact with
56     :class:`~.pubsub_v1.subscriber.message.Message` objects is to receive
57     them in callbacks on subscriptions; most users should never have a need
58     to instantiate them by hand. (The exception to this is if you are
59     implementing a custom subclass to
60     :class:`~.pubsub_v1.subscriber._consumer.Consumer`.)
61 
62     Attributes:
63         message_id (str): The message ID. In general, you should not need
64             to use this directly.
65         data (bytes): The data in the message. Note that this will be a
66             :class:`bytes`, not a text string.
67         attributes (.ScalarMapContainer): The attributes sent along with the
68             message. See :attr:`attributes` for more information on this type.
69         publish_time (datetime): The time that this message was originally
70             published.
71     """
72 
73     def __init__(self, message, ack_id, request_queue):
74         """Construct the Message.
75 
76         .. note::
77 
78             This class should not be constructed directly; it is the
79             responsibility of :class:`BasePolicy` subclasses to do so.
80 
81         Args:
82             message (~.pubsub_v1.types.PubsubMessage): The message received
83                 from Pub/Sub.
84             ack_id (str): The ack_id received from Pub/Sub.
85             request_queue (queue.Queue): A queue provided by the policy that
86                 can accept requests; the policy is responsible for handling
87                 those requests.
88         """
89         self._message = message
90         self._ack_id = ack_id
91         self._request_queue = request_queue
92         self.message_id = message.message_id
93 
94         # The instantiation time is the time that this message
95         # was received. Tracking this provides us a way to be smart about
96         # the default lease deadline.
97         self._received_timestamp = time.time()
98 
99         # The policy should lease this message, telling PubSub that it has
100         # it until it is acked or otherwise dropped.
101         self.lease()
102 
103     def __repr__(self):
104         # Get an abbreviated version of the data.
105         abbv_data = self._message.data
106         if len(abbv_data) > 50:
107             abbv_data = abbv_data[:50] + b'...'
108 
109         pretty_attrs = json.dumps(
110             dict(self.attributes),
111             indent=2,
112             separators=(',', ': '),
113             sort_keys=True,
114         )
115         pretty_attrs = _indent(pretty_attrs)
116         # We don't actually want the first line indented.
117         pretty_attrs = pretty_attrs.lstrip()
118         return _MESSAGE_REPR.format(abbv_data, pretty_attrs)
119 
120     @property
121     def attributes(self):
122         """Return the attributes of the underlying Pub/Sub Message.
123 
124         .. warning::
125 
126             A ``ScalarMapContainer`` behaves slightly differently than a
127             ``dict``. For a Pub / Sub message this is a ``string->string`` map.
128             When trying to access a value via ``map['key']``, if the key is
129             not in the map, then the default value for the string type will
130             be returned, which is an empty string. It may be more intuitive
131             to just cast the map to a ``dict`` or to one use ``map.get``.
132 
133         Returns:
134             .ScalarMapContainer: The message's attributes. This is a
135             ``dict``-like object provided by ``google.protobuf``.
136         """
137         return self._message.attributes
138 
139     @property
140     def data(self):
141         """Return the data for the underlying Pub/Sub Message.
142 
143         Returns:
144             bytes: The message data. This is always a bytestring; if you
145                 want a text string, call :meth:`bytes.decode`.
146         """
147         return self._message.data
148 
149     @property
150     def publish_time(self):
151         """Return the time that the message was originally published.
152 
153         Returns:
154             datetime: The date and time that the message was published.
155         """
156         timestamp = self._message.publish_time
157         delta = datetime.timedelta(
158             seconds=timestamp.seconds,
159             microseconds=timestamp.nanos // 1000)
160         return datetime_helpers._UTC_EPOCH + delta
161 
162     @property
163     def size(self):
164         """Return the size of the underlying message, in bytes."""
165         return self._message.ByteSize()
166 
167     def ack(self):
168         """Acknowledge the given message.
169 
170         Acknowledging a message in Pub/Sub means that you are done
171         with it, and it will not be delivered to this subscription again.
172         You should avoid acknowledging messages until you have
173         *finished* processing them, so that in the event of a failure,
174         you receive the message again.
175 
176         .. warning::
177             Acks in Pub/Sub are best effort. You should always
178             ensure that your processing code is idempotent, as you may
179             receive any given message more than once.
180         """
181         time_to_ack = math.ceil(time.time() - self._received_timestamp)
182         self._request_queue.put(
183             requests.AckRequest(
184                 ack_id=self._ack_id,
185                 byte_size=self.size,
186                 time_to_ack=time_to_ack
187             )
188         )
189 
190     def drop(self):
191         """Release the message from lease management.
192 
193         This informs the policy to no longer hold on to the lease for this
194         message. Pub/Sub will re-deliver the message if it is not acknowledged
195         before the existing lease expires.
196 
197         .. warning::
198             For most use cases, the only reason to drop a message from
199             lease management is on :meth:`ack` or :meth:`nack`; these methods
200             both call this one. You probably do not want to call this method
201             directly.
202         """
203         self._request_queue.put(
204             requests.DropRequest(
205                 ack_id=self._ack_id,
206                 byte_size=self.size
207             )
208         )
209 
210     def lease(self):
211         """Inform the policy to lease this message continually.
212 
213         .. note::
214             This method is called by the constructor, and you should never
215             need to call it manually.
216         """
217         self._request_queue.put(
218             requests.LeaseRequest(
219                 ack_id=self._ack_id,
220                 byte_size=self.size
221             )
222         )
223 
224     def modify_ack_deadline(self, seconds):
225         """Resets the deadline for acknowledgement.
226 
227         New deadline will be the given value of seconds from now.
228 
229         The default implementation handles this for you; you should not need
230         to manually deal with setting ack deadlines. The exception case is
231         if you are implementing your own custom subclass of
232         :class:`~.pubsub_v1.subcriber._consumer.Consumer`.
233 
234         Args:
235             seconds (int): The number of seconds to set the lease deadline
236                 to. This should be between 0 and 600. Due to network latency,
237                 values below 10 are advised against.
238         """
239         self._request_queue.put(
240             requests.ModAckRequest(
241                 ack_id=self._ack_id,
242                 seconds=seconds
243             )
244         )
245 
246     def nack(self):
247         """Decline to acknowldge the given message.
248 
249         This will cause the message to be re-delivered to the subscription.
250         """
251         self._request_queue.put(
252             requests.NackRequest(
253                 ack_id=self._ack_id,
254                 byte_size=self.size
255             )
256         )
257
```
--- 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/pubsub/google/cloud/pubsub_v1/subscriber/message.py b/pubsub/google/cloud/pubsub_v1/subscriber/message.py
--- a/pubsub/google/cloud/pubsub_v1/subscriber/message.py
+++ b/pubsub/google/cloud/pubsub_v1/subscriber/message.py
@@ -164,6 +164,11 @@
         """Return the size of the underlying message, in bytes."""
         return self._message.ByteSize()
 
+    @property
+    def ack_id(self):
+        """str: the ID used to ack the message."""
+        return self._ack_id
+
     def ack(self):
         """Acknowledge the given message.

{"golden_diff": "diff --git a/pubsub/google/cloud/pubsub_v1/subscriber/message.py b/pubsub/google/cloud/pubsub_v1/subscriber/message.py\n--- a/pubsub/google/cloud/pubsub_v1/subscriber/message.py\n+++ b/pubsub/google/cloud/pubsub_v1/subscriber/message.py\n@@ -164,6 +164,11 @@\n         \"\"\"Return the size of the underlying message, in bytes.\"\"\"\n         return self._message.ByteSize()\n \n+    @property\n+    def ack_id(self):\n+        \"\"\"str: the ID used to ack the message.\"\"\"\n+        return self._ack_id\n+\n     def ack(self):\n         \"\"\"Acknowledge the given message.\n", "issue": "PubSub: add ack_id property accessor to subscriber Message class\nVersion: google-cloud-pubsub 0.35.4\r\n\r\nThis is a feature request to add a property accessor for ack_id in `google.cloud.pubsub_v1.subscriber.message.Message`.\r\n\r\nCurrently the `_ack_id` field is 'private', and only gets used via the `ack()` method (plus other related methods).\r\n\r\nWe find it useful to log the ack ID so that we can manually ack the ID using the Google Cloud SDK (`gcloud` command line interface). This helps us get out of situations where the message is stuck in a (virtually) infinite retry loop because of some error.\r\n\r\nWe can just access the 'private' field, but it doesn't seem very nice to have to do that.\n", "before_files": [{"content": "# Copyright 2017, Google LLC 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\nfrom __future__ import absolute_import\n\nimport datetime\nimport json\nimport math\nimport time\n\nfrom google.api_core import datetime_helpers\nfrom google.cloud.pubsub_v1.subscriber._protocol import requests\n\n\n_MESSAGE_REPR = \"\"\"\\\nMessage {{\n  data: {!r}\n  attributes: {}\n}}\"\"\"\n\n\ndef _indent(lines, prefix='  '):\n    \"\"\"Indent some text.\n\n    Note that this is present as ``textwrap.indent``, but not in Python 2.\n\n    Args:\n        lines (str): The newline delimited string to be indented.\n        prefix (Optional[str]): The prefix to indent each line with. Default\n            to two spaces.\n\n    Returns:\n        str: The newly indented content.\n    \"\"\"\n    indented = []\n    for line in lines.split('\\n'):\n        indented.append(prefix + line)\n    return '\\n'.join(indented)\n\n\nclass Message(object):\n    \"\"\"A representation of a single Pub/Sub message.\n\n    The common way to interact with\n    :class:`~.pubsub_v1.subscriber.message.Message` objects is to receive\n    them in callbacks on subscriptions; most users should never have a need\n    to instantiate them by hand. (The exception to this is if you are\n    implementing a custom subclass to\n    :class:`~.pubsub_v1.subscriber._consumer.Consumer`.)\n\n    Attributes:\n        message_id (str): The message ID. In general, you should not need\n            to use this directly.\n        data (bytes): The data in the message. Note that this will be a\n            :class:`bytes`, not a text string.\n        attributes (.ScalarMapContainer): The attributes sent along with the\n            message. See :attr:`attributes` for more information on this type.\n        publish_time (datetime): The time that this message was originally\n            published.\n    \"\"\"\n\n    def __init__(self, message, ack_id, request_queue):\n        \"\"\"Construct the Message.\n\n        .. note::\n\n            This class should not be constructed directly; it is the\n            responsibility of :class:`BasePolicy` subclasses to do so.\n\n        Args:\n            message (~.pubsub_v1.types.PubsubMessage): The message received\n                from Pub/Sub.\n            ack_id (str): The ack_id received from Pub/Sub.\n            request_queue (queue.Queue): A queue provided by the policy that\n                can accept requests; the policy is responsible for handling\n                those requests.\n        \"\"\"\n        self._message = message\n        self._ack_id = ack_id\n        self._request_queue = request_queue\n        self.message_id = message.message_id\n\n        # The instantiation time is the time that this message\n        # was received. Tracking this provides us a way to be smart about\n        # the default lease deadline.\n        self._received_timestamp = time.time()\n\n        # The policy should lease this message, telling PubSub that it has\n        # it until it is acked or otherwise dropped.\n        self.lease()\n\n    def __repr__(self):\n        # Get an abbreviated version of the data.\n        abbv_data = self._message.data\n        if len(abbv_data) > 50:\n            abbv_data = abbv_data[:50] + b'...'\n\n        pretty_attrs = json.dumps(\n            dict(self.attributes),\n            indent=2,\n            separators=(',', ': '),\n            sort_keys=True,\n        )\n        pretty_attrs = _indent(pretty_attrs)\n        # We don't actually want the first line indented.\n        pretty_attrs = pretty_attrs.lstrip()\n        return _MESSAGE_REPR.format(abbv_data, pretty_attrs)\n\n    @property\n    def attributes(self):\n        \"\"\"Return the attributes of the underlying Pub/Sub Message.\n\n        .. warning::\n\n            A ``ScalarMapContainer`` behaves slightly differently than a\n            ``dict``. For a Pub / Sub message this is a ``string->string`` map.\n            When trying to access a value via ``map['key']``, if the key is\n            not in the map, then the default value for the string type will\n            be returned, which is an empty string. It may be more intuitive\n            to just cast the map to a ``dict`` or to one use ``map.get``.\n\n        Returns:\n            .ScalarMapContainer: The message's attributes. This is a\n            ``dict``-like object provided by ``google.protobuf``.\n        \"\"\"\n        return self._message.attributes\n\n    @property\n    def data(self):\n        \"\"\"Return the data for the underlying Pub/Sub Message.\n\n        Returns:\n            bytes: The message data. This is always a bytestring; if you\n                want a text string, call :meth:`bytes.decode`.\n        \"\"\"\n        return self._message.data\n\n    @property\n    def publish_time(self):\n        \"\"\"Return the time that the message was originally published.\n\n        Returns:\n            datetime: The date and time that the message was published.\n        \"\"\"\n        timestamp = self._message.publish_time\n        delta = datetime.timedelta(\n            seconds=timestamp.seconds,\n            microseconds=timestamp.nanos // 1000)\n        return datetime_helpers._UTC_EPOCH + delta\n\n    @property\n    def size(self):\n        \"\"\"Return the size of the underlying message, in bytes.\"\"\"\n        return self._message.ByteSize()\n\n    def ack(self):\n        \"\"\"Acknowledge the given message.\n\n        Acknowledging a message in Pub/Sub means that you are done\n        with it, and it will not be delivered to this subscription again.\n        You should avoid acknowledging messages until you have\n        *finished* processing them, so that in the event of a failure,\n        you receive the message again.\n\n        .. warning::\n            Acks in Pub/Sub are best effort. You should always\n            ensure that your processing code is idempotent, as you may\n            receive any given message more than once.\n        \"\"\"\n        time_to_ack = math.ceil(time.time() - self._received_timestamp)\n        self._request_queue.put(\n            requests.AckRequest(\n                ack_id=self._ack_id,\n                byte_size=self.size,\n                time_to_ack=time_to_ack\n            )\n        )\n\n    def drop(self):\n        \"\"\"Release the message from lease management.\n\n        This informs the policy to no longer hold on to the lease for this\n        message. Pub/Sub will re-deliver the message if it is not acknowledged\n        before the existing lease expires.\n\n        .. warning::\n            For most use cases, the only reason to drop a message from\n            lease management is on :meth:`ack` or :meth:`nack`; these methods\n            both call this one. You probably do not want to call this method\n            directly.\n        \"\"\"\n        self._request_queue.put(\n            requests.DropRequest(\n                ack_id=self._ack_id,\n                byte_size=self.size\n            )\n        )\n\n    def lease(self):\n        \"\"\"Inform the policy to lease this message continually.\n\n        .. note::\n            This method is called by the constructor, and you should never\n            need to call it manually.\n        \"\"\"\n        self._request_queue.put(\n            requests.LeaseRequest(\n                ack_id=self._ack_id,\n                byte_size=self.size\n            )\n        )\n\n    def modify_ack_deadline(self, seconds):\n        \"\"\"Resets the deadline for acknowledgement.\n\n        New deadline will be the given value of seconds from now.\n\n        The default implementation handles this for you; you should not need\n        to manually deal with setting ack deadlines. The exception case is\n        if you are implementing your own custom subclass of\n        :class:`~.pubsub_v1.subcriber._consumer.Consumer`.\n\n        Args:\n            seconds (int): The number of seconds to set the lease deadline\n                to. This should be between 0 and 600. Due to network latency,\n                values below 10 are advised against.\n        \"\"\"\n        self._request_queue.put(\n            requests.ModAckRequest(\n                ack_id=self._ack_id,\n                seconds=seconds\n            )\n        )\n\n    def nack(self):\n        \"\"\"Decline to acknowldge the given message.\n\n        This will cause the message to be re-delivered to the subscription.\n        \"\"\"\n        self._request_queue.put(\n            requests.NackRequest(\n                ack_id=self._ack_id,\n                byte_size=self.size\n            )\n        )\n", "path": "pubsub/google/cloud/pubsub_v1/subscriber/message.py"}], "after_files": [{"content": "# Copyright 2017, Google LLC 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\nfrom __future__ import absolute_import\n\nimport datetime\nimport json\nimport math\nimport time\n\nfrom google.api_core import datetime_helpers\nfrom google.cloud.pubsub_v1.subscriber._protocol import requests\n\n\n_MESSAGE_REPR = \"\"\"\\\nMessage {{\n  data: {!r}\n  attributes: {}\n}}\"\"\"\n\n\ndef _indent(lines, prefix='  '):\n    \"\"\"Indent some text.\n\n    Note that this is present as ``textwrap.indent``, but not in Python 2.\n\n    Args:\n        lines (str): The newline delimited string to be indented.\n        prefix (Optional[str]): The prefix to indent each line with. Default\n            to two spaces.\n\n    Returns:\n        str: The newly indented content.\n    \"\"\"\n    indented = []\n    for line in lines.split('\\n'):\n        indented.append(prefix + line)\n    return '\\n'.join(indented)\n\n\nclass Message(object):\n    \"\"\"A representation of a single Pub/Sub message.\n\n    The common way to interact with\n    :class:`~.pubsub_v1.subscriber.message.Message` objects is to receive\n    them in callbacks on subscriptions; most users should never have a need\n    to instantiate them by hand. (The exception to this is if you are\n    implementing a custom subclass to\n    :class:`~.pubsub_v1.subscriber._consumer.Consumer`.)\n\n    Attributes:\n        message_id (str): The message ID. In general, you should not need\n            to use this directly.\n        data (bytes): The data in the message. Note that this will be a\n            :class:`bytes`, not a text string.\n        attributes (.ScalarMapContainer): The attributes sent along with the\n            message. See :attr:`attributes` for more information on this type.\n        publish_time (datetime): The time that this message was originally\n            published.\n    \"\"\"\n\n    def __init__(self, message, ack_id, request_queue):\n        \"\"\"Construct the Message.\n\n        .. note::\n\n            This class should not be constructed directly; it is the\n            responsibility of :class:`BasePolicy` subclasses to do so.\n\n        Args:\n            message (~.pubsub_v1.types.PubsubMessage): The message received\n                from Pub/Sub.\n            ack_id (str): The ack_id received from Pub/Sub.\n            request_queue (queue.Queue): A queue provided by the policy that\n                can accept requests; the policy is responsible for handling\n                those requests.\n        \"\"\"\n        self._message = message\n        self._ack_id = ack_id\n        self._request_queue = request_queue\n        self.message_id = message.message_id\n\n        # The instantiation time is the time that this message\n        # was received. Tracking this provides us a way to be smart about\n        # the default lease deadline.\n        self._received_timestamp = time.time()\n\n        # The policy should lease this message, telling PubSub that it has\n        # it until it is acked or otherwise dropped.\n        self.lease()\n\n    def __repr__(self):\n        # Get an abbreviated version of the data.\n        abbv_data = self._message.data\n        if len(abbv_data) > 50:\n            abbv_data = abbv_data[:50] + b'...'\n\n        pretty_attrs = json.dumps(\n            dict(self.attributes),\n            indent=2,\n            separators=(',', ': '),\n            sort_keys=True,\n        )\n        pretty_attrs = _indent(pretty_attrs)\n        # We don't actually want the first line indented.\n        pretty_attrs = pretty_attrs.lstrip()\n        return _MESSAGE_REPR.format(abbv_data, pretty_attrs)\n\n    @property\n    def attributes(self):\n        \"\"\"Return the attributes of the underlying Pub/Sub Message.\n\n        .. warning::\n\n            A ``ScalarMapContainer`` behaves slightly differently than a\n            ``dict``. For a Pub / Sub message this is a ``string->string`` map.\n            When trying to access a value via ``map['key']``, if the key is\n            not in the map, then the default value for the string type will\n            be returned, which is an empty string. It may be more intuitive\n            to just cast the map to a ``dict`` or to one use ``map.get``.\n\n        Returns:\n            .ScalarMapContainer: The message's attributes. This is a\n            ``dict``-like object provided by ``google.protobuf``.\n        \"\"\"\n        return self._message.attributes\n\n    @property\n    def data(self):\n        \"\"\"Return the data for the underlying Pub/Sub Message.\n\n        Returns:\n            bytes: The message data. This is always a bytestring; if you\n                want a text string, call :meth:`bytes.decode`.\n        \"\"\"\n        return self._message.data\n\n    @property\n    def publish_time(self):\n        \"\"\"Return the time that the message was originally published.\n\n        Returns:\n            datetime: The date and time that the message was published.\n        \"\"\"\n        timestamp = self._message.publish_time\n        delta = datetime.timedelta(\n            seconds=timestamp.seconds,\n            microseconds=timestamp.nanos // 1000)\n        return datetime_helpers._UTC_EPOCH + delta\n\n    @property\n    def size(self):\n        \"\"\"Return the size of the underlying message, in bytes.\"\"\"\n        return self._message.ByteSize()\n\n    @property\n    def ack_id(self):\n        \"\"\"str: the ID used to ack the message.\"\"\"\n        return self._ack_id\n\n    def ack(self):\n        \"\"\"Acknowledge the given message.\n\n        Acknowledging a message in Pub/Sub means that you are done\n        with it, and it will not be delivered to this subscription again.\n        You should avoid acknowledging messages until you have\n        *finished* processing them, so that in the event of a failure,\n        you receive the message again.\n\n        .. warning::\n            Acks in Pub/Sub are best effort. You should always\n            ensure that your processing code is idempotent, as you may\n            receive any given message more than once.\n        \"\"\"\n        time_to_ack = math.ceil(time.time() - self._received_timestamp)\n        self._request_queue.put(\n            requests.AckRequest(\n                ack_id=self._ack_id,\n                byte_size=self.size,\n                time_to_ack=time_to_ack\n            )\n        )\n\n    def drop(self):\n        \"\"\"Release the message from lease management.\n\n        This informs the policy to no longer hold on to the lease for this\n        message. Pub/Sub will re-deliver the message if it is not acknowledged\n        before the existing lease expires.\n\n        .. warning::\n            For most use cases, the only reason to drop a message from\n            lease management is on :meth:`ack` or :meth:`nack`; these methods\n            both call this one. You probably do not want to call this method\n            directly.\n        \"\"\"\n        self._request_queue.put(\n            requests.DropRequest(\n                ack_id=self._ack_id,\n                byte_size=self.size\n            )\n        )\n\n    def lease(self):\n        \"\"\"Inform the policy to lease this message continually.\n\n        .. note::\n            This method is called by the constructor, and you should never\n            need to call it manually.\n        \"\"\"\n        self._request_queue.put(\n            requests.LeaseRequest(\n                ack_id=self._ack_id,\n                byte_size=self.size\n            )\n        )\n\n    def modify_ack_deadline(self, seconds):\n        \"\"\"Resets the deadline for acknowledgement.\n\n        New deadline will be the given value of seconds from now.\n\n        The default implementation handles this for you; you should not need\n        to manually deal with setting ack deadlines. The exception case is\n        if you are implementing your own custom subclass of\n        :class:`~.pubsub_v1.subcriber._consumer.Consumer`.\n\n        Args:\n            seconds (int): The number of seconds to set the lease deadline\n                to. This should be between 0 and 600. Due to network latency,\n                values below 10 are advised against.\n        \"\"\"\n        self._request_queue.put(\n            requests.ModAckRequest(\n                ack_id=self._ack_id,\n                seconds=seconds\n            )\n        )\n\n    def nack(self):\n        \"\"\"Decline to acknowldge the given message.\n\n        This will cause the message to be re-delivered to the subscription.\n        \"\"\"\n        self._request_queue.put(\n            requests.NackRequest(\n                ack_id=self._ack_id,\n                byte_size=self.size\n            )\n        )\n", "path": "pubsub/google/cloud/pubsub_v1/subscriber/message.py"}]}