Skip to content

Commit 6e9ae57

Browse files
callmehiphopstephenplusplus
authored andcommitted
translate: api updates (googleapis#1781)
1 parent 556b345 commit 6e9ae57

4 files changed

Lines changed: 260 additions & 98 deletions

File tree

packages/translate/README.md

Lines changed: 67 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,14 @@
66
- [API Documentation][gcloud-translate-docs]
77
- [Official Documentation][cloud-translate-docs]
88

9-
**An API key is required for Translate.** See [Identifying your application to Google][api-key-howto].
10-
119

1210
```sh
1311
$ npm install --save @google-cloud/translate
1412
```
1513
```js
1614
var translate = require('@google-cloud/translate')({
17-
key: 'API Key'
15+
projectId: 'grape-spaceship-123',
16+
keyFilename: '/path/to/keyfile.json'
1817
});
1918

2019
// Translate a string of text.
@@ -59,6 +58,71 @@ var translate = require('@google-cloud/translate')({
5958
```
6059

6160

61+
## Authentication
62+
63+
It's incredibly easy to get authenticated and start using Google's APIs. You can set your credentials on a global basis as well as on a per-API basis. See each individual API section below to see how you can auth on a per-API-basis. This is useful if you want to use different accounts for different Google Cloud services.
64+
65+
### On Google Compute Engine
66+
67+
If you are running this client on Google Compute Engine, we handle authentication for you with no configuration. You just need to make sure that when you [set up the GCE instance][gce-how-to], you add the correct scopes for the APIs you want to access.
68+
69+
``` js
70+
// Authenticating on a global basis.
71+
var projectId = process.env.GCLOUD_PROJECT; // E.g. 'grape-spaceship-123'
72+
73+
var translate = require('@google-cloud/translate')({
74+
projectId: projectId
75+
});
76+
77+
// ...you're good to go!
78+
```
79+
80+
### With a Google Developers Service Account
81+
82+
If you are not running this client on Google Compute Engine, you need a Google Developers service account. To create a service account:
83+
84+
1. Visit the [Google Developers Console][dev-console].
85+
2. Create a new project or click on an existing project.
86+
3. Navigate to **APIs & auth** > **APIs section** and turn on the following APIs (you may need to enable billing in order to use these services):
87+
* Google Translate API
88+
4. Navigate to **APIs & auth** > **Credentials** and then:
89+
* If you want to use a new service account, click on **Create new Client ID** and select **Service account**. After the account is created, you will be prompted to download the JSON key file that the library uses to authenticate your requests.
90+
* If you want to generate a new key for an existing service account, click on **Generate new JSON key** and download the JSON key file.
91+
92+
``` js
93+
var projectId = process.env.GCLOUD_PROJECT; // E.g. 'grape-spaceship-123'
94+
95+
var translate = require('@google-cloud/translate')({
96+
projectId: projectId,
97+
98+
// The path to your key file:
99+
keyFilename: '/path/to/keyfile.json'
100+
101+
// Or the contents of the key file:
102+
credentials: require('./path/to/keyfile.json')
103+
});
104+
105+
// ...you're good to go!
106+
```
107+
108+
### With an API key
109+
110+
It's also possible to authenticate with an API key. To create an API key:
111+
112+
1. Visit the [Google Developers Console][dev-console].
113+
2. Create a new project or click on an existing project.
114+
3. Navigate to **APIs & auth** > **APIs section** and turn on the following APIs (you may need to enable billing in order to use these services):
115+
* Google Translate API
116+
4. Navigate to **APIs & auth** > **Credentials** and then click on **Create new Client ID** and select **API key**. You should then be presented with a pop-up containing your newly created key.
117+
118+
```js
119+
var translate = require('@google-cloud/translate')({
120+
key: 'API Key'
121+
});
122+
123+
// ...you're good to go!
124+
```
125+
62126
[google-cloud]: https://github.com/GoogleCloudPlatform/google-cloud-node/
63127
[api-key-howto]: https://cloud.google.com/translate/v2/using_rest#auth
64128
[gcloud-translate-docs]: https://googlecloudplatform.github.io/google-cloud-node/#/docs/translate

packages/translate/src/index.js

Lines changed: 45 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ var extend = require('extend');
2626
var is = require('is');
2727
var isHtml = require('is-html');
2828
var prop = require('propprop');
29+
var util = require('util');
2930

3031
var PKG = require('../package.json');
3132

@@ -40,9 +41,6 @@ var PKG = require('../package.json');
4041
* [Pricing](https://cloud.google.com/translate/v2/pricing.html) and
4142
* [FAQ](https://cloud.google.com/translate/v2/faq.html) pages for details.
4243
*
43-
* **An API key is required for Translate.** See
44-
* [Identifying your application to Google](https://cloud.google.com/translate/v2/using_rest#auth).
45-
*
4644
* @constructor
4745
* @alias module:translate
4846
*
@@ -52,7 +50,7 @@ var PKG = require('../package.json');
5250
* @throws {Error} If an API key is not provided.
5351
*
5452
* @param {object} options - [Configuration object](#/docs).
55-
* @param {string} options.key - An API key.
53+
* @param {string=} options.key - An API key.
5654
*
5755
* @example
5856
* //-
@@ -70,21 +68,30 @@ function Translate(options) {
7068
return new Translate(options);
7169
}
7270

73-
if (!options.key) {
74-
throw new Error('An API key is required to use the Translate API.');
75-
}
76-
77-
this.baseUrl = 'https://www.googleapis.com/language/translate/v2';
71+
var baseUrl = 'https://translation.googleapis.com/language/translate/v2';
7872

7973
if (process.env.GOOGLE_CLOUD_TRANSLATE_ENDPOINT) {
80-
this.baseUrl = process.env.GOOGLE_CLOUD_TRANSLATE_ENDPOINT
74+
baseUrl = process.env.GOOGLE_CLOUD_TRANSLATE_ENDPOINT
8175
.replace(/\/+$/, '');
8276
}
8377

84-
this.options = options;
85-
this.key = options.key;
78+
if (options.key) {
79+
this.options = options;
80+
this.key = options.key;
81+
}
82+
83+
var config = {
84+
baseUrl: baseUrl,
85+
scopes: ['https://www.googleapis.com/auth/cloud-platform'],
86+
packageJson: require('../package.json'),
87+
projectIdRequired: false
88+
};
89+
90+
common.Service.call(this, config, options);
8691
}
8792

93+
util.inherits(Translate, common.Service);
94+
8895
/**
8996
* Detect the language used in a string or multiple strings.
9097
*
@@ -153,9 +160,9 @@ Translate.prototype.detect = function(input, callback) {
153160
input = arrify(input);
154161

155162
this.request({
163+
method: 'POST',
156164
uri: '/detect',
157-
useQuerystring: true,
158-
qs: {
165+
json: {
159166
q: input
160167
}
161168
}, function(err, resp) {
@@ -303,6 +310,9 @@ Translate.prototype.getLanguages = function(target, callback) {
303310
* not, we set the format as `text`.
304311
* @param {string} options.from - The ISO 639-1 language code the source input
305312
* is written in.
313+
* @param {string} options.model - **Note:** Users must be whitelisted to use
314+
* this parameter. Set the model type requested for this translation. Please
315+
* refer to the upstream documentation for possible values.
306316
* @param {string} options.to - The ISO 639-1 language code to translate the
307317
* input to.
308318
* @param {function} callback - The callback function.
@@ -366,31 +376,35 @@ Translate.prototype.getLanguages = function(target, callback) {
366376
Translate.prototype.translate = function(input, options, callback) {
367377
input = arrify(input);
368378

369-
var query = {
379+
var body = {
370380
q: input,
371381
format: options.format || (isHtml(input[0]) ? 'html' : 'text')
372382
};
373383

374384
if (is.string(options)) {
375-
query.target = options;
385+
body.target = options;
376386
} else {
377387
if (options.from) {
378-
query.source = options.from;
388+
body.source = options.from;
379389
}
380390

381391
if (options.to) {
382-
query.target = options.to;
392+
body.target = options.to;
393+
}
394+
395+
if (options.model) {
396+
body.model = options.model;
383397
}
384398
}
385399

386-
if (!query.target) {
400+
if (!body.target) {
387401
throw new Error('A target language is required to perform a translation.');
388402
}
389403

390404
this.request({
405+
method: 'POST',
391406
uri: '',
392-
useQuerystring: true,
393-
qs: query
407+
json: body
394408
}, function(err, resp) {
395409
if (err) {
396410
callback(err, null, resp);
@@ -399,7 +413,7 @@ Translate.prototype.translate = function(input, options, callback) {
399413

400414
var translations = resp.data.translations.map(prop('translatedText'));
401415

402-
if (query.q.length === 1) {
416+
if (body.q.length === 1) {
403417
translations = translations[0];
404418
}
405419

@@ -408,17 +422,22 @@ Translate.prototype.translate = function(input, options, callback) {
408422
};
409423

410424
/**
411-
* A custom request implementation. Requests to this API use an API key for an
412-
* application, not a bearer token from a service account. This means we skip
413-
* the `makeAuthenticatedRequest` portion of the typical request lifecycle, and
414-
* manually authenticate the request here.
425+
* A custom request implementation. Requests to this API may optionally use an
426+
* API key for an application, not a bearer token from a service account. This
427+
* means it is possible to skip the `makeAuthenticatedRequest` portion of the
428+
* typical request lifecycle, and manually authenticate the request here.
415429
*
416430
* @private
417431
*
418432
* @param {object} reqOpts - Request options that are passed to `request`.
419433
* @param {function} callback - The callback function passed to `request`.
420434
*/
421435
Translate.prototype.request = function(reqOpts, callback) {
436+
if (!this.key) {
437+
common.Service.prototype.request.call(this, reqOpts, callback);
438+
return;
439+
}
440+
422441
reqOpts.uri = this.baseUrl + reqOpts.uri;
423442

424443
reqOpts = extend(true, {}, reqOpts, {

packages/translate/system-test/translate.js

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,8 @@ var Translate = require('../');
2525

2626
var API_KEY = process.env.GCLOUD_TESTS_API_KEY;
2727

28-
// Only run the tests if there is an API key to test with.
29-
(API_KEY ? describe : describe.skip)('translate', function() {
30-
if (!API_KEY) {
31-
// The test runner still executes this function, even if it is skipped.
32-
return;
33-
}
34-
35-
var translate = new Translate(extend({}, env, { key: API_KEY }));
28+
describe('translate', function() {
29+
var translate = new Translate(extend({}, env));
3630

3731
describe('detecting language from input', function() {
3832
var INPUT = [
@@ -153,4 +147,14 @@ var API_KEY = process.env.GCLOUD_TESTS_API_KEY;
153147
});
154148
});
155149
});
150+
151+
(API_KEY ? describe : describe.skip)('authentication', function() {
152+
beforeEach(function() {
153+
translate = new Translate({ key: API_KEY });
154+
});
155+
156+
it('should use an API key to authenticate', function(done) {
157+
translate.getLanguages(done);
158+
});
159+
});
156160
});

0 commit comments

Comments
 (0)