Skip to content
This repository has been archived by the owner on Jul 20, 2023. It is now read-only.

Commit

Permalink
feat: load protos from JSON, grpc-fallback support
Browse files Browse the repository at this point in the history
  • Loading branch information
yoshi-automation authored and alexander-fenster committed Sep 6, 2019
1 parent 1a9c374 commit 9914445
Show file tree
Hide file tree
Showing 25 changed files with 9,089 additions and 307 deletions.
8,497 changes: 8,496 additions & 1 deletion protos/protos.json

Large diffs are not rendered by default.

21 changes: 21 additions & 0 deletions src/browser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

'use strict';

// Set a flag that we are running in a browser bundle.
global.isBrowser = true;

// Re-export all exports from ./index.js.
module.exports = require('./index');
91 changes: 54 additions & 37 deletions src/v1/image_annotator_client.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
const gapicConfig = require('./image_annotator_client_config.json');
const gax = require('google-gax');
const path = require('path');
const protobuf = require('protobufjs');

const VERSION = require('../../package.json').version;

Expand Down Expand Up @@ -61,6 +60,16 @@ class ImageAnnotatorClient {
opts = opts || {};
this._descriptors = {};

if (global.isBrowser) {
// If we're in browser, we use gRPC fallback.
opts.fallback = true;
}

// If we are in browser, we are already using fallback because of the
// "browser" field in package.json.
// But if we were explicitly requested to use fallback, let's do it now.
const gaxModule = !global.isBrowser && opts.fallback ? gax.fallback : gax;

const servicePath =
opts.servicePath || opts.apiEndpoint || this.constructor.servicePath;

Expand All @@ -77,43 +86,51 @@ class ImageAnnotatorClient {
// Create a `gaxGrpc` object, with any grpc-specific options
// sent to the client.
opts.scopes = this.constructor.scopes;
const gaxGrpc = new gax.GrpcClient(opts);
const gaxGrpc = new gaxModule.GrpcClient(opts);

// Save the auth object to the client, for use by other methods.
this.auth = gaxGrpc.auth;

// Determine the client header string.
const clientHeader = [
`gl-node/${process.versions.node}`,
`grpc/${gaxGrpc.grpcVersion}`,
`gax/${gax.version}`,
`gapic/${VERSION}`,
];
const clientHeader = [];

if (typeof process !== 'undefined' && 'versions' in process) {
clientHeader.push(`gl-node/${process.versions.node}`);
}
clientHeader.push(`gax/${gaxModule.version}`);
if (opts.fallback) {
clientHeader.push(`gl-web/${gaxModule.version}`);
} else {
clientHeader.push(`grpc/${gaxGrpc.grpcVersion}`);
}
clientHeader.push(`gapic/${VERSION}`);
if (opts.libName && opts.libVersion) {
clientHeader.push(`${opts.libName}/${opts.libVersion}`);
}

// Load the applicable protos.
const protos = gaxGrpc.loadProto(
path.join(__dirname, '..', '..', 'protos'),
['google/cloud/vision/v1/image_annotator.proto']
// For Node.js, pass the path to JSON proto file.
// For browsers, pass the JSON content.

const nodejsProtoPath = path.join(
__dirname,
'..',
'..',
'protos',
'protos.json'
);
let protoFilesRoot = new gax.GoogleProtoFilesRoot();
protoFilesRoot = protobuf.loadSync(
path.join(
__dirname,
'..',
'..',
'protos',
'google/cloud/vision/v1/image_annotator.proto'
),
protoFilesRoot
const protos = gaxGrpc.loadProto(
opts.fallback ? require('../../protos/protos.json') : nodejsProtoPath
);

const protoFilesRoot = opts.fallback
? gaxModule.protobuf.Root.fromJSON(require('../../protos/protos.json'))
: gaxModule.protobuf.loadSync(nodejsProtoPath);

// This API contains "long-running operations", which return a
// an Operation object that allows for tracking of the operation,
// rather than holding a request open.
this.operationsClient = new gax.lro({
this.operationsClient = new gaxModule.lro({
auth: gaxGrpc.auth,
grpc: gaxGrpc.grpc,
}).operationsClient(opts);
Expand All @@ -132,7 +149,7 @@ class ImageAnnotatorClient {
);

this._descriptors.longrunning = {
asyncBatchAnnotateImages: new gax.LongrunningDescriptor(
asyncBatchAnnotateImages: new gaxModule.LongrunningDescriptor(
this.operationsClient,
asyncBatchAnnotateImagesResponse.decode.bind(
asyncBatchAnnotateImagesResponse
Expand All @@ -141,7 +158,7 @@ class ImageAnnotatorClient {
asyncBatchAnnotateImagesMetadata
)
),
asyncBatchAnnotateFiles: new gax.LongrunningDescriptor(
asyncBatchAnnotateFiles: new gaxModule.LongrunningDescriptor(
this.operationsClient,
asyncBatchAnnotateFilesResponse.decode.bind(
asyncBatchAnnotateFilesResponse
Expand All @@ -168,7 +185,9 @@ class ImageAnnotatorClient {
// Put together the "service stub" for
// google.cloud.vision.v1.ImageAnnotator.
const imageAnnotatorStub = gaxGrpc.createStub(
protos.google.cloud.vision.v1.ImageAnnotator,
opts.fallback
? protos.lookupService('google.cloud.vision.v1.ImageAnnotator')
: protos.google.cloud.vision.v1.ImageAnnotator,
opts
);

Expand All @@ -181,18 +200,16 @@ class ImageAnnotatorClient {
'asyncBatchAnnotateFiles',
];
for (const methodName of imageAnnotatorStubMethods) {
this._innerApiCalls[methodName] = gax.createApiCall(
imageAnnotatorStub.then(
stub =>
function() {
const args = Array.prototype.slice.call(arguments, 0);
return stub[methodName].apply(stub, args);
},
err =>
function() {
throw err;
}
),
const innerCallPromise = imageAnnotatorStub.then(
stub => (...args) => {
return stub[methodName].apply(stub, args);
},
err => () => {
throw err;
}
);
this._innerApiCalls[methodName] = gaxModule.createApiCall(
innerCallPromise,
defaults[methodName],
this._descriptors.longrunning[methodName]
);
Expand Down
3 changes: 3 additions & 0 deletions src/v1/image_annotator_proto_list.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[
"../../protos/google/cloud/vision/v1/image_annotator.proto"
]
107 changes: 62 additions & 45 deletions src/v1/product_search_client.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
const gapicConfig = require('./product_search_client_config.json');
const gax = require('google-gax');
const path = require('path');
const protobuf = require('protobufjs');

const VERSION = require('../../package.json').version;

Expand Down Expand Up @@ -74,6 +73,16 @@ class ProductSearchClient {
opts = opts || {};
this._descriptors = {};

if (global.isBrowser) {
// If we're in browser, we use gRPC fallback.
opts.fallback = true;
}

// If we are in browser, we are already using fallback because of the
// "browser" field in package.json.
// But if we were explicitly requested to use fallback, let's do it now.
const gaxModule = !global.isBrowser && opts.fallback ? gax.fallback : gax;

const servicePath =
opts.servicePath || opts.apiEndpoint || this.constructor.servicePath;

Expand All @@ -90,42 +99,57 @@ class ProductSearchClient {
// Create a `gaxGrpc` object, with any grpc-specific options
// sent to the client.
opts.scopes = this.constructor.scopes;
const gaxGrpc = new gax.GrpcClient(opts);
const gaxGrpc = new gaxModule.GrpcClient(opts);

// Save the auth object to the client, for use by other methods.
this.auth = gaxGrpc.auth;

// Determine the client header string.
const clientHeader = [
`gl-node/${process.versions.node}`,
`grpc/${gaxGrpc.grpcVersion}`,
`gax/${gax.version}`,
`gapic/${VERSION}`,
];
const clientHeader = [];

if (typeof process !== 'undefined' && 'versions' in process) {
clientHeader.push(`gl-node/${process.versions.node}`);
}
clientHeader.push(`gax/${gaxModule.version}`);
if (opts.fallback) {
clientHeader.push(`gl-web/${gaxModule.version}`);
} else {
clientHeader.push(`grpc/${gaxGrpc.grpcVersion}`);
}
clientHeader.push(`gapic/${VERSION}`);
if (opts.libName && opts.libVersion) {
clientHeader.push(`${opts.libName}/${opts.libVersion}`);
}

// Load the applicable protos.
// For Node.js, pass the path to JSON proto file.
// For browsers, pass the JSON content.

const nodejsProtoPath = path.join(
__dirname,
'..',
'..',
'protos',
'protos.json'
);
const protos = gaxGrpc.loadProto(
path.join(__dirname, '..', '..', 'protos'),
['google/cloud/vision/v1/product_search_service.proto']
opts.fallback ? require('../../protos/protos.json') : nodejsProtoPath
);

// This API contains "path templates"; forward-slash-separated
// identifiers to uniquely identify resources within the API.
// Create useful helper objects for these.
this._pathTemplates = {
locationPathTemplate: new gax.PathTemplate(
locationPathTemplate: new gaxModule.PathTemplate(
'projects/{project}/locations/{location}'
),
productPathTemplate: new gax.PathTemplate(
productPathTemplate: new gaxModule.PathTemplate(
'projects/{project}/locations/{location}/products/{product}'
),
productSetPathTemplate: new gax.PathTemplate(
productSetPathTemplate: new gaxModule.PathTemplate(
'projects/{project}/locations/{location}/productSets/{product_set}'
),
referenceImagePathTemplate: new gax.PathTemplate(
referenceImagePathTemplate: new gaxModule.PathTemplate(
'projects/{project}/locations/{location}/products/{product}/referenceImages/{reference_image}'
),
};
Expand All @@ -134,43 +158,36 @@ class ProductSearchClient {
// (e.g. 50 results at a time, with tokens to get subsequent
// pages). Denote the keys used for pagination and results.
this._descriptors.page = {
listProductSets: new gax.PageDescriptor(
listProductSets: new gaxModule.PageDescriptor(
'pageToken',
'nextPageToken',
'productSets'
),
listProducts: new gax.PageDescriptor(
listProducts: new gaxModule.PageDescriptor(
'pageToken',
'nextPageToken',
'products'
),
listReferenceImages: new gax.PageDescriptor(
listReferenceImages: new gaxModule.PageDescriptor(
'pageToken',
'nextPageToken',
'referenceImages'
),
listProductsInProductSet: new gax.PageDescriptor(
listProductsInProductSet: new gaxModule.PageDescriptor(
'pageToken',
'nextPageToken',
'products'
),
};
let protoFilesRoot = new gax.GoogleProtoFilesRoot();
protoFilesRoot = protobuf.loadSync(
path.join(
__dirname,
'..',
'..',
'protos',
'google/cloud/vision/v1/product_search_service.proto'
),
protoFilesRoot
);

const protoFilesRoot = opts.fallback
? gaxModule.protobuf.Root.fromJSON(require('../../protos/protos.json'))
: gaxModule.protobuf.loadSync(nodejsProtoPath);

// This API contains "long-running operations", which return a
// an Operation object that allows for tracking of the operation,
// rather than holding a request open.
this.operationsClient = new gax.lro({
this.operationsClient = new gaxModule.lro({
auth: gaxGrpc.auth,
grpc: gaxGrpc.grpc,
}).operationsClient(opts);
Expand All @@ -189,12 +206,12 @@ class ProductSearchClient {
);

this._descriptors.longrunning = {
importProductSets: new gax.LongrunningDescriptor(
importProductSets: new gaxModule.LongrunningDescriptor(
this.operationsClient,
importProductSetsResponse.decode.bind(importProductSetsResponse),
importProductSetsMetadata.decode.bind(importProductSetsMetadata)
),
purgeProducts: new gax.LongrunningDescriptor(
purgeProducts: new gaxModule.LongrunningDescriptor(
this.operationsClient,
purgeProductsResponse.decode.bind(purgeProductsResponse),
purgeProductsMetadata.decode.bind(purgeProductsMetadata)
Expand All @@ -217,7 +234,9 @@ class ProductSearchClient {
// Put together the "service stub" for
// google.cloud.vision.v1.ProductSearch.
const productSearchStub = gaxGrpc.createStub(
protos.google.cloud.vision.v1.ProductSearch,
opts.fallback
? protos.lookupService('google.cloud.vision.v1.ProductSearch')
: protos.google.cloud.vision.v1.ProductSearch,
opts
);

Expand Down Expand Up @@ -245,18 +264,16 @@ class ProductSearchClient {
'purgeProducts',
];
for (const methodName of productSearchStubMethods) {
this._innerApiCalls[methodName] = gax.createApiCall(
productSearchStub.then(
stub =>
function() {
const args = Array.prototype.slice.call(arguments, 0);
return stub[methodName].apply(stub, args);
},
err =>
function() {
throw err;
}
),
const innerCallPromise = productSearchStub.then(
stub => (...args) => {
return stub[methodName].apply(stub, args);
},
err => () => {
throw err;
}
);
this._innerApiCalls[methodName] = gaxModule.createApiCall(
innerCallPromise,
defaults[methodName],
this._descriptors.page[methodName] ||
this._descriptors.longrunning[methodName]
Expand Down
3 changes: 3 additions & 0 deletions src/v1/product_search_proto_list.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[
"../../protos/google/cloud/vision/v1/product_search_service.proto"
]
Loading

0 comments on commit 9914445

Please sign in to comment.