UNPKG

18.3 kBJavaScriptView Raw
1"use strict";
2/*!
3 * Copyright 2019 Google Inc. All Rights Reserved.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17Object.defineProperty(exports, "__esModule", { value: true });
18exports.Model = void 0;
19const common = require("@google-cloud/common");
20const promisify_1 = require("@google-cloud/promisify");
21const arrify = require("arrify");
22const extend = require("extend");
23/**
24 * The model export formats accepted by BigQuery.
25 *
26 * @type {array}
27 * @private
28 */
29const FORMATS = ['ML_TF_SAVED_MODEL', 'ML_XGBOOST_BOOSTER'];
30/**
31 * Model objects are returned by methods such as {@link Dataset#model} and
32 * {@link Dataset#getModels}.
33 *
34 * @class
35 * @param {Dataset} dataset {@link Dataset} instance.
36 * @param {string} id The ID of the model.
37 *
38 * @example
39 * const {BigQuery} = require('@google-cloud/bigquery');
40 * const bigquery = new BigQuery();
41 * const dataset = bigquery.dataset('my-dataset');
42 *
43 * const model = dataset.model('my-model');
44 */
45class Model extends common.ServiceObject {
46 constructor(dataset, id) {
47 const methods = {
48 /**
49 * @callback DeleteModelCallback
50 * @param {?Error} err Request error, if any.
51 * @param {object} apiResponse The full API response.
52 */
53 /**
54 * Delete the model.
55 *
56 * @see [Models: delete API Documentation]{@link https://cloud.google.com/bigquery/docs/reference/rest/v2/models/delete}
57 *
58 * @method Model#delete
59 * @param {DeleteModelCallback} [callback] The callback function.
60 * @param {?error} callback.err An error returned while making this
61 * request.
62 * @param {object} callback.apiResponse The full API response.
63 * @returns {Promise}
64 *
65 * @example
66 * const {BigQuery} = require('@google-cloud/bigquery');
67 * const bigquery = new BigQuery();
68 * const dataset = bigquery.dataset('my-dataset');
69 * const model = dataset.model('my-model');
70 *
71 * model.delete((err, apiResponse) => {});
72 *
73 * @example <caption>If the callback is omitted we'll return a Promise.</caption>
74 * const [apiResponse] = await model.delete();
75 * @example <caption>If successful, the response body is empty.</caption>
76 */
77 delete: true,
78 /**
79 * @callback ModelExistsCallback
80 * @param {?Error} err Request error, if any.
81 * @param {boolean} exists Indicates if the model exists.
82 */
83 /**
84 * @typedef {array} ModelExistsResponse
85 * @property {boolean} 0 Indicates if the model exists.
86 */
87 /**
88 * Check if the model exists.
89 *
90 * @method Model#exists
91 * @param {ModelExistsCallback} [callback] The callback function.
92 * @param {?error} callback.err An error returned while making this
93 * request.
94 * @param {boolean} callback.exists Whether the model exists or not.
95 * @returns {Promise<ModelExistsResponse>}
96 *
97 * @example
98 * const {BigQuery} = require('@google-cloud/bigquery');
99 * const bigquery = new BigQuery();
100 * const dataset = bigquery.dataset('my-dataset');
101 * const model = dataset.model('my-model');
102 *
103 * model.exists((err, exists) => {});
104 *
105 * @example <caption>If the callback is omitted we'll return a Promise.</caption>
106 * const [exists] = await model.exists();
107 */
108 exists: true,
109 /**
110 * @callback GetModelCallback
111 * @param {?Error} err Request error, if any.
112 * @param {Model} model The model.
113 * @param {object} apiResponse The full API response body.
114 */
115 /**
116 * @typedef {array} GetModelResponse
117 * @property {Model} 0 The model.
118 * @property {object} 1 The full API response body.
119 */
120 /**
121 * Get a model if it exists.
122 *
123 * @see [Models: get API Documentation]{@link https://cloud.google.com/bigquery/docs/reference/rest/v2/models/get}
124 *
125 * @method Model#get:
126 * @param {GetModelCallback} [callback] The callback function.
127 * @param {?error} callback.err An error returned while making this
128 * request.
129 * @param {Model} callback.model The {@link Model}.
130 * @param {object} callback.apiResponse The full API response.
131 * @returns {Promise<GetModelResponse>}
132 *
133 * @example
134 * const {BigQuery} = require('@google-cloud/bigquery');
135 * const bigquery = new BigQuery();
136 * const dataset = bigquery.dataset('my-dataset');
137 * const model = dataset.model('my-model');
138 *
139 * model.get(err => {
140 * if (!err) {
141 * // `model.metadata` has been populated.
142 * }
143 * });
144 *
145 * @example <caption>If the callback is omitted we'll return a Promise.</caption>
146 * await model.get();
147 */
148 get: true,
149 /**
150 * @callback GetModelMetadataCallback
151 * @param {?Error} err Request error, if any.
152 * @param {object} metadata The model metadata.
153 * @param {object} apiResponse The full API response.
154 */
155 /**
156 * @typedef {array} GetModelMetadataResponse
157 * @property {object} 0 The model metadata.
158 * @property {object} 1 The full API response.
159 */
160 /**
161 * Return the metadata associated with the model.
162 *
163 * @see [Models: get API Documentation]{@link https://cloud.google.com/bigquery/docs/reference/rest/v2/models/get}
164 *
165 * @method Model#getMetadata
166 * @param {GetModelMetadataCallback} [callback] The callback function.
167 * @param {?error} callback.err An error returned while making this
168 * request.
169 * @param {object} callback.metadata The metadata of the model.
170 * @param {object} callback.apiResponse The full API response.
171 * @returns {Promise<GetModelMetadataResponse>}
172 *
173 * @example
174 * const {BigQuery} = require('@google-cloud/bigquery');
175 * const bigquery = new BigQuery();
176 * const dataset = bigquery.dataset('my-dataset');
177 * const model = dataset.model('my-model');
178 *
179 * model.getMetadata((err, metadata, apiResponse) => {});
180 *
181 * @example <caption>If the callback is omitted we'll return a Promise.</caption>
182 * const [metadata, apiResponse] = await model.getMetadata();
183 */
184 getMetadata: true,
185 /**
186 * @callback SetModelMetadataCallback
187 * @param {?Error} err Request error, if any.
188 * @param {object} metadata The model metadata.
189 * @param {object} apiResponse The full API response.
190 */
191 /**
192 * @typedef {array} SetModelMetadataResponse
193 * @property {object} 0 The model metadata.
194 * @property {object} 1 The full API response.
195 */
196 /**
197 * @see [Models: patch API Documentation]{@link https://cloud.google.com/bigquery/docs/reference/rest/v2/models/patch}
198 *
199 * @method Model#setMetadata
200 * @param {object} metadata The metadata key/value object to set.
201 * @param {SetModelMetadataCallback} [callback] The callback function.
202 * @param {?error} callback.err An error returned while making this
203 * request.
204 * @param {object} callback.metadata The updated metadata of the model.
205 * @param {object} callback.apiResponse The full API response.
206 * @returns {Promise<SetModelMetadataResponse>}
207 *
208 * @example
209 * const {BigQuery} = require('@google-cloud/bigquery');
210 * const bigquery = new BigQuery();
211 * const dataset = bigquery.dataset('my-dataset');
212 * const model = dataset.model('my-model');
213 *
214 * const metadata = {
215 * friendlyName: 'TheBestModelEver'
216 * };
217 *
218 * model.setMetadata(metadata, (err, metadata, apiResponse) => {});
219 *
220 * @example <caption>If the callback is omitted we'll return a Promise.</caption>
221 * const [metadata, apiResponse] = await model.setMetadata(metadata);
222 */
223 setMetadata: true,
224 };
225 super({
226 parent: dataset,
227 baseUrl: '/models',
228 id,
229 methods,
230 });
231 this.dataset = dataset;
232 this.bigQuery = dataset.bigQuery;
233 }
234 /**
235 * @callback JobCallback
236 * @param {?Error} err Request error, if any.
237 * @param {object} Job The [Job]{@link https://cloud.google.com/bigquery/docs/reference/v2/Job} resource.
238 * @param {object} apiResponse The full API response.
239 */
240 /**
241 * @typedef {array} JobResponse
242 * @property {object} 0 The [Job]{@link https://cloud.google.com/bigquery/docs/reference/v2/Job} resource.
243 * @property {object} 1 The full API response.
244 */
245 /**
246 * Export model to Cloud Storage.
247 *
248 * @see [Jobs: insert API Documentation]{@link https://cloud.google.com/bigquery/docs/reference/v2/jobs/insert}
249 *
250 * @param {string|File} destination Where the model should be exported
251 * to. A string or {@link
252 * https://googleapis.dev/nodejs/storage/latest/File.html File}
253 * object.
254 * @param {object} [options] The configuration object. For all extract job options, see [CreateExtractJobOptions]{@link https://cloud.google.com/bigquery/docs/reference/rest/v2/Job#JobConfigurationExtract}.
255 * @param {string} [options.format] The format to export the data in.
256 * Allowed options are "ML_TF_SAVED_MODEL" or "ML_XGBOOST_BOOSTER".
257 * Default: "ML_TF_SAVED_MODEL".
258 * @param {string} [options.jobId] Custom job id.
259 * @param {string} [options.jobPrefix] Prefix to apply to the job id.
260 * @param {JobCallback} [callback] The callback function.
261 * @param {?error} callback.err An error returned while making this request.
262 * @param {Job} callback.job The job used to export the model.
263 * @param {object} callback.apiResponse The full API response.
264 * @returns {Promise<JobResponse>}
265 *
266 * @throws {Error} If a destination isn't a string or File object.
267 *
268 * @example
269 * const {BigQuery} = require('@google-cloud/bigquery');
270 * const bigquery = new BigQuery();
271 * const dataset = bigquery.dataset('my-dataset');
272 * const model = dataset.model('my-model');
273 *
274 * const extractedModel = 'gs://my-bucket/extracted-model';
275 *
276 * function callback(err, job, apiResponse) {
277 * // `job` is a Job object that can be used to check the status of the
278 * // request.
279 * }
280 *
281 * //-
282 * // To use the default options, just pass a string or a {@link
283 * https://googleapis.dev/nodejs/storage/latest/File.html File}
284 * object.
285 * //
286 * // Note: The default format is 'ML_TF_SAVED_MODEL'.
287 * //-
288 * model.createExtractJob(extractedModel, callback);
289 *
290 * //-
291 * // If you need more customization, pass an `options` object.
292 * //-
293 * const options = {
294 * format: 'ML_TF_SAVED_MODEL',
295 * jobId: '123abc'
296 * };
297 *
298 * model.createExtractJob(extractedModel, options, callback);
299 *
300 * //-
301 * // If the callback is omitted, we'll return a Promise.
302 * //-
303 * model.createExtractJob(extractedModel, options).then((data) => {
304 * const job = data[0];
305 * const apiResponse = data[1];
306 * });
307 */
308 createExtractJob(destination, optionsOrCallback, cb) {
309 let options = typeof optionsOrCallback === 'object' ? optionsOrCallback : {};
310 const callback = typeof optionsOrCallback === 'function' ? optionsOrCallback : cb;
311 options = extend(true, options, {
312 destinationUris: arrify(destination).map(dest => {
313 if (common.util.isCustomType(dest, 'storage/file')) {
314 return ('gs://' + dest.bucket.name + '/' + dest.name);
315 }
316 if (typeof dest === 'string') {
317 return dest;
318 }
319 throw new Error('Destination must be a string or a File object.');
320 }),
321 });
322 if (options.format) {
323 options.format = options.format.toUpperCase();
324 if (FORMATS.includes(options.format)) {
325 options.destinationFormat = options.format;
326 delete options.format;
327 }
328 else {
329 throw new Error('Destination format not recognized: ' + options.format);
330 }
331 }
332 // eslint-disable-next-line @typescript-eslint/no-explicit-any
333 const body = {
334 configuration: {
335 extract: extend(true, options, {
336 sourceModel: {
337 datasetId: this.dataset.id,
338 projectId: this.bigQuery.projectId,
339 modelId: this.id,
340 },
341 }),
342 },
343 };
344 if (options.jobPrefix) {
345 body.jobPrefix = options.jobPrefix;
346 delete options.jobPrefix;
347 }
348 if (options.jobId) {
349 body.jobId = options.jobId;
350 delete options.jobId;
351 }
352 this.bigQuery.createJob(body, callback);
353 }
354 /**
355 * @callback JobMetadataCallback
356 * @param {?Error} err Request error, if any.
357 * @param {object} metadata The job metadata.
358 * @param {object} apiResponse The full API response.
359 */
360 /**
361 * @typedef {array} JobMetadataResponse
362 * @property {object} 0 The job metadata.
363 * @property {object} 1 The full API response.
364 */
365 /**
366 * Export model to Cloud Storage.
367 *
368 * @param {string|File} destination Where the model should be exported
369 * to. A string or {@link
370 * https://googleapis.dev/nodejs/storage/latest/File.html File}
371 * object.
372 * @param {object} [options] The configuration object. For all extract job options, see [CreateExtractJobOptions]{@link https://cloud.google.com/bigquery/docs/reference/rest/v2/Job#JobConfigurationExtract}.
373 * @param {string} [options.format] The format to export
374 * the data in. Allowed options are "ML_TF_SAVED_MODEL" or
375 * "ML_XGBOOST_BOOSTER". Default: "ML_TF_SAVED_MODEL".
376 * @param {string} [options.jobId] Custom id for the underlying job.
377 * @param {string} [options.jobPrefix] Prefix to apply to the underlying job id.
378 * @param {JobMetadataCallback} [callback] The callback function.
379 * @param {?error} callback.err An error returned while making this request
380 * @param {object} callback.apiResponse The full API response.
381 * @returns {Promise<JobMetadataResponse>}
382 *
383 * @throws {Error} If destination isn't a string or File object.
384 *
385 * @example
386 * const {BigQuery} = require('@google-cloud/bigquery');
387 * const bigquery = new BigQuery();
388 * const dataset = bigquery.dataset('my-dataset');
389 * const model = dataset.model('my-model');
390 *
391 * const extractedModel = 'gs://my-bucket/extracted-model';
392 *
393 *
394 * //-
395 * function callback(err, job, apiResponse) {
396 * // `job` is a Job object that can be used to check the status of the
397 * // request.
398 * }
399 *
400 * //-
401 * // To use the default options, just pass a string or a {@link
402 * https://googleapis.dev/nodejs/storage/latest/File.html File}
403 * object.
404 * //
405 * // Note: The default format is 'ML_TF_SAVED_MODEL'.
406 * //-
407 * model.createExtractJob(extractedModel, callback);
408 *
409 * //-
410 * // If you need more customization, pass an `options` object.
411 * //-
412 * const options = {
413 * format: 'ML_TF_SAVED_MODEL',
414 * jobId: '123abc'
415 * };
416 *
417 * model.createExtractJob(extractedModel, options, callback);
418 *
419 * //-
420 * // If the callback is omitted, we'll return a Promise.
421 * //-
422 * model.createExtractJob(extractedModel, options).then((data) => {
423 * const job = data[0];
424 * const apiResponse = data[1];
425 * });
426 */
427 extract(destination, optionsOrCallback, cb) {
428 const options = typeof optionsOrCallback === 'object' ? optionsOrCallback : {};
429 const callback = typeof optionsOrCallback === 'function' ? optionsOrCallback : cb;
430 this.createExtractJob(destination, options, (err, job, resp) => {
431 if (err) {
432 callback(err, resp);
433 return;
434 }
435 job.on('error', callback).on('complete', metadata => {
436 callback(null, metadata);
437 });
438 });
439 }
440}
441exports.Model = Model;
442/*! Developer Documentation
443 *
444 * All async methods (except for streams) will return a Promise in the event
445 * that a callback is omitted.
446 */
447promisify_1.promisifyAll(Model);
448//# sourceMappingURL=model.js.map
\No newline at end of file