Vincent STRAGIER
commited on
Commit
·
dbaf8a8
1
Parent(s):
ed150d4
Autogenerate the a dictionary of translators.
Browse files- deep_translator/__init__.py +6 -1
- deep_translator/cli.py +3 -26
- deep_translator/deepl.py +13 -6
- deep_translator/engine.py +46 -0
- deep_translator/microsoft.py +6 -1
- deep_translator/papago.py +12 -5
- deep_translator/qcri.py +5 -1
- deep_translator/yandex.py +14 -5
deep_translator/__init__.py
CHANGED
@@ -11,6 +11,7 @@ from .detection import single_detection, batch_detection
|
|
11 |
from .microsoft import MicrosoftTranslator
|
12 |
from .papago import PapagoTranslator
|
13 |
from .libre import LibreTranslator
|
|
|
14 |
|
15 |
__author__ = """Nidhal Baccouri"""
|
16 |
__email__ = '[email protected]'
|
@@ -29,4 +30,8 @@ __all__ = [
|
|
29 |
"PapagoTranslator",
|
30 |
"single_detection",
|
31 |
"batch_detection"
|
32 |
-
|
|
|
|
|
|
|
|
|
|
11 |
from .microsoft import MicrosoftTranslator
|
12 |
from .papago import PapagoTranslator
|
13 |
from .libre import LibreTranslator
|
14 |
+
from .engine import generate_engines_dict, engine
|
15 |
|
16 |
__author__ = """Nidhal Baccouri"""
|
17 |
__email__ = '[email protected]'
|
|
|
30 |
"PapagoTranslator",
|
31 |
"single_detection",
|
32 |
"batch_detection"
|
33 |
+
]
|
34 |
+
|
35 |
+
__engines__ = generate_engines_dict(__all__, locals())
|
36 |
+
del generate_engines_dict
|
37 |
+
engine.translation_engines = __engines__
|
deep_translator/cli.py
CHANGED
@@ -1,39 +1,16 @@
|
|
1 |
"""Console script for deep_translator."""
|
2 |
-
|
3 |
-
from .google_trans import GoogleTranslator
|
4 |
-
from .mymemory import MyMemoryTranslator
|
5 |
-
from .pons import PonsTranslator
|
6 |
-
from .linguee import LingueeTranslator
|
7 |
-
from .yandex import YandexTranslator
|
8 |
-
from .deepl import DeepL
|
9 |
-
from .qcri import QCRI
|
10 |
-
from .papago import PapagoTranslator
|
11 |
-
from .microsoft import MicrosoftTranslator
|
12 |
-
from .libre import LibreTranslator
|
13 |
import argparse
|
14 |
|
15 |
|
16 |
class CLI(object):
|
17 |
-
|
18 |
-
translators_dict = None
|
19 |
translator = None
|
20 |
|
21 |
def __init__(self, custom_args=None):
|
22 |
-
self.translators_dict = {
|
23 |
-
'google': GoogleTranslator,
|
24 |
-
'pons': PonsTranslator,
|
25 |
-
'linguee': LingueeTranslator,
|
26 |
-
'mymemory': MyMemoryTranslator,
|
27 |
-
'deepl': DeepL,
|
28 |
-
'libre': LibreTranslator,
|
29 |
-
'yandex': YandexTranslator,
|
30 |
-
'microsoft': MicrosoftTranslator,
|
31 |
-
'qcri': QCRI,
|
32 |
-
'papago': PapagoTranslator
|
33 |
-
}
|
34 |
self.custom_args = custom_args
|
35 |
self.args = self.parse_args()
|
36 |
-
|
37 |
translator_class = self.translators_dict.get(self.args.translator, None)
|
38 |
if not translator_class:
|
39 |
raise Exception(f"Translator {self.args.translator} is not supported."
|
|
|
1 |
"""Console script for deep_translator."""
|
2 |
+
from . import __engines__
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
import argparse
|
4 |
|
5 |
|
6 |
class CLI(object):
|
7 |
+
translators_dict = __engines__
|
|
|
8 |
translator = None
|
9 |
|
10 |
def __init__(self, custom_args=None):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
11 |
self.custom_args = custom_args
|
12 |
self.args = self.parse_args()
|
13 |
+
# print(f'{__engines__}')
|
14 |
translator_class = self.translators_dict.get(self.args.translator, None)
|
15 |
if not translator_class:
|
16 |
raise Exception(f"Translator {self.args.translator} is not supported."
|
deep_translator/deepl.py
CHANGED
@@ -1,9 +1,10 @@
|
|
1 |
import requests
|
2 |
from .constants import BASE_URLS, DEEPL_LANGUAGE_TO_CODE
|
3 |
from .exceptions import (ServerException,
|
4 |
-
|
5 |
-
|
6 |
-
|
|
|
7 |
|
8 |
|
9 |
class DeepL(object):
|
@@ -26,9 +27,11 @@ class DeepL(object):
|
|
26 |
self.source = self._map_language_to_code(source)
|
27 |
self.target = self._map_language_to_code(target)
|
28 |
if use_free_api:
|
29 |
-
self.__base_url = BASE_URLS.get(
|
|
|
30 |
else:
|
31 |
-
self.__base_url = BASE_URLS.get(
|
|
|
32 |
|
33 |
def translate(self, text, **kwargs):
|
34 |
"""
|
@@ -45,7 +48,8 @@ class DeepL(object):
|
|
45 |
}
|
46 |
# Do the request and check the connection.
|
47 |
try:
|
48 |
-
response = requests.get(
|
|
|
49 |
except ConnectionError:
|
50 |
raise ServerException(503)
|
51 |
# If the answer is not success, raise server exception.
|
@@ -83,6 +87,9 @@ class DeepL(object):
|
|
83 |
raise LanguageNotSupportedException(lang)
|
84 |
|
85 |
|
|
|
|
|
|
|
86 |
if __name__ == '__main__':
|
87 |
d = DeepL(target="de")
|
88 |
t = d.translate("I have no idea")
|
|
|
1 |
import requests
|
2 |
from .constants import BASE_URLS, DEEPL_LANGUAGE_TO_CODE
|
3 |
from .exceptions import (ServerException,
|
4 |
+
TranslationNotFound,
|
5 |
+
LanguageNotSupportedException,
|
6 |
+
AuthorizationException)
|
7 |
+
from .parent import BaseTranslator
|
8 |
|
9 |
|
10 |
class DeepL(object):
|
|
|
27 |
self.source = self._map_language_to_code(source)
|
28 |
self.target = self._map_language_to_code(target)
|
29 |
if use_free_api:
|
30 |
+
self.__base_url = BASE_URLS.get(
|
31 |
+
"DEEPL_FREE").format(version=self.version)
|
32 |
else:
|
33 |
+
self.__base_url = BASE_URLS.get(
|
34 |
+
"DEEPL").format(version=self.version)
|
35 |
|
36 |
def translate(self, text, **kwargs):
|
37 |
"""
|
|
|
48 |
}
|
49 |
# Do the request and check the connection.
|
50 |
try:
|
51 |
+
response = requests.get(
|
52 |
+
self.__base_url + translate_endpoint, params=params)
|
53 |
except ConnectionError:
|
54 |
raise ServerException(503)
|
55 |
# If the answer is not success, raise server exception.
|
|
|
87 |
raise LanguageNotSupportedException(lang)
|
88 |
|
89 |
|
90 |
+
BaseTranslator.register(DeepL)
|
91 |
+
|
92 |
+
|
93 |
if __name__ == '__main__':
|
94 |
d = DeepL(target="de")
|
95 |
t = d.translate("I have no idea")
|
deep_translator/engine.py
ADDED
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from .parent import BaseTranslator
|
2 |
+
|
3 |
+
# BaseTranslator.register(YandexTranslator)
|
4 |
+
# BaseTranslator.register(QCRI)
|
5 |
+
# BaseTranslator.register(DeepL)
|
6 |
+
# BaseTranslator.register(MicrosoftTranslator)
|
7 |
+
# BaseTranslator.register(PapagoTranslator)
|
8 |
+
|
9 |
+
|
10 |
+
def generate_engines_dict(_all: list, _locals: dict) -> dict:
|
11 |
+
base_translator_type = BaseTranslator
|
12 |
+
|
13 |
+
def is_translator(__object: object) -> bool:
|
14 |
+
try:
|
15 |
+
return issubclass(__object, base_translator_type)
|
16 |
+
except TypeError:
|
17 |
+
return False
|
18 |
+
|
19 |
+
translation_engines = {}
|
20 |
+
for _object in _all:
|
21 |
+
__object = _locals.get(_object, 'failed')
|
22 |
+
key_name = _object.replace('Translator', '').lower()
|
23 |
+
if is_translator(__object):
|
24 |
+
translation_engines.update({key_name: __object})
|
25 |
+
return translation_engines
|
26 |
+
|
27 |
+
|
28 |
+
def engine(engine_name: str, *args, **kwargs) -> BaseTranslator:
|
29 |
+
"""Return translation engine.
|
30 |
+
|
31 |
+
Free and keyless engines are 'google', 'pons', 'linguee', 'mymemory',
|
32 |
+
'libre'.
|
33 |
+
|
34 |
+
Args:
|
35 |
+
engine_name: the name of the engine
|
36 |
+
*args: positional argument to pass to the engine
|
37 |
+
**kwargs: named argument to pass to the engine
|
38 |
+
Return:
|
39 |
+
A translation engine
|
40 |
+
"""
|
41 |
+
engine.translation_engines = {}
|
42 |
+
try:
|
43 |
+
return engine.translation_engines[engine_name.lower()](*args, **kwargs)
|
44 |
+
except KeyError:
|
45 |
+
keys = '\', \''.join(engine.translation_engines.keys())
|
46 |
+
raise(KeyError(f'Please provide a valid engine name (\'{keys}\')'))
|
deep_translator/microsoft.py
CHANGED
@@ -6,6 +6,7 @@ import sys
|
|
6 |
|
7 |
from .constants import BASE_URLS, MICROSOFT_CODES_TO_LANGUAGES
|
8 |
from .exceptions import LanguageNotSupportedException, ServerException, MicrosoftAPIerror
|
|
|
9 |
|
10 |
|
11 |
class MicrosoftTranslator:
|
@@ -121,7 +122,8 @@ class MicrosoftTranslator:
|
|
121 |
raise MicrosoftAPIerror(error_message)
|
122 |
# Where it responds with a translation, its response.json() is a list e.g. [{'translations': [{'text': 'Hello world!', 'to': 'en'}]}]
|
123 |
elif type(requested.json()) is list:
|
124 |
-
all_translations = [i['text']
|
|
|
125 |
return "\n".join(all_translations)
|
126 |
|
127 |
def translate_file(self, path, **kwargs):
|
@@ -144,3 +146,6 @@ class MicrosoftTranslator:
|
|
144 |
@return: list of translations
|
145 |
"""
|
146 |
return [self.translate(text, **kwargs) for text in batch]
|
|
|
|
|
|
|
|
6 |
|
7 |
from .constants import BASE_URLS, MICROSOFT_CODES_TO_LANGUAGES
|
8 |
from .exceptions import LanguageNotSupportedException, ServerException, MicrosoftAPIerror
|
9 |
+
from .parent import BaseTranslator
|
10 |
|
11 |
|
12 |
class MicrosoftTranslator:
|
|
|
122 |
raise MicrosoftAPIerror(error_message)
|
123 |
# Where it responds with a translation, its response.json() is a list e.g. [{'translations': [{'text': 'Hello world!', 'to': 'en'}]}]
|
124 |
elif type(requested.json()) is list:
|
125 |
+
all_translations = [i['text']
|
126 |
+
for i in requested.json()[0]['translations']]
|
127 |
return "\n".join(all_translations)
|
128 |
|
129 |
def translate_file(self, path, **kwargs):
|
|
|
146 |
@return: list of translations
|
147 |
"""
|
148 |
return [self.translate(text, **kwargs) for text in batch]
|
149 |
+
|
150 |
+
|
151 |
+
BaseTranslator.register(MicrosoftTranslator)
|
deep_translator/papago.py
CHANGED
@@ -4,6 +4,7 @@ google translator API
|
|
4 |
import json
|
5 |
from .constants import BASE_URLS, PAPAGO_LANGUAGE_TO_CODE
|
6 |
from .exceptions import LanguageNotSupportedException, TranslationNotFound, NotValidPayload
|
|
|
7 |
import requests
|
8 |
import warnings
|
9 |
import logging
|
@@ -22,13 +23,15 @@ class PapagoTranslator(object):
|
|
22 |
@param target: target language to translate to
|
23 |
"""
|
24 |
if not client_id or not secret_key:
|
25 |
-
raise Exception(
|
|
|
26 |
|
27 |
self.__base_url = BASE_URLS.get("PAPAGO_API")
|
28 |
self.client_id = client_id
|
29 |
self.secret_key = secret_key
|
30 |
if self.is_language_supported(source, target):
|
31 |
-
self._source, self._target = self._map_language_to_code(
|
|
|
32 |
|
33 |
@staticmethod
|
34 |
def get_supported_languages(as_dict=False, **kwargs):
|
@@ -82,9 +85,11 @@ class PapagoTranslator(object):
|
|
82 |
'X-Naver-Client-Secret': self.secret_key,
|
83 |
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
|
84 |
}
|
85 |
-
response = requests.post(
|
|
|
86 |
if response.status_code != 200:
|
87 |
-
raise Exception(
|
|
|
88 |
res_body = json.loads(response.text)
|
89 |
if "message" not in res_body:
|
90 |
raise TranslationNotFound(text)
|
@@ -120,7 +125,8 @@ class PapagoTranslator(object):
|
|
120 |
@param sentences: list of sentences to translate
|
121 |
@return: list of all translated sentences
|
122 |
"""
|
123 |
-
warnings.warn("deprecated. Use the translate_batch function instead",
|
|
|
124 |
logging.warning("deprecated. Use the translate_batch function instead")
|
125 |
if not sentences:
|
126 |
raise NotValidPayload(sentences)
|
@@ -152,3 +158,4 @@ class PapagoTranslator(object):
|
|
152 |
return arr
|
153 |
|
154 |
|
|
|
|
4 |
import json
|
5 |
from .constants import BASE_URLS, PAPAGO_LANGUAGE_TO_CODE
|
6 |
from .exceptions import LanguageNotSupportedException, TranslationNotFound, NotValidPayload
|
7 |
+
from .parent import BaseTranslator
|
8 |
import requests
|
9 |
import warnings
|
10 |
import logging
|
|
|
23 |
@param target: target language to translate to
|
24 |
"""
|
25 |
if not client_id or not secret_key:
|
26 |
+
raise Exception(
|
27 |
+
"Please pass your client id and secret key! visit the papago website for more infos")
|
28 |
|
29 |
self.__base_url = BASE_URLS.get("PAPAGO_API")
|
30 |
self.client_id = client_id
|
31 |
self.secret_key = secret_key
|
32 |
if self.is_language_supported(source, target):
|
33 |
+
self._source, self._target = self._map_language_to_code(
|
34 |
+
source.lower(), target.lower())
|
35 |
|
36 |
@staticmethod
|
37 |
def get_supported_languages(as_dict=False, **kwargs):
|
|
|
85 |
'X-Naver-Client-Secret': self.secret_key,
|
86 |
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
|
87 |
}
|
88 |
+
response = requests.post(
|
89 |
+
self.__base_url, headers=headers, data=payload)
|
90 |
if response.status_code != 200:
|
91 |
+
raise Exception(
|
92 |
+
f'Translation error! -> status code: {response.status_code}')
|
93 |
res_body = json.loads(response.text)
|
94 |
if "message" not in res_body:
|
95 |
raise TranslationNotFound(text)
|
|
|
125 |
@param sentences: list of sentences to translate
|
126 |
@return: list of all translated sentences
|
127 |
"""
|
128 |
+
warnings.warn("deprecated. Use the translate_batch function instead",
|
129 |
+
DeprecationWarning, stacklevel=2)
|
130 |
logging.warning("deprecated. Use the translate_batch function instead")
|
131 |
if not sentences:
|
132 |
raise NotValidPayload(sentences)
|
|
|
158 |
return arr
|
159 |
|
160 |
|
161 |
+
BaseTranslator.register(PapagoTranslator)
|
deep_translator/qcri.py
CHANGED
@@ -2,6 +2,7 @@
|
|
2 |
import requests
|
3 |
from .constants import BASE_URLS, QCRI_LANGUAGE_TO_CODE
|
4 |
from .exceptions import (ServerException, TranslationNotFound)
|
|
|
5 |
|
6 |
|
7 |
class QCRI(object):
|
@@ -34,7 +35,8 @@ class QCRI(object):
|
|
34 |
if not params:
|
35 |
params = self.params
|
36 |
try:
|
37 |
-
res = requests.get(self.__base_url.format(
|
|
|
38 |
return res.text if return_text else res
|
39 |
except Exception as e:
|
40 |
raise e
|
@@ -90,3 +92,5 @@ class QCRI(object):
|
|
90 |
"""
|
91 |
return [self.translate(domain, text, **kwargs) for text in batch]
|
92 |
|
|
|
|
|
|
2 |
import requests
|
3 |
from .constants import BASE_URLS, QCRI_LANGUAGE_TO_CODE
|
4 |
from .exceptions import (ServerException, TranslationNotFound)
|
5 |
+
from .parent import BaseTranslator
|
6 |
|
7 |
|
8 |
class QCRI(object):
|
|
|
35 |
if not params:
|
36 |
params = self.params
|
37 |
try:
|
38 |
+
res = requests.get(self.__base_url.format(
|
39 |
+
endpoint=self.api_endpoints[endpoint]), params=params)
|
40 |
return res.text if return_text else res
|
41 |
except Exception as e:
|
42 |
raise e
|
|
|
92 |
"""
|
93 |
return [self.translate(domain, text, **kwargs) for text in batch]
|
94 |
|
95 |
+
|
96 |
+
BaseTranslator.register(QCRI)
|
deep_translator/yandex.py
CHANGED
@@ -3,7 +3,9 @@ Yandex translator API
|
|
3 |
"""
|
4 |
import requests
|
5 |
from .constants import BASE_URLS
|
6 |
-
from .exceptions import (RequestError, ServerException,
|
|
|
|
|
7 |
|
8 |
|
9 |
class YandexTranslator(object):
|
@@ -47,9 +49,11 @@ class YandexTranslator(object):
|
|
47 |
def dirs(self, proxies=None):
|
48 |
|
49 |
try:
|
50 |
-
url = self.__base_url.format(
|
|
|
51 |
print("url: ", url)
|
52 |
-
response = requests.get(
|
|
|
53 |
except requests.exceptions.ConnectionError:
|
54 |
raise ServerException(503)
|
55 |
else:
|
@@ -67,7 +71,8 @@ class YandexTranslator(object):
|
|
67 |
"key": self.api_key,
|
68 |
}
|
69 |
try:
|
70 |
-
url = self.__base_url.format(
|
|
|
71 |
response = requests.post(url, data=params, proxies=proxies)
|
72 |
|
73 |
except RequestError:
|
@@ -94,7 +99,8 @@ class YandexTranslator(object):
|
|
94 |
"key": self.api_key
|
95 |
}
|
96 |
try:
|
97 |
-
url = self.__base_url.format(
|
|
|
98 |
response = requests.post(url, data=params, proxies=proxies)
|
99 |
except ConnectionError:
|
100 |
raise ServerException(503)
|
@@ -133,3 +139,6 @@ class YandexTranslator(object):
|
|
133 |
@return: list of translations
|
134 |
"""
|
135 |
return [self.translate(text, **kwargs) for text in batch]
|
|
|
|
|
|
|
|
3 |
"""
|
4 |
import requests
|
5 |
from .constants import BASE_URLS
|
6 |
+
from .exceptions import (RequestError, ServerException,
|
7 |
+
TranslationNotFound, TooManyRequests)
|
8 |
+
from .parent import BaseTranslator
|
9 |
|
10 |
|
11 |
class YandexTranslator(object):
|
|
|
49 |
def dirs(self, proxies=None):
|
50 |
|
51 |
try:
|
52 |
+
url = self.__base_url.format(
|
53 |
+
version=self.api_version, endpoint="getLangs")
|
54 |
print("url: ", url)
|
55 |
+
response = requests.get(
|
56 |
+
url, params={"key": self.api_key}, proxies=proxies)
|
57 |
except requests.exceptions.ConnectionError:
|
58 |
raise ServerException(503)
|
59 |
else:
|
|
|
71 |
"key": self.api_key,
|
72 |
}
|
73 |
try:
|
74 |
+
url = self.__base_url.format(
|
75 |
+
version=self.api_version, endpoint="detect")
|
76 |
response = requests.post(url, data=params, proxies=proxies)
|
77 |
|
78 |
except RequestError:
|
|
|
99 |
"key": self.api_key
|
100 |
}
|
101 |
try:
|
102 |
+
url = self.__base_url.format(
|
103 |
+
version=self.api_version, endpoint="translate")
|
104 |
response = requests.post(url, data=params, proxies=proxies)
|
105 |
except ConnectionError:
|
106 |
raise ServerException(503)
|
|
|
139 |
@return: list of translations
|
140 |
"""
|
141 |
return [self.translate(text, **kwargs) for text in batch]
|
142 |
+
|
143 |
+
|
144 |
+
BaseTranslator.register(YandexTranslator)
|