Skip to content

Commit 0267a0c

Browse files
authored
BigQuery: Add project parameter to list_datasets and list_jobs (googleapis#5217)
This allows a Client to list datasets or jobs in projects other than the default project.
1 parent 00e618a commit 0267a0c

3 files changed

Lines changed: 99 additions & 63 deletions

File tree

bigquery/google/cloud/bigquery/client.py

Lines changed: 67 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -186,51 +186,53 @@ def list_projects(self, max_results=None, page_token=None,
186186
page_token=page_token,
187187
max_results=max_results)
188188

189-
def list_datasets(self, include_all=False, filter=None, max_results=None,
190-
page_token=None, retry=DEFAULT_RETRY):
189+
def list_datasets(
190+
self, project=None, include_all=False, filter=None,
191+
max_results=None, page_token=None, retry=DEFAULT_RETRY):
191192
"""List datasets for the project associated with this client.
192193
193194
See
194195
https://cloud.google.com/bigquery/docs/reference/rest/v2/datasets/list
195196
196-
:type include_all: bool
197-
:param include_all: True if results include hidden datasets.
198-
199-
:type filter: str
200-
:param filter: (Optional) an expression for filtering the results by
201-
label. For syntax, see
202-
https://cloud.google.com/bigquery/docs/reference/rest/v2/datasets/list#filter.
203-
204-
:type max_results: int
205-
:param max_results: (Optional) maximum number of datasets to return,
206-
if not passed, defaults to a value set by the API.
207-
208-
:type page_token: str
209-
:param page_token:
210-
(Optional) Token representing a cursor into the datasets. If
211-
not passed, the API will return the first page of datasets.
212-
The token marks the beginning of the iterator to be returned
213-
and the value of the ``page_token`` can be accessed at
214-
``next_page_token`` of the
215-
:class:`~google.api_core.page_iterator.HTTPIterator`.
216-
217-
:type retry: :class:`google.api_core.retry.Retry`
218-
:param retry: (Optional) How to retry the RPC.
197+
Args:
198+
project (str):
199+
Optional. Project ID to use for retreiving datasets. Defaults
200+
to the client's project.
201+
include_all (bool):
202+
Optional. True if results include hidden datasets. Defaults
203+
to False.
204+
filter (str):
205+
Optional. An expression for filtering the results by label.
206+
For syntax, see
207+
https://cloud.google.com/bigquery/docs/reference/rest/v2/datasets/list#filter.
208+
max_results (int):
209+
Optional. Maximum number of datasets to return.
210+
page_token (str):
211+
Optional. Token representing a cursor into the datasets. If
212+
not passed, the API will return the first page of datasets.
213+
The token marks the beginning of the iterator to be returned
214+
and the value of the ``page_token`` can be accessed at
215+
``next_page_token`` of the
216+
:class:`~google.api_core.page_iterator.HTTPIterator`.
217+
retry (google.api_core.retry.Retry):
218+
Optional. How to retry the RPC.
219219
220-
:rtype: :class:`~google.api_core.page_iterator.Iterator`
221-
:returns:
222-
Iterator of
223-
:class:`~google.cloud.bigquery.dataset.DatasetListItem`.
224-
associated with the client's project.
220+
Returns:
221+
google.api_core.page_iterator.Iterator:
222+
Iterator of
223+
:class:`~google.cloud.bigquery.dataset.DatasetListItem`.
224+
associated with the project.
225225
"""
226226
extra_params = {}
227+
if project is None:
228+
project = self.project
227229
if include_all:
228230
extra_params['all'] = True
229231
if filter:
230232
# TODO: consider supporting a dict of label -> value for filter,
231233
# and converting it into a string here.
232234
extra_params['filter'] = filter
233-
path = '/projects/%s/datasets' % (self.project,)
235+
path = '/projects/%s/datasets' % (project,)
234236
return page_iterator.HTTPIterator(
235237
client=self,
236238
api_request=functools.partial(self._call_api, retry),
@@ -658,53 +660,55 @@ def cancel_job(
658660

659661
return self.job_from_resource(resource['job'])
660662

661-
def list_jobs(self, max_results=None, page_token=None, all_users=None,
662-
state_filter=None, retry=DEFAULT_RETRY):
663+
def list_jobs(
664+
self, project=None, max_results=None, page_token=None,
665+
all_users=None, state_filter=None, retry=DEFAULT_RETRY):
663666
"""List jobs for the project associated with this client.
664667
665668
See
666669
https://cloud.google.com/bigquery/docs/reference/rest/v2/jobs/list
667670
668-
:type max_results: int
669-
:param max_results: maximum number of jobs to return, If not
670-
passed, defaults to a value set by the API.
671-
672-
:type page_token: str
673-
:param page_token:
674-
(Optional) Opaque marker for the next "page" of jobs. If not
675-
passed, the API will return the first page of jobs. The token
676-
marks the beginning of the iterator to be returned and the
677-
value of the ``page_token`` can be accessed at
678-
``next_page_token`` of
679-
:class:`~google.api_core.page_iterator.HTTPIterator`.
680-
681-
:type all_users: bool
682-
:param all_users: if true, include jobs owned by all users in the
683-
project.
684-
685-
:type state_filter: str
686-
:param state_filter: if passed, include only jobs matching the given
687-
state. One of
688-
689-
* ``"done"``
690-
* ``"pending"``
691-
* ``"running"``
692-
693-
:type retry: :class:`google.api_core.retry.Retry`
694-
:param retry: (Optional) How to retry the RPC.
671+
Args:
672+
project (str):
673+
Optional. Project ID to use for retreiving datasets. Defaults
674+
to the client's project.
675+
max_results (int):
676+
Optional. Maximum number of jobs to return.
677+
page_token (str):
678+
Optional. Opaque marker for the next "page" of jobs. If not
679+
passed, the API will return the first page of jobs. The token
680+
marks the beginning of the iterator to be returned and the
681+
value of the ``page_token`` can be accessed at
682+
``next_page_token`` of
683+
:class:`~google.api_core.page_iterator.HTTPIterator`.
684+
all_users (bool):
685+
If true, include jobs owned by all users in the project.
686+
state_filter (str):
687+
Optional. If set, include only jobs matching the given
688+
state. One of
689+
690+
* ``"done"``
691+
* ``"pending"``
692+
* ``"running"``
693+
retry (google.api_core.retry.Retry):
694+
Optional. How to retry the RPC.
695695
696-
:rtype: :class:`~google.api_core.page_iterator.Iterator`
697-
:returns: Iterable of job instances.
696+
Returns:
697+
google.api_core.page_iterator.Iterator:
698+
Iterable of job instances.
698699
"""
699700
extra_params = {'projection': 'full'}
700701

702+
if project is None:
703+
project = self.project
704+
701705
if all_users is not None:
702706
extra_params['allUsers'] = all_users
703707

704708
if state_filter is not None:
705709
extra_params['stateFilter'] = state_filter
706710

707-
path = '/projects/%s/jobs' % (self.project,)
711+
path = '/projects/%s/jobs' % (project,)
708712
return page_iterator.HTTPIterator(
709713
client=self,
710714
api_request=functools.partial(self._call_api, retry),

bigquery/tests/system.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,12 @@ def test_list_datasets(self):
222222
dataset.project == Config.CLIENT.project]
223223
self.assertEqual(len(created), len(datasets_to_create))
224224

225+
def test_list_datasets_w_project(self):
226+
# Retrieve datasets from a different project.
227+
iterator = Config.CLIENT.list_datasets(project='bigquery-public-data')
228+
all_datasets = frozenset([dataset.dataset_id for dataset in iterator])
229+
self.assertIn('usa_names', all_datasets)
230+
225231
def test_create_table(self):
226232
dataset = self.temp_dataset(_make_dataset_id('create_table'))
227233
table_id = 'test_table'

bigquery/tests/unit/test_client.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,18 @@ def test_list_datasets_defaults(self):
264264
conn.api_request.assert_called_once_with(
265265
method='GET', path='/%s' % PATH, query_params={})
266266

267+
def test_list_datasets_w_project(self):
268+
creds = _make_credentials()
269+
client = self._make_one(self.PROJECT, creds)
270+
conn = client._connection = _make_connection({})
271+
272+
list(client.list_datasets(project='other-project'))
273+
274+
conn.api_request.assert_called_once_with(
275+
method='GET',
276+
path='/projects/other-project/datasets',
277+
query_params={})
278+
267279
def test_list_datasets_explicit_response_missing_datasets_key(self):
268280
PATH = 'projects/%s/datasets' % self.PROJECT
269281
TOKEN = 'TOKEN'
@@ -1715,6 +1727,20 @@ def test_list_jobs_explicit_missing(self):
17151727
'stateFilter': 'done'
17161728
})
17171729

1730+
def test_list_jobs_w_project(self):
1731+
creds = _make_credentials()
1732+
client = self._make_one(self.PROJECT, creds)
1733+
conn = client._connection = _make_connection({})
1734+
1735+
list(client.list_jobs(project='other-project'))
1736+
1737+
conn.api_request.assert_called_once_with(
1738+
method='GET',
1739+
path='/projects/other-project/jobs',
1740+
query_params={
1741+
'projection': 'full',
1742+
})
1743+
17181744
def test_load_table_from_uri(self):
17191745
from google.cloud.bigquery.job import LoadJob
17201746

0 commit comments

Comments
 (0)