2222import os
2323import re
2424import socket
25+ import subprocess
2526import sys
2627from threading import local as Local
2728
@@ -130,13 +131,13 @@ def _ensure_tuple_or_list(arg_name, tuple_or_list):
130131 This effectively reduces the iterable types allowed to a very short
131132 whitelist: list and tuple.
132133
133- :type arg_name: string
134+ :type arg_name: str
134135 :param arg_name: Name of argument to use in error message.
135136
136- :type tuple_or_list: sequence of string
137+ :type tuple_or_list: sequence of str
137138 :param tuple_or_list: Sequence to be verified.
138139
139- :rtype: list of string
140+ :rtype: list of str
140141 :returns: The ``tuple_or_list`` passed in cast to a ``list``.
141142 :raises: class:`TypeError` if the ``tuple_or_list`` is not a tuple or
142143 list.
@@ -150,7 +151,7 @@ def _ensure_tuple_or_list(arg_name, tuple_or_list):
150151def _app_engine_id ():
151152 """Gets the App Engine application ID if it can be inferred.
152153
153- :rtype: string or ``NoneType``
154+ :rtype: str or ``NoneType``
154155 :returns: App Engine application ID if running in App Engine,
155156 else ``None``.
156157 """
@@ -163,7 +164,7 @@ def _app_engine_id():
163164def _file_project_id ():
164165 """Gets the project id from the credentials file if one is available.
165166
166- :rtype: string or ``NoneType``
167+ :rtype: str or ``NoneType``
167168 :returns: Project-ID from JSON credentials file if value exists,
168169 else ``None``.
169170 """
@@ -177,6 +178,22 @@ def _file_project_id():
177178 return None
178179
179180
181+ def _default_service_project_id ():
182+ """Retrieves the project ID from the gcloud command line tool.
183+
184+ :rtype: str or ``NoneType``
185+ :returns: Project-ID from ``gcloud info`` else ``None``
186+ """
187+ gcloud_project_conf = subprocess .check_output (['gcloud' , 'info' ])
188+ gcloud_project_conf = gcloud_project_conf .split ('\n ' )
189+
190+ for key in gcloud_project_conf :
191+ if key .startswith ('Project:' ):
192+ return key [10 :- 1 ]
193+
194+ return None
195+
196+
180197def _compute_engine_id ():
181198 """Gets the Compute Engine project ID if it can be inferred.
182199
@@ -190,7 +207,7 @@ def _compute_engine_id():
190207 See https://github.com/google/oauth2client/issues/93 for context about
191208 DNS latency.
192209
193- :rtype: string or ``NoneType``
210+ :rtype: str or ``NoneType``
194211 :returns: Compute Engine project ID if the metadata service is available,
195212 else ``None``.
196213 """
@@ -223,14 +240,14 @@ def _determine_default_project(project=None):
223240
224241 * GCLOUD_PROJECT environment variable
225242 * GOOGLE_APPLICATION_CREDENTIALS JSON file
226- * Get from oauth defaults
243+ * Get from `gcloud auth login` defaults
227244 * Google App Engine application ID
228245 * Google Compute Engine project ID (from metadata server)
229246
230- :type project: string
247+ :type project: str
231248 :param project: Optional. The project name to use as default.
232249
233- :rtype: string or ``NoneType``
250+ :rtype: str or ``NoneType``
234251 :returns: Default project if it can be determined.
235252 """
236253 if project is None :
@@ -239,8 +256,8 @@ def _determine_default_project(project=None):
239256 if project is None :
240257 project = _file_project_id ()
241258
242- # if project is None:
243- # print oauth2client.get_application_default ()
259+ if project is None :
260+ project = _default_service_project_id ()
244261
245262 if project is None :
246263 project = _app_engine_id ()
@@ -257,7 +274,7 @@ def _millis(when):
257274 :type when: :class:`datetime.datetime`
258275 :param when: the datetime to convert
259276
260- :rtype: integer
277+ :rtype: int
261278 :returns: milliseconds since epoch for ``when``
262279 """
263280 micros = _microseconds_from_datetime (when )
@@ -282,7 +299,7 @@ def _microseconds_from_datetime(value):
282299 :type value: :class:`datetime.datetime`
283300 :param value: The timestamp to convert.
284301
285- :rtype: integer
302+ :rtype: int
286303 :returns: The timestamp, in microseconds.
287304 """
288305 if not value .tzinfo :
@@ -299,7 +316,7 @@ def _millis_from_datetime(value):
299316 :type value: :class:`datetime.datetime`, or None
300317 :param value: the timestamp
301318
302- :rtype: integer , or ``NoneType``
319+ :rtype: int , or ``NoneType``
303320 :returns: the timestamp, in milliseconds, or None
304321 """
305322 if value is not None :
@@ -456,20 +473,20 @@ def _datetime_to_pb_timestamp(when):
456473def _name_from_project_path (path , project , template ):
457474 """Validate a URI path and get the leaf object's name.
458475
459- :type path: string
476+ :type path: str
460477 :param path: URI path containing the name.
461478
462- :type project: string or NoneType
479+ :type project: str or NoneType
463480 :param project: The project associated with the request. It is
464481 included for validation purposes. If passed as None,
465482 disables validation.
466483
467- :type template: string
484+ :type template: str
468485 :param template: Template regex describing the expected form of the path.
469486 The regex must have two named groups, 'project' and
470487 'name'.
471488
472- :rtype: string
489+ :rtype: str
473490 :returns: Name parsed from ``path``.
474491 :raises: :class:`ValueError` if the ``path`` is ill-formed or if
475492 the project from the ``path`` does not agree with the
0 commit comments