Skip to content
This repository was archived by the owner on Mar 31, 2026. It is now read-only.

Commit d046f30

Browse files
committed
Add timeout to _PropertyMixin helpers
1 parent 306deba commit d046f30

2 files changed

Lines changed: 42 additions & 6 deletions

File tree

google/cloud/storage/_helpers.py

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@
2121
from hashlib import md5
2222
import os
2323

24+
from google.cloud.storage.constants import _DEFAULT_TIMEOUT
25+
26+
2427
STORAGE_EMULATOR_ENV_VAR = "STORAGE_EMULATOR_HOST"
2528
"""Environment variable defining host for Storage emulator."""
2629

@@ -117,7 +120,7 @@ def _query_params(self):
117120
params["userProject"] = self.user_project
118121
return params
119122

120-
def reload(self, client=None):
123+
def reload(self, client=None, timeout=_DEFAULT_TIMEOUT):
121124
"""Reload properties from Cloud Storage.
122125
123126
If :attr:`user_project` is set, bills the API request to that project.
@@ -126,6 +129,12 @@ def reload(self, client=None):
126129
``NoneType``
127130
:param client: the client to use. If not passed, falls back to the
128131
``client`` stored on the current object.
132+
:type timeout: float or tuple
133+
:param timeout: (optional) The amount of time, in seconds, to wait
134+
for the server response.
135+
136+
Can also be passed as a tuple (connect_timeout, read_timeout).
137+
See :meth:`requests.Session.request` documentation for details.
129138
"""
130139
client = self._require_client(client)
131140
query_params = self._query_params
@@ -138,6 +147,7 @@ def reload(self, client=None):
138147
query_params=query_params,
139148
headers=self._encryption_headers(),
140149
_target_object=self,
150+
timeout=timeout,
141151
)
142152
self._set_properties(api_response)
143153

@@ -169,7 +179,7 @@ def _set_properties(self, value):
169179
# If the values are reset, the changes must as well.
170180
self._changes = set()
171181

172-
def patch(self, client=None):
182+
def patch(self, client=None, timeout=_DEFAULT_TIMEOUT):
173183
"""Sends all changed properties in a PATCH request.
174184
175185
Updates the ``_properties`` with the response from the backend.
@@ -180,6 +190,12 @@ def patch(self, client=None):
180190
``NoneType``
181191
:param client: the client to use. If not passed, falls back to the
182192
``client`` stored on the current object.
193+
:type timeout: float or tuple
194+
:param timeout: (optional) The amount of time, in seconds, to wait
195+
for the server response.
196+
197+
Can also be passed as a tuple (connect_timeout, read_timeout).
198+
See :meth:`requests.Session.request` documentation for details.
183199
"""
184200
client = self._require_client(client)
185201
query_params = self._query_params
@@ -195,10 +211,11 @@ def patch(self, client=None):
195211
data=update_properties,
196212
query_params=query_params,
197213
_target_object=self,
214+
timeout=timeout,
198215
)
199216
self._set_properties(api_response)
200217

201-
def update(self, client=None):
218+
def update(self, client=None, timeout=_DEFAULT_TIMEOUT):
202219
"""Sends all properties in a PUT request.
203220
204221
Updates the ``_properties`` with the response from the backend.
@@ -209,6 +226,12 @@ def update(self, client=None):
209226
``NoneType``
210227
:param client: the client to use. If not passed, falls back to the
211228
``client`` stored on the current object.
229+
:type timeout: float or tuple
230+
:param timeout: (optional) The amount of time, in seconds, to wait
231+
for the server response.
232+
233+
Can also be passed as a tuple (connect_timeout, read_timeout).
234+
See :meth:`requests.Session.request` documentation for details.
212235
"""
213236
client = self._require_client(client)
214237
query_params = self._query_params
@@ -219,6 +242,7 @@ def update(self, client=None):
219242
data=self._properties,
220243
query_params=query_params,
221244
_target_object=self,
245+
timeout=timeout,
222246
)
223247
self._set_properties(api_response)
224248

tests/unit/test__helpers.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,12 @@ def test_w_env_var(self):
4444

4545

4646
class Test_PropertyMixin(unittest.TestCase):
47+
@staticmethod
48+
def _get_default_timeout():
49+
from google.cloud.storage.constants import _DEFAULT_TIMEOUT
50+
51+
return _DEFAULT_TIMEOUT
52+
4753
@staticmethod
4854
def _get_target_class():
4955
from google.cloud.storage._helpers import _PropertyMixin
@@ -103,7 +109,7 @@ def test_reload(self):
103109
# Make sure changes is not a set instance before calling reload
104110
# (which will clear / replace it with an empty set), checked below.
105111
derived._changes = object()
106-
derived.reload(client=client)
112+
derived.reload(client=client, timeout=42)
107113
self.assertEqual(derived._properties, {"foo": "Foo"})
108114
kw = connection._requested
109115
self.assertEqual(len(kw), 1)
@@ -115,6 +121,7 @@ def test_reload(self):
115121
"query_params": {"projection": "noAcl"},
116122
"headers": {},
117123
"_target_object": derived,
124+
"timeout": 42,
118125
},
119126
)
120127
self.assertEqual(derived._changes, set())
@@ -139,6 +146,7 @@ def test_reload_w_user_project(self):
139146
"query_params": {"projection": "noAcl", "userProject": user_project},
140147
"headers": {},
141148
"_target_object": derived,
149+
"timeout": self._get_default_timeout(),
142150
},
143151
)
144152
self.assertEqual(derived._changes, set())
@@ -164,7 +172,7 @@ def test_patch(self):
164172
BAZ = object()
165173
derived._properties = {"bar": BAR, "baz": BAZ}
166174
derived._changes = set(["bar"]) # Ignore baz.
167-
derived.patch(client=client)
175+
derived.patch(client=client, timeout=42)
168176
self.assertEqual(derived._properties, {"foo": "Foo"})
169177
kw = connection._requested
170178
self.assertEqual(len(kw), 1)
@@ -177,6 +185,7 @@ def test_patch(self):
177185
# Since changes does not include `baz`, we don't see it sent.
178186
"data": {"bar": BAR},
179187
"_target_object": derived,
188+
"timeout": 42,
180189
},
181190
)
182191
# Make sure changes get reset by patch().
@@ -205,6 +214,7 @@ def test_patch_w_user_project(self):
205214
# Since changes does not include `baz`, we don't see it sent.
206215
"data": {"bar": BAR},
207216
"_target_object": derived,
217+
"timeout": self._get_default_timeout(),
208218
},
209219
)
210220
# Make sure changes get reset by patch().
@@ -219,14 +229,15 @@ def test_update(self):
219229
BAZ = object()
220230
derived._properties = {"bar": BAR, "baz": BAZ}
221231
derived._changes = set(["bar"]) # Update sends 'baz' anyway.
222-
derived.update(client=client)
232+
derived.update(client=client, timeout=42)
223233
self.assertEqual(derived._properties, {"foo": "Foo"})
224234
kw = connection._requested
225235
self.assertEqual(len(kw), 1)
226236
self.assertEqual(kw[0]["method"], "PUT")
227237
self.assertEqual(kw[0]["path"], "/path")
228238
self.assertEqual(kw[0]["query_params"], {"projection": "full"})
229239
self.assertEqual(kw[0]["data"], {"bar": BAR, "baz": BAZ})
240+
self.assertEqual(kw[0]["timeout"], 42)
230241
# Make sure changes get reset by patch().
231242
self.assertEqual(derived._changes, set())
232243

@@ -250,6 +261,7 @@ def test_update_w_user_project(self):
250261
kw[0]["query_params"], {"projection": "full", "userProject": user_project}
251262
)
252263
self.assertEqual(kw[0]["data"], {"bar": BAR, "baz": BAZ})
264+
self.assertEqual(kw[0]["timeout"], self._get_default_timeout())
253265
# Make sure changes get reset by patch().
254266
self.assertEqual(derived._changes, set())
255267

0 commit comments

Comments
 (0)