Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update translation #2731

Merged
merged 5 commits into from
Nov 14, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions CONTRIBUTING.rst
Original file line number Diff line number Diff line change
Expand Up @@ -235,8 +235,6 @@ Running System Tests
`docs <https://cloud.google.com/storage/docs/authentication#generating-a-private-key>`__
for more details. In order for Logging system tests to work, the Service Account
will also have to be made a project Owner. This can be changed under "IAM & Admin".
- ``GOOGLE_CLOUD_TESTS_API_KEY``: The API key for your project with
the Google Translate API (and others) enabled.

- Examples of these can be found in ``system_tests/local_test_setup.sample``. We
recommend copying this to ``system_tests/local_test_setup``, editing the
Expand Down
1 change: 0 additions & 1 deletion system_tests/local_test_setup.sample
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
export GOOGLE_APPLICATION_CREDENTIALS="app_credentials.json.sample"
export GOOGLE_CLOUD_TESTING_REMOTE="upstream"
export GOOGLE_CLOUD_TESTING_BRANCH="master"
export GOOGLE_CLOUD_TESTS_API_KEY="abcd1234"
12 changes: 3 additions & 9 deletions system_tests/translate.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,11 @@
# limitations under the License.


import os

import unittest

from google.cloud import translate


ENV_VAR = 'GOOGLE_CLOUD_TESTS_API_KEY'


class Config(object):
"""Run-time configuration to be modified at set-up.

Expand All @@ -33,8 +28,7 @@ class Config(object):


def setUpModule():
api_key = os.getenv(ENV_VAR)
Config.CLIENT = translate.Client(api_key=api_key)
Config.CLIENT = translate.Client()


class TestTranslate(unittest.TestCase):
Expand All @@ -61,8 +55,8 @@ def test_detect_language(self):
def test_translate(self):
values = ['hvala ti', 'dankon',
'Me llamo Jeff', 'My name is Jeff']
translations = Config.CLIENT.translate(values,
target_language='de')
translations = Config.CLIENT.translate(
values, target_language='de', model=translate.NMT)
self.assertEqual(len(values), len(translations))

self.assertEqual(
Expand Down
2 changes: 2 additions & 0 deletions translate/google/cloud/translate/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,7 @@

"""Google Cloud Translate API wrapper."""

from google.cloud.translate.client import BASE
from google.cloud.translate.client import Client
from google.cloud.translate.client import NMT
from google.cloud.translate.connection import Connection
70 changes: 52 additions & 18 deletions translate/google/cloud/translate/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,37 +19,57 @@
import six

from google.cloud._helpers import _to_bytes
from google.cloud.client import Client as BaseClient
from google.cloud.translate.connection import Connection


ENGLISH_ISO_639 = 'en'
"""ISO 639-1 language code for English."""

BASE = 'base'
"""Base translation model."""

class Client(object):
"""Client to bundle configuration needed for API requests.
NMT = 'nmt'
"""Neural Machine Translation model."""

:type api_key: str
:param api_key: The key used to send with requests as a query
parameter.

:type http: :class:`httplib2.Http` or class that defines ``request()``.
:param http: (Optional) HTTP object to make requests. If not
passed, an :class:`httplib.Http` object is created.
class Client(BaseClient):
"""Client to bundle configuration needed for API requests.

:type target_language: str
:param target_language: (Optional) The target language used for
translations and language names. (Defaults to
:data:`ENGLISH_ISO_639`.)

:type api_key: str
:param api_key: (Optional) The key used to send with requests as a
query parameter.

:type credentials: :class:`oauth2client.client.OAuth2Credentials`
:param credentials: (Optional) The OAuth2 Credentials to use for the
connection owned by this client. If not passed (and
if no ``http`` object is passed), falls back to the
default inferred from the environment.

:type http: :class:`httplib2.Http` or class that defines ``request()``.
:param http: (Optional) HTTP object to make requests. If not
passed, an :class:`httplib.Http` object is created.
"""

def __init__(self, api_key, http=None, target_language=ENGLISH_ISO_639):
_connection_class = Connection

def __init__(self, target_language=ENGLISH_ISO_639, api_key=None,
credentials=None, http=None):
self.api_key = api_key
if http is None:
http = httplib2.Http()
self._connection = Connection(http=http)
self.target_language = target_language

if api_key is not None:
# If API key auth is desired, make it so that no credentials

This comment was marked as spam.

# will be auto-detected by the base class constructor.
if http is None:
http = httplib2.Http()
super(Client, self).__init__(credentials=credentials, http=http)

This comment was marked as spam.

This comment was marked as spam.


def get_languages(self, target_language=None):
"""Get list of supported languages for translation.

Expand All @@ -70,7 +90,9 @@ def get_languages(self, target_language=None):
dictionary will also contain the name of each supported
language (localized to the target language).
"""
query_params = {'key': self.api_key}
query_params = {}
if self.api_key is not None:
query_params['key'] = self.api_key
if target_language is None:
target_language = self.target_language
if target_language is not None:
Expand Down Expand Up @@ -114,7 +136,9 @@ def detect_language(self, values):
single_value = True
values = [values]

query_params = [('key', self.api_key)]
query_params = []
if self.api_key is not None:
query_params.append(('key', self.api_key))
query_params.extend(('q', _to_bytes(value, 'utf-8'))
for value in values)
response = self._connection.api_request(
Expand Down Expand Up @@ -146,7 +170,8 @@ def detect_language(self, values):
return detections

def translate(self, values, target_language=None, format_=None,
source_language=None, customization_ids=()):
source_language=None, customization_ids=(),
model=None):
"""Translate a string or list of strings.

See: https://cloud.google.com/translate/v2/\
Expand All @@ -173,7 +198,11 @@ def translate(self, values, target_language=None, format_=None,
for translation. Sets the ``cid`` parameter
in the query.

:rtype: str or list list
:type model: str
:param model: (Optional) The model used to translate the text. The
only accepted values are :attr:`BASE` and :attr:`NMT`.

:rtype: str or list
:returns: A list of dictionaries for each queried value. Each
dictionary typically contains three keys (though not
all will be present in all cases)
Expand All @@ -183,10 +212,11 @@ def translate(self, values, target_language=None, format_=None,
* ``translatedText``: The translation of the text into the
target language.
* ``input``: The corresponding input value.
* ``model``: The model used to translate the text.

If only a single value is passed, then only a single
dictionary will be returned.
:raises: :class:`ValueError <exceptions.ValueError>` if the number of
:raises: :class:`~exceptions.ValueError` if the number of
values and translations differ.
"""
single_value = False
Expand All @@ -199,14 +229,18 @@ def translate(self, values, target_language=None, format_=None,
if isinstance(customization_ids, six.string_types):
customization_ids = [customization_ids]

query_params = [('key', self.api_key), ('target', target_language)]
query_params = [('target', target_language)]
if self.api_key is not None:
query_params.append(('key', self.api_key))
query_params.extend(('q', _to_bytes(value, 'utf-8'))
for value in values)
query_params.extend(('cid', cid) for cid in customization_ids)
if format_ is not None:
query_params.append(('format', format_))
if source_language is not None:
query_params.append(('source', source_language))
if model is not None:
query_params.append(('model', model))

response = self._connection.api_request(
method='GET', path='', query_params=query_params)
Expand Down
5 changes: 4 additions & 1 deletion translate/google/cloud/translate/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,14 @@
class Connection(_http.JSONConnection):
"""A connection to Google Cloud Translate via the JSON REST API."""

API_BASE_URL = 'https://www.googleapis.com'
API_BASE_URL = 'https://translation.googleapis.com'
"""The base of the API call URL."""

API_VERSION = 'v2'
"""The version of the API, used in building the API call's URL."""

API_URL_TEMPLATE = '{api_base_url}/language/translate/{api_version}{path}'
"""A template for the URL of a particular API call."""

SCOPE = ('https://www.googleapis.com/auth/cloud-platform',)

This comment was marked as spam.

This comment was marked as spam.

This comment was marked as spam.

"""The scopes required for authenticating."""
1 change: 1 addition & 0 deletions translate/tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ envlist =
localdeps =
pip install --quiet --upgrade {toxinidir}/../core
deps =
mock
pytest
covercmd =
py.test --quiet \
Expand Down
Loading