Skip to content

Commit cc4ba04

Browse files
committed
Add 'Client.get_job' API wrapper.
1 parent 177caa5 commit cc4ba04

File tree

2 files changed

+98
-0
lines changed

2 files changed

+98
-0
lines changed

bigquery/google/cloud/bigquery/client.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,35 @@ def job_from_resource(self, resource):
187187
return QueryJob.from_api_repr(resource, self)
188188
raise ValueError('Cannot parse job resource')
189189

190+
def get_job(self, job_name, project=None):
191+
"""Fetch a job for the project associated with this client.
192+
193+
See
194+
https://cloud.google.com/bigquery/docs/reference/rest/v2/jobs/get
195+
196+
:type job_name: str
197+
:param job_name: Name of the job.
198+
199+
:type project: str
200+
:param project:
201+
project ID owning the job (defaults to the client's project)
202+
203+
:rtype: :class:`~google.cloud.bigquery.job._AsyncJob`
204+
:returns:
205+
Concrete job instance, based on the resource returned by the API.
206+
"""
207+
extra_params = {'projection': 'full'}
208+
209+
if project is None:
210+
project = self.project
211+
212+
path = '/projects/{}/jobs/{}'.format(project, job_name)
213+
214+
resource = self._connection.api_request(
215+
method='GET', path=path, query_params=extra_params)
216+
217+
return self.job_from_resource(resource)
218+
190219
def list_jobs(self, max_results=None, page_token=None, all_users=None,
191220
state_filter=None):
192221
"""List jobs for the project associated with this client.

bigquery/tests/unit/test_client.py

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,70 @@ def test_job_from_resource_unknown_type(self):
208208
with self.assertRaises(ValueError):
209209
client.job_from_resource({'configuration': {'nonesuch': {}}})
210210

211+
def test_get_job_miss_w_explict_project(self):
212+
from google.cloud.exceptions import NotFound
213+
214+
PROJECT = 'PROJECT'
215+
OTHER_PROJECT = 'OTHER_PROJECT'
216+
JOB_ID = 'NONESUCH'
217+
creds = _make_credentials()
218+
client = self._make_one(PROJECT, creds)
219+
conn = client._connection = _Connection()
220+
221+
with self.assertRaises(NotFound):
222+
client.get_job(JOB_ID, project=OTHER_PROJECT)
223+
224+
self.assertEqual(len(conn._requested), 1)
225+
req = conn._requested[0]
226+
self.assertEqual(req['method'], 'GET')
227+
self.assertEqual(req['path'], '/projects/OTHER_PROJECT/jobs/NONESUCH')
228+
self.assertEqual(req['query_params'], {'projection': 'full'})
229+
230+
def test_get_job_hit(self):
231+
from google.cloud.bigquery.job import QueryJob
232+
233+
PROJECT = 'PROJECT'
234+
JOB_ID = 'query_job'
235+
DATASET = 'test_dataset'
236+
QUERY_DESTINATION_TABLE = 'query_destination_table'
237+
QUERY = 'SELECT * from test_dataset:test_table'
238+
ASYNC_QUERY_DATA = {
239+
'id': '{}:{}'.format(PROJECT, JOB_ID),
240+
'jobReference': {
241+
'projectId': PROJECT,
242+
'jobId': 'query_job',
243+
},
244+
'state': 'DONE',
245+
'configuration': {
246+
'query': {
247+
'query': QUERY,
248+
'destinationTable': {
249+
'projectId': PROJECT,
250+
'datasetId': DATASET,
251+
'tableId': QUERY_DESTINATION_TABLE,
252+
},
253+
'createDisposition': 'CREATE_IF_NEEDED',
254+
'writeDisposition': 'WRITE_TRUNCATE',
255+
}
256+
},
257+
}
258+
creds = _make_credentials()
259+
client = self._make_one(PROJECT, creds)
260+
conn = client._connection = _Connection(ASYNC_QUERY_DATA)
261+
262+
job = client.get_job(JOB_ID)
263+
264+
self.assertIsInstance(job, QueryJob)
265+
self.assertEqual(job.name, JOB_ID)
266+
self.assertEqual(job.create_disposition, 'CREATE_IF_NEEDED')
267+
self.assertEqual(job.write_disposition, 'WRITE_TRUNCATE')
268+
269+
self.assertEqual(len(conn._requested), 1)
270+
req = conn._requested[0]
271+
self.assertEqual(req['method'], 'GET')
272+
self.assertEqual(req['path'], '/projects/PROJECT/jobs/query_job')
273+
self.assertEqual(req['query_params'], {'projection': 'full'})
274+
211275
def test_list_jobs_defaults(self):
212276
import six
213277
from google.cloud.bigquery.job import LoadTableFromStorageJob
@@ -607,6 +671,11 @@ def __init__(self, *responses):
607671
self._requested = []
608672

609673
def api_request(self, **kw):
674+
from google.cloud.exceptions import NotFound
610675
self._requested.append(kw)
676+
677+
if len(self._responses) == 0:
678+
raise NotFound("miss")
679+
611680
response, self._responses = self._responses[0], self._responses[1:]
612681
return response

0 commit comments

Comments
 (0)