Skip to content

Commit

Permalink
Merge pull request #240 from jdpedrie/translate-update
Browse files Browse the repository at this point in the history
Update Translate API Client
  • Loading branch information
jdpedrie authored Nov 14, 2016
2 parents e7d59f9 + f89aa4a commit f198981
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 48 deletions.
8 changes: 4 additions & 4 deletions src/ServiceBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -268,10 +268,10 @@ public function vision(array $config = [])
* more information at
* [Google Translate docs](https://cloud.google.com/translate/docs/).
*
* Please note that unlike most other Cloud Platform services Google
* Translate requires a public API access key and cannot currently be
* accessed with a service account or application default credentials.
* Follow the
* Please note that while Google Translate supports authentication via service
* account and application default credentials like other Cloud Platform APIs,
* it also supports authentication via a public API access key. If you wish to
* authenticate using an API key, follow the
* [before you begin](https://cloud.google.com/translate/v2/translating-text-with-rest#before-you-begin)
* instructions to learn how to generate a key.
*
Expand Down
2 changes: 1 addition & 1 deletion src/Translate/Connection/Rest.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class Rest implements ConnectionInterface
use RestTrait;
use UriTrait;

const BASE_URI = 'https://www.googleapis.com/language/translate/';
const BASE_URI = 'https://translation.googleapis.com/language/translate/';

/**
* @param array $config
Expand Down
12 changes: 9 additions & 3 deletions src/Translate/Connection/ServiceDefinition/translate-v2.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@
},
"documentationLink": "https://developers.google.com/translate/v2/using_rest",
"protocol": "rest",
"baseUrl": "https://www.googleapis.com/language/translate/",
"baseUrl": "https://translation.googleapis.com/language/translate/",
"basePath": "/language/translate/",
"rootUrl": "https://www.googleapis.com/",
"rootUrl": "https://translation.googleapis.com/",
"servicePath": "language/translate/",
"batchPath": "batch",
"parameters": {
Expand Down Expand Up @@ -221,6 +221,12 @@
"repeated": true,
"location": "query"
},
"model": {
"type": "string",
"description": "The model to use",
"repeated": false,
"location": "query"
},
"format": {
"type": "string",
"description": "The format of the text",
Expand Down Expand Up @@ -264,4 +270,4 @@
}
}
}
}
}
97 changes: 69 additions & 28 deletions src/Translate/TranslateClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,18 @@
* information at
* [Google Translate docs](https://cloud.google.com/translate/docs/).
*
* Please note that unlike most other Cloud Platform services Google Translate
* requires a public API access key and cannot currently be accessed with a
* service account or application default credentials. Follow the
* Please note that while Google Translate supports authentication via service
* account and application default credentials like other Cloud Platform APIs,
* it also supports authentication via a public API access key. If you wish to
* authenticate using an API key, follow the
* [before you begin](https://cloud.google.com/translate/v2/translating-text-with-rest#before-you-begin)
* instructions to learn how to generate a key.
*
* Example:
* ```
* use Google\Cloud\ServiceBuilder;
*
* $cloud = new ServiceBuilder([
* 'key' => 'YOUR_KEY'
* ]);
* $cloud = new ServiceBuilder();
*
* $translate = $cloud->translate();
* ```
Expand All @@ -52,9 +51,7 @@
* // TranslateClient can be instantiated directly.
* use Google\Cloud\Translate\TranslateClient;
*
* $translate = new TranslateClient([
* 'key' => 'YOUR_KEY'
* ]);
* $translate = new TranslateClient();
* ```
*/
class TranslateClient
Expand All @@ -63,6 +60,8 @@ class TranslateClient

const ENGLISH_LANGUAGE_CODE = 'en';

const FULL_CONTROL_SCOPE = 'https://www.googleapis.com/auth/cloud-platform';

/**
* @var ConnectionInterface
*/
Expand All @@ -83,30 +82,53 @@ class TranslateClient
* @type string $target The target language to assign to the client.
* Must be a valid ISO 639-1 language code. **Defaults to** `"en"`
* (English).
* @type int $retries Number of retries for a failed request.
* **Defaults to** `3`.
* @type string $projectId The project ID from the Google Developer's
* Console.
* @type CacheItemPoolInterface $authCache A cache used storing access
* tokens. **Defaults to** a simple in memory implementation.
* @type array $authCacheOptions Cache configuration options.
* @type callable $authHttpHandler A handler used to deliver Psr7
* requests specifically for authentication.
* @type callable $httpHandler A handler used to deliver Psr7 requests.
* Only valid for requests sent over REST.
* @type string $keyFile The contents of the service account
* credentials .json file retrieved from the Google Developers
* Console.
* @type string $keyFilePath The full path to your service account
* credentials .json file retrieved from the Google Developers
* Console.
* @type int $retries Number of retries for a failed request.
* **Defaults to** `3`.
* @type array $scopes Scopes to be used for the request.
* }
* @throws \InvalidArgumentException
*/
public function __construct(array $config = [])
{
if (!isset($config['key'])) {
throw new \InvalidArgumentException('A key is required.');
}
$this->key = (isset($config['key']))
? $config['key']
: null;

$this->key = $config['key'];
$this->targetLanguage = isset($config['target'])
? $config['target']
: self::ENGLISH_LANGUAGE_CODE;

if (!isset($config['scopes'])) {
$config['scopes'] = [self::FULL_CONTROL_SCOPE];
}

if (!$this->key) {
$config = $this->configureAuthentication($config);
} else {
$config['shouldSignRequest'] = false;
}

unset($config['key']);
unset($config['target']);

$this->connection = new Rest($config + [
'shouldSignRequest' => false
]);
$this->connection = new Rest($config);
}

/**
Expand Down Expand Up @@ -134,15 +156,20 @@ public function __construct(array $config = [])
* @type string $format Indicates whether the string to be translated is
* either plain-text or HTML. Acceptable values are `html` or
* `text`. **Defaults to** `"html"`.
* @type string $model The model to use for the translation request. May
* be `nmt` or `base`. **Defaults to** an empty string.
* }
* @return array A translation result including a `source` key containing
* @return array|null A translation result including a `source` key containing
* the detected or provided langauge of the provided input, an
* `input` key containing the original string, and a `text` key
* containing the translated result.
*/
public function translate($string, array $options = [])
{
return $this->translateBatch([$string], $options)[0];
$res = $this->translateBatch([$string], $options);
if (count($res) > 0) {
return $res[0];
}
}

/**
Expand Down Expand Up @@ -175,6 +202,8 @@ public function translate($string, array $options = [])
* @type string $format Indicates whether the string to be translated is
* either plain-text or HTML. Acceptable values are `html` or
* `text`. **Defaults to** `"html"`.
* @type string $model The model to use for the translation request. May
* be `nmt` or `base`. **Defaults to** an empty string.
* }
* @return array A set of translation results. Each result includes a
* `source` key containing the detected or provided language of the
Expand All @@ -183,24 +212,36 @@ public function translate($string, array $options = [])
*/
public function translateBatch(array $strings, array $options = [])
{
$options += [
'model' => '',
];

$response = $this->connection->listTranslations($options + [
'q' => $strings,
'key' => $this->key,
'target' => $this->targetLanguage
'target' => $this->targetLanguage,
'model' => $options['model']
]);

$translations = [];

foreach ($response['data']['translations'] as $key => $translation) {
$source = isset($translation['detectedSourceLanguage'])
? $translation['detectedSourceLanguage']
: $options['source'];
if (isset($response['data']['translations'])) {
foreach ($response['data']['translations'] as $key => $translation) {
$source = isset($translation['detectedSourceLanguage'])
? $translation['detectedSourceLanguage']
: $options['source'];

$translations[] = [
'source' => $source,
'input' => $strings[$key],
'text' => $translation['translatedText']
];
$model = (isset($translation['model']))
? $translation['model']
: null;

$translations[] = [
'source' => $source,
'input' => $strings[$key],
'text' => $translation['translatedText'],
'model' => $model
];
}
}

return $translations;
Expand Down
63 changes: 51 additions & 12 deletions tests/unit/Translate/TranslateClientTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,18 @@ public function setUp()
$this->connection = $this->prophesize(ConnectionInterface::class);
}

/**
* @expectedException \InvalidArgumentException
*/
public function testThrowsExceptionWithNoKey()
public function testWithNoKey()
{
$client = new TranslateClient();
$client = new TranslateTestClient();

$this->connection->listTranslations(Argument::that(function($args) {
if (!is_null($args['key'])) return false;
return true;
}))->shouldBeCalled()->willReturn([]);

$client->setConnection($this->connection->reveal());

$client->translate('foo');
}

public function testTranslate()
Expand All @@ -50,7 +56,8 @@ public function testTranslate()
$options = [
'source' => $expected['source'],
'target' => 'de',
'format' => 'text'
'format' => 'text',
'model' => 'base'
];
$this->connection
->listTranslations($options + [
Expand All @@ -71,6 +78,35 @@ public function testTranslate()
$this->assertEquals($expected, $translation);
}

public function testTranslateWithNmtModel()
{
$expected = $this->getTranslateExpectedData('translate', 'translated', 'en', 'nmt');

$options = [
'source' => $expected['source'],
'target' => 'de',
'format' => 'text',
'model' => 'nmt'
];
$this->connection
->listTranslations($options + [
'q' => [$expected['input']],
'key' => $this->key
])
->willReturn([
'data' => [
'translations' => [
$this->getTranslateApiData($expected['text'], null, 'nmt')
]
]
])
->shouldBeCalledTimes(1);
$this->client->setConnection($this->connection->reveal());
$translation = $this->client->translate($expected['input'], $options);

$this->assertEquals($expected, $translation);
}

public function testTranslateBatch()
{
$expected1 = $this->getTranslateExpectedData('translate', 'translated', 'en');
Expand All @@ -81,7 +117,8 @@ public function testTranslateBatch()
->listTranslations([
'target' => $target,
'q' => $stringsToTranslate,
'key' => $this->key
'key' => $this->key,
'model' => 'base'
])
->willReturn([
'data' => [
Expand All @@ -94,7 +131,7 @@ public function testTranslateBatch()
->shouldBeCalledTimes(1);
$client = new TranslateTestClient(['key' => $this->key, 'target' => $target]);
$client->setConnection($this->connection->reveal());
$translations = $client->translateBatch($stringsToTranslate);
$translations = $client->translateBatch($stringsToTranslate, ['model' => 'base']);

$this->assertEquals($expected1, $translations[0]);
$this->assertEquals($expected2, $translations[1]);
Expand Down Expand Up @@ -197,20 +234,22 @@ public function testLanguages()
$this->assertEquals($expectedLanguage, $languages[0]);
}

private function getTranslateApiData($translatedText, $source = null)
private function getTranslateApiData($translatedText, $source = null, $model = 'base')
{
return array_filter([
'translatedText' => $translatedText,
'detectedSourceLanguage' => $source
'detectedSourceLanguage' => $source,
'model' => $model
]);
}

private function getTranslateExpectedData($textToTranslate, $translatedText, $source)
private function getTranslateExpectedData($textToTranslate, $translatedText, $source, $model = 'base')
{
return [
'text' => $translatedText,
'source' => $source,
'input' => $textToTranslate
'input' => $textToTranslate,
'model' => $model
];
}

Expand Down

0 comments on commit f198981

Please sign in to comment.