Skip to content

Commit a291f66

Browse files
authored
Merge pull request #224 from Shubha-accenture/bigquery-api-check
Perform the Bigquery API check on the server side instead of directly from the UI.
2 parents b829282 + 3b5a57f commit a291f66

File tree

4 files changed

+50
-38
lines changed

4 files changed

+50
-38
lines changed

dataproc_jupyter_plugin/controllers/bigquery.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,12 @@
1414

1515

1616
import json
17+
import subprocess
1718

1819
import aiohttp
1920
import tornado
2021
from jupyter_server.base.handlers import APIHandler
21-
22+
from google.cloud.jupyter_config.config import async_run_gcloud_subcommand
2223
from dataproc_jupyter_plugin import credentials
2324
from dataproc_jupyter_plugin.services import bigquery
2425

@@ -158,3 +159,17 @@ async def post(self):
158159
except Exception as e:
159160
self.log.exception("Error fetching search data")
160161
self.finish({"error": str(e)})
162+
163+
164+
class CheckApiController(APIHandler):
165+
@tornado.web.authenticated
166+
async def post(self):
167+
try:
168+
project_id = await credentials._gcp_project()
169+
cmd = f"services list --enabled --project={project_id} | grep bigquery.googleapis.com"
170+
result = await async_run_gcloud_subcommand(cmd)
171+
is_enabled = bool(result.strip())
172+
self.finish({"success": True, "is_enabled": is_enabled})
173+
174+
except Exception as e:
175+
self.finish({"success": False, "is_enabled": False, "error": str(e)})

dataproc_jupyter_plugin/handlers.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ def full_path(name):
230230
"bigQueryPreview": bigquery.PreviewController,
231231
"bigQueryProjectsList": bigquery.ProjectsController,
232232
"bigQuerySearch": bigquery.SearchController,
233+
"bigQueryApiEnabled": bigquery.CheckApiController,
233234
}
234235
handlers = [(full_path(name), handler) for name, handler in handlersMap.items()]
235236
web_app.add_handlers(host_pattern, handlers)

src/bigQuery/bigQueryService.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -421,17 +421,17 @@ export class BigQueryService {
421421
}
422422
};
423423

424-
static listBigQueryDatasetsAPIService = async (projectId: string) => {
425-
const pageToken = '';
424+
static checkBigQueryDatasetsAPIService = async () => {
426425
try {
427-
const data: any = await requestAPI(
428-
`bigQueryDataset?project_id=${projectId}&pageToken=${pageToken}`
429-
);
426+
const data: any = await requestAPI(`bigQueryApiEnabled`, {
427+
method: 'POST'
428+
});
430429
return data;
431430
} catch (reason) {
432431
return reason;
433432
}
434433
};
434+
435435
static getBigQuerySearchCatalogAPIService = async () => {
436436
try {
437437
const data: any = await requestAPI(

src/index.ts

Lines changed: 28 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -181,9 +181,7 @@ const extension: JupyterFrontEndPlugin<void> = {
181181
const credentials = await authApi();
182182
if (credentials?.project_id) {
183183
bigqueryDatasetsResponse =
184-
await BigQueryService.listBigQueryDatasetsAPIService(
185-
credentials.project_id
186-
);
184+
await BigQueryService.checkBigQueryDatasetsAPIService();
187185
}
188186

189187
const dataCatalogResponse =
@@ -195,53 +193,57 @@ const extension: JupyterFrontEndPlugin<void> = {
195193
errorKey: 'error.message',
196194
errorMessage: 'Cloud Dataproc API has not been used in project',
197195
notificationMessage: 'The Cloud Dataproc API is not enabled.',
198-
enableLink:
199-
'https://console.cloud.google.com/apis/library/dataproc.googleapis.com'
196+
enableLink: `https://console.cloud.google.com/apis/library/dataproc.googleapis.com?project=${credentials?.project_id}`
200197
},
201198
{
202199
response: bigqueryDatasetsResponse,
203200
errorKey: 'error',
201+
checkType: 'bigquery',
204202
errorMessage: 'has not enabled BigQuery',
205203
notificationMessage: 'The BigQuery API is not enabled.',
206-
enableLink:
207-
'https://console.cloud.google.com/apis/library/bigquery.googleapis.com'
204+
enableLink: `https://console.cloud.google.com/apis/library/bigquery.googleapis.com?project=${credentials?.project_id}`
208205
},
209206
{
210207
response: dataCatalogResponse,
211208
errorKey: 'error',
212209
errorMessage:
213210
'Google Cloud Data Catalog API has not been used in project',
214211
notificationMessage: 'Google Cloud Data Catalog API is not enabled.',
215-
enableLink:
216-
'https://console.cloud.google.com/apis/library/datacatalog.googleapis.com'
212+
enableLink: `https://console.cloud.google.com/apis/library/datacatalog.googleapis.com?project=${credentials?.project_id}`
217213
}
218214
];
219-
220-
apiChecks.forEach(
221-
({
222-
response,
223-
errorKey,
224-
errorMessage,
225-
notificationMessage,
226-
enableLink
227-
}) => {
228-
const errorValue = errorKey
215+
apiChecks.forEach(check => {
216+
if (check.checkType === 'bigquery') {
217+
if (check.response && check.response.is_enabled === false) {
218+
Notification.error(check.notificationMessage, {
219+
actions: [
220+
{
221+
label: 'Enable',
222+
callback: () => window.open(check.enableLink, '_blank'),
223+
displayType: 'link'
224+
}
225+
],
226+
autoClose: false
227+
});
228+
}
229+
} else {
230+
const errorValue = check.errorKey
229231
.split('.')
230-
.reduce((acc, key) => acc?.[key], response);
231-
if (errorValue && errorValue.includes(errorMessage)) {
232-
Notification.error(notificationMessage, {
232+
.reduce((acc, key) => acc?.[key], check.response);
233+
if (errorValue && errorValue.includes(check.errorMessage)) {
234+
Notification.error(check.notificationMessage, {
233235
actions: [
234236
{
235237
label: 'Enable',
236-
callback: () => window.open(enableLink, '_blank'),
238+
callback: () => window.open(check.enableLink, '_blank'),
237239
displayType: 'link'
238240
}
239241
],
240242
autoClose: false
241243
});
242244
}
243245
}
244-
);
246+
});
245247
};
246248

247249
await checkAllApisEnabled();
@@ -340,10 +342,7 @@ const extension: JupyterFrontEndPlugin<void> = {
340342
panelDpms.addWidget(new dpmsWidget(app as JupyterLab, themeManager));
341343
onThemeChanged();
342344
app.shell.add(panelDpms, 'left', { rank: 1001 });
343-
DataprocLoggingService.log(
344-
'Metastore is enabled',
345-
LOG_LEVEL.INFO
346-
);
345+
DataprocLoggingService.log('Metastore is enabled', LOG_LEVEL.INFO);
347346
}
348347

349348
if (enableCloudStorage) {
@@ -358,10 +357,7 @@ const extension: JupyterFrontEndPlugin<void> = {
358357
);
359358
onThemeChanged();
360359
app.shell.add(panelGcs, 'left', { rank: 1002 });
361-
DataprocLoggingService.log(
362-
'Cloud storage is enabled',
363-
LOG_LEVEL.INFO
364-
);
360+
DataprocLoggingService.log('Cloud storage is enabled', LOG_LEVEL.INFO);
365361
}
366362
};
367363
onSidePanelEnabled();

0 commit comments

Comments
 (0)