=
commited on
Commit
·
c006992
1
Parent(s):
379334a
added support for yandex
Browse files- README.rst +29 -0
- deep_translator/__init__.py +2 -0
- deep_translator/constants.py +1 -1
- deep_translator/exceptions.py +27 -2
- deep_translator/yandex.py +103 -0
- docs/usage.rst +27 -0
README.rst
CHANGED
@@ -91,6 +91,7 @@ Features
|
|
91 |
* Support for `Pons translator <https://de.pons.com//>`_
|
92 |
* Support for the `Linguee translator <https://www.linguee.com//>`_
|
93 |
* Support for the `Mymemory translator <https://mymemory.translated.net//>`_
|
|
|
94 |
* Automatic single language detection
|
95 |
* Batch language detection
|
96 |
* Translate directly from a text file
|
@@ -149,6 +150,7 @@ Imports
|
|
149 |
PonsTranslator,
|
150 |
LingueeTranslator,
|
151 |
MyMemoryTranslator,
|
|
|
152 |
single_detection,
|
153 |
batch_detection)
|
154 |
|
@@ -331,6 +333,33 @@ PONS Translator
|
|
331 |
|
332 |
translated_words = LingueeTranslator(source='english', target='french').translate_words(["good", "awesome"])
|
333 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
334 |
Usage from Terminal
|
335 |
--------------------
|
336 |
|
|
|
91 |
* Support for `Pons translator <https://de.pons.com//>`_
|
92 |
* Support for the `Linguee translator <https://www.linguee.com//>`_
|
93 |
* Support for the `Mymemory translator <https://mymemory.translated.net//>`_
|
94 |
+
* Support for the `Yandex translator <https://yandex.com/>`_ (version >= 1.2.1)
|
95 |
* Automatic single language detection
|
96 |
* Batch language detection
|
97 |
* Translate directly from a text file
|
|
|
150 |
PonsTranslator,
|
151 |
LingueeTranslator,
|
152 |
MyMemoryTranslator,
|
153 |
+
YandexTranslator
|
154 |
single_detection,
|
155 |
batch_detection)
|
156 |
|
|
|
333 |
|
334 |
translated_words = LingueeTranslator(source='english', target='french').translate_words(["good", "awesome"])
|
335 |
|
336 |
+
Yandex Translator
|
337 |
+
----------------
|
338 |
+
|
339 |
+
.. note::
|
340 |
+
|
341 |
+
You need to require an private api key if you want to use the yandex translator.
|
342 |
+
visit the official website for more information about how to get one
|
343 |
+
|
344 |
+
- Language detection
|
345 |
+
|
346 |
+
.. code-block:: python
|
347 |
+
|
348 |
+
lang = YandexTranslator('your_api_key').detect('Hallo, Welt')
|
349 |
+
print(f"language detected: {lang}") # output -> language detected: 'de'
|
350 |
+
|
351 |
+
- Text translation
|
352 |
+
|
353 |
+
.. code-block:: python
|
354 |
+
|
355 |
+
# with auto detection | meaning provide only the target language and let yandex detect the source
|
356 |
+
translated = YandexTranslator('your_api_key').translate('Hallo, Welt', 'en')
|
357 |
+
print(f"translated text: {translated}") # output -> translated text: Hello world
|
358 |
+
|
359 |
+
# provide source and target language explicitly
|
360 |
+
translated = YandexTranslator('your_api_key').translate('Hallo, Welt', 'de-en')
|
361 |
+
print(f"translated text: {translated}") # output -> translated text: Hello world
|
362 |
+
|
363 |
Usage from Terminal
|
364 |
--------------------
|
365 |
|
deep_translator/__init__.py
CHANGED
@@ -4,6 +4,7 @@ from .google_trans import GoogleTranslator
|
|
4 |
from .pons import PonsTranslator
|
5 |
from .linguee import LingueeTranslator
|
6 |
from .mymemory import MyMemoryTranslator
|
|
|
7 |
from .detection import single_detection, batch_detection
|
8 |
|
9 |
|
@@ -15,5 +16,6 @@ __all__ = [GoogleTranslator,
|
|
15 |
PonsTranslator,
|
16 |
LingueeTranslator,
|
17 |
MyMemoryTranslator,
|
|
|
18 |
single_detection,
|
19 |
batch_detection]
|
|
|
4 |
from .pons import PonsTranslator
|
5 |
from .linguee import LingueeTranslator
|
6 |
from .mymemory import MyMemoryTranslator
|
7 |
+
from .yandex import YandexTranslator
|
8 |
from .detection import single_detection, batch_detection
|
9 |
|
10 |
|
|
|
16 |
PonsTranslator,
|
17 |
LingueeTranslator,
|
18 |
MyMemoryTranslator,
|
19 |
+
YandexTranslator,
|
20 |
single_detection,
|
21 |
batch_detection]
|
deep_translator/constants.py
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
BASE_URLS = {
|
4 |
"GOOGLE_TRANSLATE": "https://translate.google.com/m",
|
5 |
"PONS": "https://en.pons.com/translate/",
|
6 |
-
"YANDEX": "https://translate.yandex.
|
7 |
"LINGUEE": "https://www.linguee.com/",
|
8 |
"MYMEMORY": "http://api.mymemory.translated.net/get"
|
9 |
}
|
|
|
3 |
BASE_URLS = {
|
4 |
"GOOGLE_TRANSLATE": "https://translate.google.com/m",
|
5 |
"PONS": "https://en.pons.com/translate/",
|
6 |
+
"YANDEX": "https://translate.yandex.net/api/{version}/tr.json/{endpoint}",
|
7 |
"LINGUEE": "https://www.linguee.com/",
|
8 |
"MYMEMORY": "http://api.mymemory.translated.net/get"
|
9 |
}
|
deep_translator/exceptions.py
CHANGED
@@ -1,9 +1,8 @@
|
|
1 |
-
|
2 |
-
|
3 |
class BaseError(Exception):
|
4 |
"""
|
5 |
base error structure class
|
6 |
"""
|
|
|
7 |
def __init__(self, val, message):
|
8 |
"""
|
9 |
@param val: actual value
|
@@ -21,6 +20,7 @@ class LanguageNotSupportedException(BaseError):
|
|
21 |
"""
|
22 |
exception thrown if the user uses a language that is not supported by the deep_translator
|
23 |
"""
|
|
|
24 |
def __init__(self, val, message="There is no support for the chosen language"):
|
25 |
super().__init__(val, message)
|
26 |
|
@@ -29,6 +29,7 @@ class NotValidPayload(BaseError):
|
|
29 |
"""
|
30 |
exception thrown if the user enters an invalid payload
|
31 |
"""
|
|
|
32 |
def __init__(self,
|
33 |
val,
|
34 |
message='text must be a valid text with maximum 5000 character, otherwise it cannot be translated'):
|
@@ -39,6 +40,7 @@ class TranslationNotFound(BaseError):
|
|
39 |
"""
|
40 |
exception thrown if no translation was found for the text provided by the user
|
41 |
"""
|
|
|
42 |
def __init__(self,
|
43 |
val,
|
44 |
message='No translation was found using the current translator. Try another translator?'):
|
@@ -49,6 +51,7 @@ class ElementNotFoundInGetRequest(BaseError):
|
|
49 |
"""
|
50 |
exception thrown if the html element was not found in the body parsed by beautifulsoup
|
51 |
"""
|
|
|
52 |
def __init__(self,
|
53 |
val,
|
54 |
message='Required element was not found in the API response'):
|
@@ -59,6 +62,7 @@ class NotValidLength(BaseError):
|
|
59 |
"""
|
60 |
exception thrown if the provided text exceed the length limit of the translator
|
61 |
"""
|
|
|
62 |
def __init__(self, val, min_chars, max_chars):
|
63 |
message = "Text length need to be between {} and {} characters".format(min_chars, max_chars)
|
64 |
super(NotValidLength, self).__init__(val, message)
|
@@ -68,9 +72,30 @@ class RequestError(Exception):
|
|
68 |
"""
|
69 |
exception thrown if an error occured during the request call, e.g a connection problem.
|
70 |
"""
|
|
|
71 |
def __init__(self, message="Request exception can happen due to an api connection error. "
|
72 |
"Please check your connection and try again"):
|
73 |
self.message = message
|
74 |
|
75 |
def __str__(self):
|
76 |
return self.message
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
class BaseError(Exception):
|
2 |
"""
|
3 |
base error structure class
|
4 |
"""
|
5 |
+
|
6 |
def __init__(self, val, message):
|
7 |
"""
|
8 |
@param val: actual value
|
|
|
20 |
"""
|
21 |
exception thrown if the user uses a language that is not supported by the deep_translator
|
22 |
"""
|
23 |
+
|
24 |
def __init__(self, val, message="There is no support for the chosen language"):
|
25 |
super().__init__(val, message)
|
26 |
|
|
|
29 |
"""
|
30 |
exception thrown if the user enters an invalid payload
|
31 |
"""
|
32 |
+
|
33 |
def __init__(self,
|
34 |
val,
|
35 |
message='text must be a valid text with maximum 5000 character, otherwise it cannot be translated'):
|
|
|
40 |
"""
|
41 |
exception thrown if no translation was found for the text provided by the user
|
42 |
"""
|
43 |
+
|
44 |
def __init__(self,
|
45 |
val,
|
46 |
message='No translation was found using the current translator. Try another translator?'):
|
|
|
51 |
"""
|
52 |
exception thrown if the html element was not found in the body parsed by beautifulsoup
|
53 |
"""
|
54 |
+
|
55 |
def __init__(self,
|
56 |
val,
|
57 |
message='Required element was not found in the API response'):
|
|
|
62 |
"""
|
63 |
exception thrown if the provided text exceed the length limit of the translator
|
64 |
"""
|
65 |
+
|
66 |
def __init__(self, val, min_chars, max_chars):
|
67 |
message = "Text length need to be between {} and {} characters".format(min_chars, max_chars)
|
68 |
super(NotValidLength, self).__init__(val, message)
|
|
|
72 |
"""
|
73 |
exception thrown if an error occured during the request call, e.g a connection problem.
|
74 |
"""
|
75 |
+
|
76 |
def __init__(self, message="Request exception can happen due to an api connection error. "
|
77 |
"Please check your connection and try again"):
|
78 |
self.message = message
|
79 |
|
80 |
def __str__(self):
|
81 |
return self.message
|
82 |
+
|
83 |
+
|
84 |
+
class YandexDefaultException(Exception):
|
85 |
+
"""
|
86 |
+
Default YandexTranslate exception from the official website
|
87 |
+
"""
|
88 |
+
errors = {
|
89 |
+
401: "ERR_KEY_INVALID",
|
90 |
+
402: "ERR_KEY_BLOCKED",
|
91 |
+
403: "ERR_DAILY_REQ_LIMIT_EXCEEDED",
|
92 |
+
404: "ERR_DAILY_CHAR_LIMIT_EXCEEDED",
|
93 |
+
413: "ERR_TEXT_TOO_LONG",
|
94 |
+
422: "ERR_UNPROCESSABLE_TEXT",
|
95 |
+
501: "ERR_LANG_NOT_SUPPORTED",
|
96 |
+
503: "ERR_SERVICE_NOT_AVAIBLE",
|
97 |
+
}
|
98 |
+
|
99 |
+
def __init__(self, status_code, *args):
|
100 |
+
message = self.errors.get(status_code)
|
101 |
+
super(YandexDefaultException, self).__init__(message, *args)
|
deep_translator/yandex.py
ADDED
@@ -0,0 +1,103 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"""
|
2 |
+
Yandex translator API
|
3 |
+
"""
|
4 |
+
import requests
|
5 |
+
from requests import exceptions
|
6 |
+
from deep_translator.constants import BASE_URLS
|
7 |
+
from deep_translator.exceptions import (RequestError,
|
8 |
+
YandexDefaultException, TranslationNotFound)
|
9 |
+
|
10 |
+
|
11 |
+
class YandexTranslator(object):
|
12 |
+
"""
|
13 |
+
class that wraps functions, which use the yandex translator under the hood to translate word(s)
|
14 |
+
"""
|
15 |
+
|
16 |
+
def __init__(self, api_key=None):
|
17 |
+
"""
|
18 |
+
@param api_key: your yandex api key
|
19 |
+
"""
|
20 |
+
if not api_key:
|
21 |
+
raise YandexDefaultException(401)
|
22 |
+
self.__base_url = BASE_URLS.get("YANDEX")
|
23 |
+
|
24 |
+
self.api_key = api_key
|
25 |
+
self.api_version = "v1.5"
|
26 |
+
self.api_endpoints = {
|
27 |
+
"langs": "getLangs",
|
28 |
+
"detect": "detect",
|
29 |
+
"translate": "translate",
|
30 |
+
}
|
31 |
+
|
32 |
+
def get_supported_languages(self):
|
33 |
+
return set(x.split("-")[0] for x in self.dirs)
|
34 |
+
|
35 |
+
@property
|
36 |
+
def languages(self):
|
37 |
+
return self.get_supported_languages()
|
38 |
+
|
39 |
+
@property
|
40 |
+
def dirs(self, proxies=None):
|
41 |
+
|
42 |
+
try:
|
43 |
+
url = self.__base_url.format(version=self.api_version, endpoint="getLangs")
|
44 |
+
print("url: ", url)
|
45 |
+
response = requests.get(url, params={"key": self.api_key}, proxies=proxies)
|
46 |
+
except requests.exceptions.ConnectionError:
|
47 |
+
raise YandexDefaultException(503)
|
48 |
+
else:
|
49 |
+
data = response.json()
|
50 |
+
|
51 |
+
if response.status_code != 200:
|
52 |
+
raise YandexDefaultException(response.status_code)
|
53 |
+
return data.get("dirs")
|
54 |
+
|
55 |
+
|
56 |
+
def detect(self, text, proxies=None):
|
57 |
+
response = None
|
58 |
+
params = {
|
59 |
+
"text": text,
|
60 |
+
"format": "plain",
|
61 |
+
"key": self.api_key,
|
62 |
+
}
|
63 |
+
try:
|
64 |
+
url = self.__base_url.format(version=self.api_version, endpoint="detect")
|
65 |
+
response = requests.post(url, data=params, proxies=proxies)
|
66 |
+
|
67 |
+
except RequestError:
|
68 |
+
raise
|
69 |
+
except ConnectionError:
|
70 |
+
raise YandexDefaultException(503)
|
71 |
+
except ValueError:
|
72 |
+
raise YandexDefaultException(response.status_code)
|
73 |
+
else:
|
74 |
+
response = response.json()
|
75 |
+
language = response['lang']
|
76 |
+
status_code = response['code']
|
77 |
+
if status_code != 200:
|
78 |
+
raise RequestError()
|
79 |
+
elif not language:
|
80 |
+
raise YandexDefaultException(501)
|
81 |
+
return language
|
82 |
+
|
83 |
+
|
84 |
+
def translate(self, text, lang, proxies=None):
|
85 |
+
params = {
|
86 |
+
"text": text,
|
87 |
+
"format": "plain",
|
88 |
+
"lang": lang,
|
89 |
+
"key": self.api_key
|
90 |
+
}
|
91 |
+
try:
|
92 |
+
url = self.__base_url.format(version=self.api_version, endpoint="translate")
|
93 |
+
response = requests.post(url, data=params, proxies=proxies)
|
94 |
+
except ConnectionError:
|
95 |
+
raise YandexDefaultException(503)
|
96 |
+
else:
|
97 |
+
response = response.json()
|
98 |
+
if response['code'] != 200:
|
99 |
+
raise YandexDefaultException(response['code'])
|
100 |
+
if not response['text']:
|
101 |
+
raise TranslationNotFound()
|
102 |
+
|
103 |
+
return response['text']
|
docs/usage.rst
CHANGED
@@ -204,6 +204,33 @@ PONS Translator
|
|
204 |
|
205 |
translated_words = LingueeTranslator(source='english', target='french').translate_words(["good", "awesome"])
|
206 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
207 |
Usage from Terminal
|
208 |
--------------------
|
209 |
|
|
|
204 |
|
205 |
translated_words = LingueeTranslator(source='english', target='french').translate_words(["good", "awesome"])
|
206 |
|
207 |
+
Yandex Translator
|
208 |
+
----------------
|
209 |
+
|
210 |
+
.. note::
|
211 |
+
|
212 |
+
You need to require an private api key if you want to use the yandex translator.
|
213 |
+
visit the official website for more information about how to get one
|
214 |
+
|
215 |
+
- Language detection
|
216 |
+
|
217 |
+
.. code-block:: python
|
218 |
+
|
219 |
+
lang = YandexTranslator('your_api_key').detect('Hallo, Welt')
|
220 |
+
print(f"language detected: {lang}") # output -> language detected: 'de'
|
221 |
+
|
222 |
+
- Text translation
|
223 |
+
|
224 |
+
.. code-block:: python
|
225 |
+
|
226 |
+
# with auto detection | meaning provide only the target language and let yandex detect the source
|
227 |
+
translated = YandexTranslator('your_api_key').translate('Hallo, Welt', 'en')
|
228 |
+
print(f"translated text: {translated}") # output -> translated text: Hello world
|
229 |
+
|
230 |
+
# provide source and target language explicitly
|
231 |
+
translated = YandexTranslator('your_api_key').translate('Hallo, Welt', 'de-en')
|
232 |
+
print(f"translated text: {translated}") # output -> translated text: Hello world
|
233 |
+
|
234 |
Usage from Terminal
|
235 |
--------------------
|
236 |
|