Source code for platypush.plugins.google.translate
import os
from typing import Optional, List
from google.cloud import translate_v2 as translate
from platypush.plugins import action, Plugin
[docs]
class GoogleTranslatePlugin(Plugin):
"""
Plugin to interact with the Google Translate API.
You'll need a Google Cloud active project and a set of credentials to use this plugin:
1. Create a project on the `Google Cloud console
<https://console.cloud.google.com/projectcreate>`_ if you don't
have one already.
2. In the menu navigate to the *Artificial Intelligence* section and
select *Translations* and enable the API.
3. From the menu select *APIs & Services* and create a service account.
You can leave role and permissions empty.
4. Create a new private JSON key for the service account and download
it. By default platypush will look for the credentials file under
``~/.credentials/platypush/google/translate.json``.
"""
_maximum_text_length = 2000
default_credentials_file = os.path.join(
os.path.expanduser('~'), '.credentials', 'platypush', 'google', 'translate.json'
)
[docs]
def __init__(
self,
target_language: str = 'en',
credentials_file: Optional[str] = None,
**kwargs
):
"""
:param target_language: Default target language (default: 'en').
:param credentials_file: Google service account JSON credentials file.
If none is specified then the plugin will search for the credentials
file in the following order:
1. ``~/.credentials/platypush/google/translate.json``
2. Context from the ``GOOGLE_APPLICATION_CREDENTIALS``
environment variable.
"""
super().__init__(**kwargs)
self.target_language = target_language
self.credentials_file = None
if credentials_file:
self.credentials_file = os.path.abspath(
os.path.expanduser(credentials_file)
)
elif os.path.isfile(self.default_credentials_file):
self.credentials_file = self.default_credentials_file
if self.credentials_file:
os.environ['GOOGLE_APPLICATION_CREDENTIALS'] = self.credentials_file
@staticmethod
def _nearest_delimiter_index(text: str, pos: int) -> int:
for i in range(min(pos, len(text) - 1), -1, -1):
if text[i] in [' ', '\t', ',', '.', ')', '>']:
return i
if text[i] in ['(', '<']:
return i - 1 if i > 0 else 0
return 0
@classmethod
def _split_text(cls, text: str, length: int = _maximum_text_length) -> List[str]:
parts = []
while text:
i = cls._nearest_delimiter_index(text, length)
if i == 0:
parts.append(text)
text = ''
else:
part = text[: i + 1]
if part:
parts.append(part.strip())
text = text[i + 1 :]
return parts
[docs]
@action
def translate(
self,
text: str,
target_language: Optional[str] = None,
source_language: Optional[str] = None,
format: Optional[str] = None,
) -> dict:
"""
Translate a piece of text or HTML.
:param text: Input text.
:param target_language: target_language override.
:param source_language: source_language (default: auto-detect).
:param format: Input format (available formats: ``text``, ``html``).
:return: dict
.. code-block:: json
{
"translated_text": "Translated text",
"source_text": "Source text",
"detected_source_language": "Detected source language"
}
"""
target_language = target_language or self.target_language
args = {}
if target_language:
args['target_language'] = target_language
client = translate.Client(**args)
if source_language:
args['source_language'] = source_language
inputs = self._split_text(text)
result = {}
for input in inputs:
response = client.translate(input, format_=format, **args)
if not result:
result = response
else:
result['translatedText'] += ' ' + response['translatedText']
return {
'translated_text': result.get('translatedText'),
'source_text': text,
'detected_source_language': result.get('detectedSourceLanguage'),
}
# vim:sw=4:ts=4:et: