mirror of
https://github.com/Hopiu/django-rosetta.git
synced 2026-03-16 21:30:24 +00:00
162 lines
5.5 KiB
Python
162 lines
5.5 KiB
Python
import json
|
|
import uuid
|
|
|
|
import requests
|
|
|
|
from django.conf import settings
|
|
|
|
|
|
class TranslationException(Exception):
|
|
pass
|
|
|
|
|
|
def translate(text, from_language, to_language):
|
|
AZURE_CLIENT_SECRET = getattr(settings, "AZURE_CLIENT_SECRET", None)
|
|
GOOGLE_APPLICATION_CREDENTIALS_PATH = getattr(
|
|
settings, "GOOGLE_APPLICATION_CREDENTIALS_PATH", None
|
|
)
|
|
GOOGLE_PROJECT_ID = getattr(settings, "GOOGLE_PROJECT_ID", None)
|
|
DEEPL_AUTH_KEY = getattr(settings, "DEEPL_AUTH_KEY", None)
|
|
|
|
if DEEPL_AUTH_KEY:
|
|
deepl_language_code = None
|
|
DEEPL_LANGUAGES = getattr(settings, "DEEPL_LANGUAGES", None)
|
|
if type(DEEPL_LANGUAGES) is dict:
|
|
deepl_language_code = DEEPL_LANGUAGES.get(to_language, None)
|
|
|
|
if deepl_language_code is None:
|
|
deepl_language_code = to_language[:2].upper()
|
|
|
|
return translate_by_deepl(
|
|
text,
|
|
deepl_language_code.upper(),
|
|
DEEPL_AUTH_KEY,
|
|
)
|
|
|
|
elif AZURE_CLIENT_SECRET:
|
|
return translate_by_azure(text, from_language, to_language, AZURE_CLIENT_SECRET)
|
|
elif GOOGLE_APPLICATION_CREDENTIALS_PATH and GOOGLE_PROJECT_ID:
|
|
return translate_by_google(
|
|
text,
|
|
from_language,
|
|
to_language,
|
|
GOOGLE_APPLICATION_CREDENTIALS_PATH,
|
|
GOOGLE_PROJECT_ID,
|
|
)
|
|
else:
|
|
raise TranslationException("No translation API service is configured.")
|
|
|
|
|
|
def translate_by_deepl(text, to_language, auth_key):
|
|
if auth_key.lower().endswith(":fx"):
|
|
endpoint = "https://api-free.deepl.com"
|
|
else:
|
|
endpoint = "https://api.deepl.com"
|
|
|
|
r = requests.post(
|
|
f"{endpoint}/v2/translate",
|
|
headers={"Authorization": f"DeepL-Auth-Key {auth_key}"},
|
|
data={
|
|
"target_lang": to_language.upper(),
|
|
"text": text,
|
|
},
|
|
)
|
|
return r.json().get("translations")[0].get("text")
|
|
|
|
|
|
def translate_by_azure(text, from_language, to_language, subscription_key):
|
|
"""
|
|
This method does the heavy lifting of connecting to the translator API and fetching a response
|
|
:param text: The source text to be translated
|
|
:param from_language: The language of the source text
|
|
:param to_language: The target language to translate the text into
|
|
:param subscription_key: An API key that grants you access to the Azure translation service
|
|
:return: Returns the response from the AZURE service as a python object. For more information about the
|
|
response, please visit
|
|
https://docs.microsoft.com/en-us/azure/cognitive-services/translator/reference/v3-0-translate?tabs=curl
|
|
"""
|
|
|
|
AZURE_TRANSLATOR_HOST = "https://api.cognitive.microsofttranslator.com"
|
|
AZURE_TRANSLATOR_PATH = "/translate?api-version=3.0"
|
|
|
|
headers = {
|
|
"Ocp-Apim-Subscription-Key": subscription_key,
|
|
"Content-type": "application/json",
|
|
"X-ClientTraceId": str(uuid.uuid4()),
|
|
}
|
|
|
|
url_parameters = {"from": from_language, "to": to_language}
|
|
|
|
request_data = [{"text": text}]
|
|
|
|
api_hostname = AZURE_TRANSLATOR_HOST + AZURE_TRANSLATOR_PATH
|
|
r = requests.post(
|
|
api_hostname,
|
|
headers=headers,
|
|
params=url_parameters,
|
|
data=json.dumps(request_data),
|
|
)
|
|
api_response = json.loads(r.text)
|
|
|
|
try:
|
|
# result will be a dict if there is an error, e.g.
|
|
# {
|
|
# "success": false,
|
|
# "error": "Microsoft Translation API error: Error code 401000,
|
|
# The request is not authorized because credentials are missing or invalid."
|
|
# }
|
|
if isinstance(api_response, dict):
|
|
api_error = api_response.get("error")
|
|
error_code = api_error.get("code")
|
|
error_message = api_error.get("message")
|
|
|
|
raise TranslationException(
|
|
"Microsoft Translation API error: Error code {}, {}".format(
|
|
error_code, error_message
|
|
)
|
|
)
|
|
else:
|
|
# response body will be of the form:
|
|
# [
|
|
# {
|
|
# "translations":[
|
|
# {"text": "some chinese text that gave a build error on travis ci", "to": "zh-Hans"}
|
|
# ]
|
|
# }
|
|
# ]
|
|
# for more information, please visit
|
|
# https://docs.microsoft.com/en-us/azure/cognitive-services/translator/reference/v3-0-translate?tabs=curl
|
|
|
|
translations = api_response[0].get("translations")
|
|
translated_text = translations[0].get("text")
|
|
|
|
return translated_text
|
|
except requests.exceptions.RequestException as err:
|
|
raise TranslationException(
|
|
"Error connecting to Microsoft Translation Service: {0}".format(err)
|
|
)
|
|
|
|
|
|
def translate_by_google(
|
|
text, input_language, output_language, creadentials_path, project_id
|
|
):
|
|
from google.cloud import translate as google_translate
|
|
|
|
client = google_translate.TranslationServiceClient.from_service_account_json(
|
|
creadentials_path
|
|
)
|
|
parent = "projects/{}/locations/{}".format(project_id, "global")
|
|
try:
|
|
api_response = client.translate_text(
|
|
request=dict(
|
|
parent=parent,
|
|
contents=[text],
|
|
mime_type="text/plain",
|
|
source_language_code=input_language,
|
|
target_language_code=output_language.split(".", 1)[0],
|
|
)
|
|
)
|
|
except Exception as e:
|
|
raise TranslationException("Google API error: {}".format(e))
|
|
else:
|
|
return str(api_response.translations[0].translated_text)
|