= commited on
Commit
c006992
·
1 Parent(s): 379334a

added support for yandex

Browse files
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.com/",
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