nidhal baccouri commited on
Commit
78d0ff1
·
1 Parent(s): 721a708

added black for formatting

Browse files
Makefile CHANGED
@@ -48,7 +48,7 @@ clean-test: ## remove test and coverage artifacts
48
  rm -fr .pytest_cache
49
 
50
  lint: ## check style with flake8
51
- flake8 deep_translator tests
52
 
53
  test: ## run tests quickly with the default Python
54
  pytest
 
48
  rm -fr .pytest_cache
49
 
50
  lint: ## check style with flake8
51
+ poetry run black deep_translator tests
52
 
53
  test: ## run tests quickly with the default Python
54
  pytest
deep_translator/__init__.py CHANGED
@@ -1,20 +1,20 @@
1
  """Top-level package for Deep Translator"""
2
 
3
- from .google import GoogleTranslator
4
- from .pons import PonsTranslator
5
- from .linguee import LingueeTranslator
6
- from .mymemory import MyMemoryTranslator
7
- from .yandex import YandexTranslator
8
- from .qcri import QcriTranslator
9
- from .deepl import DeeplTranslator
10
- 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]'
17
- __version__ = '1.7.1'
18
 
19
  __all__ = [
20
  "GoogleTranslator",
@@ -28,5 +28,5 @@ __all__ = [
28
  "LibreTranslator",
29
  "PapagoTranslator",
30
  "single_detection",
31
- "batch_detection"
32
  ]
 
1
  """Top-level package for Deep Translator"""
2
 
3
+ from deep_translator.google import GoogleTranslator
4
+ from deep_translator.pons import PonsTranslator
5
+ from deep_translator.linguee import LingueeTranslator
6
+ from deep_translator.mymemory import MyMemoryTranslator
7
+ from deep_translator.yandex import YandexTranslator
8
+ from deep_translator.qcri import QcriTranslator
9
+ from deep_translator.deepl import DeeplTranslator
10
+ from deep_translator.detection import single_detection, batch_detection
11
+ from deep_translator.microsoft import MicrosoftTranslator
12
+ from deep_translator.papago import PapagoTranslator
13
+ from deep_translator.libre import LibreTranslator
14
 
15
  __author__ = """Nidhal Baccouri"""
16
+ __email__ = "[email protected]"
17
+ __version__ = "1.7.1"
18
 
19
  __all__ = [
20
  "GoogleTranslator",
 
28
  "LibreTranslator",
29
  "PapagoTranslator",
30
  "single_detection",
31
+ "batch_detection",
32
  ]
deep_translator/__main__.py CHANGED
@@ -1,5 +1,4 @@
1
-
2
- from .cli import CLI
3
 
4
 
5
  def main():
 
1
+ from deep_translator.cli import CLI
 
2
 
3
 
4
  def main():
deep_translator/base.py CHANGED
@@ -1,7 +1,7 @@
1
  """base translator class"""
2
 
3
- from .constants import GOOGLE_LANGUAGES_TO_CODES
4
- from .exceptions import InvalidSourceOrTargetLanguage
5
  from abc import ABC, abstractmethod
6
 
7
 
@@ -9,15 +9,18 @@ class BaseTranslator(ABC):
9
  """
10
  Abstract class that serve as a base translator for other different translators
11
  """
12
- def __init__(self,
13
- base_url=None,
14
- source="auto",
15
- target="en",
16
- payload_key=None,
17
- element_tag=None,
18
- element_query=None,
19
- languages=None,
20
- **url_params):
 
 
 
21
  """
22
  @param source: source language to translate from
23
  @param target: target language to translate to
@@ -47,7 +50,7 @@ class BaseTranslator(ABC):
47
  @return: mapped value of the language or raise an exception if the language is not supported
48
  """
49
  for language in languages:
50
- if language in self.languages.values() or language == 'auto':
51
  yield language
52
  elif language in self.languages.keys():
53
  yield self.languages[language]
@@ -69,7 +72,11 @@ class BaseTranslator(ABC):
69
  @param language: a string for 1 language
70
  @return: bool or raise an Exception
71
  """
72
- if language == 'auto' or language in self.languages.keys() or language in self.languages.values():
 
 
 
 
73
  return True
74
  else:
75
  return False
@@ -82,7 +89,7 @@ class BaseTranslator(ABC):
82
  @param kwargs: additional arguments
83
  @return: str
84
  """
85
- return NotImplemented('You need to implement the translate method!')
86
 
87
  def _translate_file(self, path, **kwargs):
88
  """
@@ -93,7 +100,7 @@ class BaseTranslator(ABC):
93
  @return: str
94
  """
95
  try:
96
- with open(path, 'r', encoding='utf-8') as f:
97
  text = f.read().strip()
98
  return self.translate(text)
99
  except Exception as e:
 
1
  """base translator class"""
2
 
3
+ from deep_translator.constants import GOOGLE_LANGUAGES_TO_CODES
4
+ from deep_translator.exceptions import InvalidSourceOrTargetLanguage
5
  from abc import ABC, abstractmethod
6
 
7
 
 
9
  """
10
  Abstract class that serve as a base translator for other different translators
11
  """
12
+
13
+ def __init__(
14
+ self,
15
+ base_url=None,
16
+ source="auto",
17
+ target="en",
18
+ payload_key=None,
19
+ element_tag=None,
20
+ element_query=None,
21
+ languages=None,
22
+ **url_params
23
+ ):
24
  """
25
  @param source: source language to translate from
26
  @param target: target language to translate to
 
50
  @return: mapped value of the language or raise an exception if the language is not supported
51
  """
52
  for language in languages:
53
+ if language in self.languages.values() or language == "auto":
54
  yield language
55
  elif language in self.languages.keys():
56
  yield self.languages[language]
 
72
  @param language: a string for 1 language
73
  @return: bool or raise an Exception
74
  """
75
+ if (
76
+ language == "auto"
77
+ or language in self.languages.keys()
78
+ or language in self.languages.values()
79
+ ):
80
  return True
81
  else:
82
  return False
 
89
  @param kwargs: additional arguments
90
  @return: str
91
  """
92
+ return NotImplemented("You need to implement the translate method!")
93
 
94
  def _translate_file(self, path, **kwargs):
95
  """
 
100
  @return: str
101
  """
102
  try:
103
+ with open(path, "r", encoding="utf-8") as f:
104
  text = f.read().strip()
105
  return self.translate(text)
106
  except Exception as e:
deep_translator/cli.py CHANGED
@@ -1,6 +1,6 @@
1
  """Console script for deep_translator."""
2
  import argparse
3
- from .engines import __engines__
4
 
5
 
6
  class CLI(object):
@@ -12,9 +12,13 @@ class CLI(object):
12
  self.args = self.parse_args()
13
  translator_class = self.translators_dict.get(self.args.translator, None)
14
  if not translator_class:
15
- raise Exception(f"Translator {self.args.translator} is not supported."
16
- f"Supported translators: {list(self.translators_dict.keys())}")
17
- self.translator = translator_class(source=self.args.source, target=self.args.target)
 
 
 
 
18
 
19
  def translate(self):
20
  """
@@ -22,9 +26,9 @@ class CLI(object):
22
  @return: None
23
  """
24
  res = self.translator.translate(self.args.text)
25
- print("Translation from {} to {}".format(self.args.source, self.args.target))
26
  print("-" * 50)
27
- print("Translation result: {}".format(res))
28
 
29
  def get_supported_languages(self):
30
  """
@@ -32,42 +36,54 @@ class CLI(object):
32
  @return: None
33
  """
34
 
35
- translator_supported_languages = self.translator.get_supported_languages(as_dict=True)
36
- print(f'Languages supported by \'{self.args.translator}\' are :\n')
 
 
37
  print(translator_supported_languages)
38
 
39
  def parse_args(self):
40
  """
41
  function responsible for parsing terminal arguments and provide them for further use in the translation process
42
  """
43
- parser = argparse.ArgumentParser(add_help=True,
44
- description="Official CLI for deep-translator",
45
- usage="dt --help")
 
 
46
 
47
- parser.add_argument('--translator',
48
- '-trans',
49
- default='google',
50
- type=str,
51
- help="name of the translator you want to use")
52
- parser.add_argument('--source',
53
- '-src',
54
- default='auto',
55
- type=str,
56
- help="source language to translate from")
57
- parser.add_argument('--target',
58
- '-tg',
59
- type=str,
60
- help="target language to translate to")
61
- parser.add_argument('--text',
62
- '-txt',
63
- type=str,
64
- help="text you want to translate")
65
- parser.add_argument('--languages',
66
- '-lang',
67
- action='store_true',
68
- help="all the languages available with the translator"
69
- "Run the command deep_translator -trans <translator service> -lang")
70
- parsed_args = parser.parse_args(self.custom_args) if self.custom_args else parser.parse_args()
 
 
 
 
 
 
 
 
71
  return parsed_args
72
 
73
  def run(self):
 
1
  """Console script for deep_translator."""
2
  import argparse
3
+ from deep_translator.engines import __engines__
4
 
5
 
6
  class CLI(object):
 
12
  self.args = self.parse_args()
13
  translator_class = self.translators_dict.get(self.args.translator, None)
14
  if not translator_class:
15
+ raise Exception(
16
+ f"Translator {self.args.translator} is not supported."
17
+ f"Supported translators: {list(self.translators_dict.keys())}"
18
+ )
19
+ self.translator = translator_class(
20
+ source=self.args.source, target=self.args.target
21
+ )
22
 
23
  def translate(self):
24
  """
 
26
  @return: None
27
  """
28
  res = self.translator.translate(self.args.text)
29
+ print(f"Translation from {self.args.source} to {self.args.target}")
30
  print("-" * 50)
31
+ print(f"Translation result: {res}")
32
 
33
  def get_supported_languages(self):
34
  """
 
36
  @return: None
37
  """
38
 
39
+ translator_supported_languages = self.translator.get_supported_languages(
40
+ as_dict=True
41
+ )
42
+ print(f"Languages supported by '{self.args.translator}' are :\n")
43
  print(translator_supported_languages)
44
 
45
  def parse_args(self):
46
  """
47
  function responsible for parsing terminal arguments and provide them for further use in the translation process
48
  """
49
+ parser = argparse.ArgumentParser(
50
+ add_help=True,
51
+ description="Official CLI for deep-translator",
52
+ usage="dt --help",
53
+ )
54
 
55
+ parser.add_argument(
56
+ "--translator",
57
+ "-trans",
58
+ default="google",
59
+ type=str,
60
+ help="name of the translator you want to use",
61
+ )
62
+ parser.add_argument(
63
+ "--source",
64
+ "-src",
65
+ default="auto",
66
+ type=str,
67
+ help="source language to translate from",
68
+ )
69
+ parser.add_argument(
70
+ "--target", "-tg", type=str, help="target language to translate to"
71
+ )
72
+ parser.add_argument(
73
+ "--text", "-txt", type=str, help="text you want to translate"
74
+ )
75
+ parser.add_argument(
76
+ "--languages",
77
+ "-lang",
78
+ action="store_true",
79
+ help="all the languages available with the translator"
80
+ "Run the command deep_translator -trans <translator service> -lang",
81
+ )
82
+ parsed_args = (
83
+ parser.parse_args(self.custom_args)
84
+ if self.custom_args
85
+ else parser.parse_args()
86
+ )
87
  return parsed_args
88
 
89
  def run(self):
deep_translator/constants.py CHANGED
@@ -1,5 +1,3 @@
1
- import requests
2
-
3
  BASE_URLS = {
4
  "GOOGLE_TRANSLATE": "https://translate.google.com/m",
5
  "PONS": "https://en.pons.com/translate/",
@@ -17,150 +15,150 @@ BASE_URLS = {
17
  }
18
 
19
  GOOGLE_CODES_TO_LANGUAGES = {
20
- 'af': 'afrikaans',
21
- 'sq': 'albanian',
22
- 'am': 'amharic',
23
- 'ar': 'arabic',
24
- 'hy': 'armenian',
25
- 'az': 'azerbaijani',
26
- 'eu': 'basque',
27
- 'be': 'belarusian',
28
- 'bn': 'bengali',
29
- 'bs': 'bosnian',
30
- 'bg': 'bulgarian',
31
- 'ca': 'catalan',
32
- 'ceb': 'cebuano',
33
- 'ny': 'chichewa',
34
- 'zh-CN': 'chinese (simplified)',
35
- 'zh-TW': 'chinese (traditional)',
36
- 'co': 'corsican',
37
- 'hr': 'croatian',
38
- 'cs': 'czech',
39
- 'da': 'danish',
40
- 'nl': 'dutch',
41
- 'en': 'english',
42
- 'eo': 'esperanto',
43
- 'et': 'estonian',
44
- 'tl': 'filipino',
45
- 'fi': 'finnish',
46
- 'fr': 'french',
47
- 'fy': 'frisian',
48
- 'gl': 'galician',
49
- 'ka': 'georgian',
50
- 'de': 'german',
51
- 'el': 'greek',
52
- 'gu': 'gujarati',
53
- 'ht': 'haitian creole',
54
- 'ha': 'hausa',
55
- 'haw': 'hawaiian',
56
- 'iw': 'hebrew',
57
- 'hi': 'hindi',
58
- 'hmn': 'hmong',
59
- 'hu': 'hungarian',
60
- 'is': 'icelandic',
61
- 'ig': 'igbo',
62
- 'id': 'indonesian',
63
- 'ga': 'irish',
64
- 'it': 'italian',
65
- 'ja': 'japanese',
66
- 'jw': 'javanese',
67
- 'kn': 'kannada',
68
- 'kk': 'kazakh',
69
- 'km': 'khmer',
70
- 'rw': 'kinyarwanda',
71
- 'ko': 'korean',
72
- 'ku': 'kurdish',
73
- 'ky': 'kyrgyz',
74
- 'lo': 'lao',
75
- 'la': 'latin',
76
- 'lv': 'latvian',
77
- 'lt': 'lithuanian',
78
- 'lb': 'luxembourgish',
79
- 'mk': 'macedonian',
80
- 'mg': 'malagasy',
81
- 'ms': 'malay',
82
- 'ml': 'malayalam',
83
- 'mt': 'maltese',
84
- 'mi': 'maori',
85
- 'mr': 'marathi',
86
- 'mn': 'mongolian',
87
- 'my': 'myanmar',
88
- 'ne': 'nepali',
89
- 'no': 'norwegian',
90
- 'or': 'odia',
91
- 'ps': 'pashto',
92
- 'fa': 'persian',
93
- 'pl': 'polish',
94
- 'pt': 'portuguese',
95
- 'pa': 'punjabi',
96
- 'ro': 'romanian',
97
- 'ru': 'russian',
98
- 'sm': 'samoan',
99
- 'gd': 'scots gaelic',
100
- 'sr': 'serbian',
101
- 'st': 'sesotho',
102
- 'sn': 'shona',
103
- 'sd': 'sindhi',
104
- 'si': 'sinhala',
105
- 'sk': 'slovak',
106
- 'sl': 'slovenian',
107
- 'so': 'somali',
108
- 'es': 'spanish',
109
- 'su': 'sundanese',
110
- 'sw': 'swahili',
111
- 'sv': 'swedish',
112
- 'tg': 'tajik',
113
- 'ta': 'tamil',
114
- 'tt': 'tatar',
115
- 'te': 'telugu',
116
- 'th': 'thai',
117
- 'tr': 'turkish',
118
- 'tk': 'turkmen',
119
- 'uk': 'ukrainian',
120
- 'ur': 'urdu',
121
- 'ug': 'uyghur',
122
- 'uz': 'uzbek',
123
- 'vi': 'vietnamese',
124
- 'cy': 'welsh',
125
- 'xh': 'xhosa',
126
- 'yi': 'yiddish',
127
- 'yo': 'yoruba',
128
- 'zu': 'zulu',
129
  }
130
 
131
  GOOGLE_LANGUAGES_TO_CODES = {v: k for k, v in GOOGLE_CODES_TO_LANGUAGES.items()}
132
 
133
  # This dictionary maps the primary name of language to its secondary names in list manner (if any)
134
  GOOGLE_LANGUAGES_SECONDARY_NAMES = {
135
- 'myanmar': ['burmese'],
136
- 'odia': ['oriya'],
137
- 'kurdish': ['kurmanji']
138
  }
139
 
140
 
141
  PONS_CODES_TO_LANGUAGES = {
142
- 'ar': 'arabic',
143
- 'bg': 'bulgarian',
144
- 'zh-cn': 'chinese',
145
- 'cs': 'czech',
146
- 'da': 'danish',
147
- 'nl': 'dutch',
148
- 'en': 'english',
149
- 'fr': 'french',
150
- 'de': 'german',
151
- 'el': 'greek',
152
- 'hu': 'hungarian',
153
- 'it': 'italian',
154
- 'la': 'latin',
155
- 'no': 'norwegian',
156
- 'pl': 'polish',
157
- 'pt': 'portuguese',
158
- 'ru': 'russian',
159
- 'sl': 'slovenian',
160
- 'es': 'spanish',
161
- 'sv': 'swedish',
162
- 'tr': 'turkish',
163
- 'elv': 'elvish'
164
  }
165
 
166
  PONS_LANGUAGES_TO_CODES = {v: k for k, v in PONS_CODES_TO_LANGUAGES.items()}
@@ -192,7 +190,7 @@ LINGUEE_LANGUAGES_TO_CODES = {
192
  "swedish": "sv",
193
  "latvian": "lv",
194
  "estonian": "et",
195
- "japanese": "ja"
196
  }
197
 
198
  LINGUEE_CODE_TO_LANGUAGE = {v: k for k, v in LINGUEE_LANGUAGES_TO_CODES.items()}
@@ -221,56 +219,48 @@ DEEPL_LANGUAGE_TO_CODE = {
221
  "slovak": "sk",
222
  "slovenian": "sl",
223
  "swedish": "sv",
224
- "chinese": "zh"
225
  }
226
 
227
  DEEPL_CODE_TO_LANGUAGE = {v: k for k, v in DEEPL_LANGUAGE_TO_CODE.items()}
228
 
229
  PAPAGO_CODE_TO_LANGUAGE = {
230
- 'ko': 'Korean',
231
- 'en': 'English',
232
- 'ja': 'Japanese',
233
- 'zh-CN': 'Chinese',
234
- 'zh-TW': 'Chinese traditional',
235
- 'es': 'Spanish',
236
- 'fr': 'French',
237
- 'vi': 'Vietnamese',
238
- 'th': 'Thai',
239
- 'id': 'Indonesia'
240
  }
241
 
242
  PAPAGO_LANGUAGE_TO_CODE = {v: k for v, k in PAPAGO_CODE_TO_LANGUAGE.items()}
243
 
244
- QCRI_CODE_TO_LANGUAGE = {
245
- 'ar': 'Arabic',
246
- 'en': 'English',
247
- 'es': 'Spanish'
248
- }
249
 
250
- QCRI_LANGUAGE_TO_CODE = {
251
- v: k for k, v in QCRI_CODE_TO_LANGUAGE.items()
252
- }
253
 
254
  LIBRE_CODES_TO_LANGUAGES = {
255
- 'en': 'English',
256
- 'ar': 'Arabic',
257
- 'zh': 'Chinese',
258
- 'fr': 'French',
259
- 'de': 'German',
260
- 'hi': 'Hindi',
261
- 'id': 'Indonesian',
262
- 'ga': 'Irish',
263
- 'it': 'Italian',
264
- 'ja': 'Japanese',
265
- 'ko': 'Korean',
266
- 'pl': 'Polish',
267
- 'pt': 'Portuguese',
268
- 'ru': 'Russian',
269
- 'es': 'Spanish',
270
- 'tr': 'Turkish',
271
- 'vi': 'Vietnamese'
272
  }
273
 
274
- LIBRE_LANGUAGES_TO_CODES = {
275
- v: k for k, v in LIBRE_CODES_TO_LANGUAGES.items()
276
- }
 
 
 
1
  BASE_URLS = {
2
  "GOOGLE_TRANSLATE": "https://translate.google.com/m",
3
  "PONS": "https://en.pons.com/translate/",
 
15
  }
16
 
17
  GOOGLE_CODES_TO_LANGUAGES = {
18
+ "af": "afrikaans",
19
+ "sq": "albanian",
20
+ "am": "amharic",
21
+ "ar": "arabic",
22
+ "hy": "armenian",
23
+ "az": "azerbaijani",
24
+ "eu": "basque",
25
+ "be": "belarusian",
26
+ "bn": "bengali",
27
+ "bs": "bosnian",
28
+ "bg": "bulgarian",
29
+ "ca": "catalan",
30
+ "ceb": "cebuano",
31
+ "ny": "chichewa",
32
+ "zh-CN": "chinese (simplified)",
33
+ "zh-TW": "chinese (traditional)",
34
+ "co": "corsican",
35
+ "hr": "croatian",
36
+ "cs": "czech",
37
+ "da": "danish",
38
+ "nl": "dutch",
39
+ "en": "english",
40
+ "eo": "esperanto",
41
+ "et": "estonian",
42
+ "tl": "filipino",
43
+ "fi": "finnish",
44
+ "fr": "french",
45
+ "fy": "frisian",
46
+ "gl": "galician",
47
+ "ka": "georgian",
48
+ "de": "german",
49
+ "el": "greek",
50
+ "gu": "gujarati",
51
+ "ht": "haitian creole",
52
+ "ha": "hausa",
53
+ "haw": "hawaiian",
54
+ "iw": "hebrew",
55
+ "hi": "hindi",
56
+ "hmn": "hmong",
57
+ "hu": "hungarian",
58
+ "is": "icelandic",
59
+ "ig": "igbo",
60
+ "id": "indonesian",
61
+ "ga": "irish",
62
+ "it": "italian",
63
+ "ja": "japanese",
64
+ "jw": "javanese",
65
+ "kn": "kannada",
66
+ "kk": "kazakh",
67
+ "km": "khmer",
68
+ "rw": "kinyarwanda",
69
+ "ko": "korean",
70
+ "ku": "kurdish",
71
+ "ky": "kyrgyz",
72
+ "lo": "lao",
73
+ "la": "latin",
74
+ "lv": "latvian",
75
+ "lt": "lithuanian",
76
+ "lb": "luxembourgish",
77
+ "mk": "macedonian",
78
+ "mg": "malagasy",
79
+ "ms": "malay",
80
+ "ml": "malayalam",
81
+ "mt": "maltese",
82
+ "mi": "maori",
83
+ "mr": "marathi",
84
+ "mn": "mongolian",
85
+ "my": "myanmar",
86
+ "ne": "nepali",
87
+ "no": "norwegian",
88
+ "or": "odia",
89
+ "ps": "pashto",
90
+ "fa": "persian",
91
+ "pl": "polish",
92
+ "pt": "portuguese",
93
+ "pa": "punjabi",
94
+ "ro": "romanian",
95
+ "ru": "russian",
96
+ "sm": "samoan",
97
+ "gd": "scots gaelic",
98
+ "sr": "serbian",
99
+ "st": "sesotho",
100
+ "sn": "shona",
101
+ "sd": "sindhi",
102
+ "si": "sinhala",
103
+ "sk": "slovak",
104
+ "sl": "slovenian",
105
+ "so": "somali",
106
+ "es": "spanish",
107
+ "su": "sundanese",
108
+ "sw": "swahili",
109
+ "sv": "swedish",
110
+ "tg": "tajik",
111
+ "ta": "tamil",
112
+ "tt": "tatar",
113
+ "te": "telugu",
114
+ "th": "thai",
115
+ "tr": "turkish",
116
+ "tk": "turkmen",
117
+ "uk": "ukrainian",
118
+ "ur": "urdu",
119
+ "ug": "uyghur",
120
+ "uz": "uzbek",
121
+ "vi": "vietnamese",
122
+ "cy": "welsh",
123
+ "xh": "xhosa",
124
+ "yi": "yiddish",
125
+ "yo": "yoruba",
126
+ "zu": "zulu",
127
  }
128
 
129
  GOOGLE_LANGUAGES_TO_CODES = {v: k for k, v in GOOGLE_CODES_TO_LANGUAGES.items()}
130
 
131
  # This dictionary maps the primary name of language to its secondary names in list manner (if any)
132
  GOOGLE_LANGUAGES_SECONDARY_NAMES = {
133
+ "myanmar": ["burmese"],
134
+ "odia": ["oriya"],
135
+ "kurdish": ["kurmanji"],
136
  }
137
 
138
 
139
  PONS_CODES_TO_LANGUAGES = {
140
+ "ar": "arabic",
141
+ "bg": "bulgarian",
142
+ "zh-cn": "chinese",
143
+ "cs": "czech",
144
+ "da": "danish",
145
+ "nl": "dutch",
146
+ "en": "english",
147
+ "fr": "french",
148
+ "de": "german",
149
+ "el": "greek",
150
+ "hu": "hungarian",
151
+ "it": "italian",
152
+ "la": "latin",
153
+ "no": "norwegian",
154
+ "pl": "polish",
155
+ "pt": "portuguese",
156
+ "ru": "russian",
157
+ "sl": "slovenian",
158
+ "es": "spanish",
159
+ "sv": "swedish",
160
+ "tr": "turkish",
161
+ "elv": "elvish",
162
  }
163
 
164
  PONS_LANGUAGES_TO_CODES = {v: k for k, v in PONS_CODES_TO_LANGUAGES.items()}
 
190
  "swedish": "sv",
191
  "latvian": "lv",
192
  "estonian": "et",
193
+ "japanese": "ja",
194
  }
195
 
196
  LINGUEE_CODE_TO_LANGUAGE = {v: k for k, v in LINGUEE_LANGUAGES_TO_CODES.items()}
 
219
  "slovak": "sk",
220
  "slovenian": "sl",
221
  "swedish": "sv",
222
+ "chinese": "zh",
223
  }
224
 
225
  DEEPL_CODE_TO_LANGUAGE = {v: k for k, v in DEEPL_LANGUAGE_TO_CODE.items()}
226
 
227
  PAPAGO_CODE_TO_LANGUAGE = {
228
+ "ko": "Korean",
229
+ "en": "English",
230
+ "ja": "Japanese",
231
+ "zh-CN": "Chinese",
232
+ "zh-TW": "Chinese traditional",
233
+ "es": "Spanish",
234
+ "fr": "French",
235
+ "vi": "Vietnamese",
236
+ "th": "Thai",
237
+ "id": "Indonesia",
238
  }
239
 
240
  PAPAGO_LANGUAGE_TO_CODE = {v: k for v, k in PAPAGO_CODE_TO_LANGUAGE.items()}
241
 
242
+ QCRI_CODE_TO_LANGUAGE = {"ar": "Arabic", "en": "English", "es": "Spanish"}
 
 
 
 
243
 
244
+ QCRI_LANGUAGE_TO_CODE = {v: k for k, v in QCRI_CODE_TO_LANGUAGE.items()}
 
 
245
 
246
  LIBRE_CODES_TO_LANGUAGES = {
247
+ "en": "English",
248
+ "ar": "Arabic",
249
+ "zh": "Chinese",
250
+ "fr": "French",
251
+ "de": "German",
252
+ "hi": "Hindi",
253
+ "id": "Indonesian",
254
+ "ga": "Irish",
255
+ "it": "Italian",
256
+ "ja": "Japanese",
257
+ "ko": "Korean",
258
+ "pl": "Polish",
259
+ "pt": "Portuguese",
260
+ "ru": "Russian",
261
+ "es": "Spanish",
262
+ "tr": "Turkish",
263
+ "vi": "Vietnamese",
264
  }
265
 
266
+ LIBRE_LANGUAGES_TO_CODES = {v: k for k, v in LIBRE_CODES_TO_LANGUAGES.items()}
 
 
deep_translator/deepl.py CHANGED
@@ -2,9 +2,11 @@ import requests
2
 
3
  from deep_translator.validate import is_empty, validate_input
4
  from deep_translator.constants import BASE_URLS, DEEPL_LANGUAGE_TO_CODE
5
- from deep_translator.exceptions import (ServerException,
6
- TranslationNotFound,
7
- AuthorizationException)
 
 
8
  from deep_translator.base import BaseTranslator
9
 
10
 
@@ -13,7 +15,9 @@ class DeeplTranslator(BaseTranslator):
13
  class that wraps functions, which use the DeeplTranslator translator under the hood to translate word(s)
14
  """
15
 
16
- def __init__(self, api_key=None, source="de", target="en", use_free_api=True, **kwargs):
 
 
17
  """
18
  @param api_key: your DeeplTranslator api key.
19
  Get one here: https://www.deepl.com/docs-api/accessing-the-api/
@@ -22,17 +26,20 @@ class DeeplTranslator(BaseTranslator):
22
  """
23
  if not api_key:
24
  raise ServerException(401)
25
- self.version = 'v2'
26
  self.api_key = api_key
27
- url = BASE_URLS.get(
28
- "DEEPL_FREE").format(version=self.version) if use_free_api else BASE_URLS.get(
29
- "DEEPL").format(version=self.version)
 
 
30
  super().__init__(
31
  base_url=url,
32
  source=source,
33
  target=target,
34
  languages=DEEPL_LANGUAGE_TO_CODE,
35
- **kwargs)
 
36
 
37
  def translate(self, text, **kwargs):
38
  """
@@ -44,17 +51,18 @@ class DeeplTranslator(BaseTranslator):
44
  return text
45
 
46
  # Create the request parameters.
47
- translate_endpoint = 'translate'
48
  params = {
49
  "auth_key": self.api_key,
50
  "source_lang": self._source,
51
  "target_lang": self._target,
52
- "text": text
53
  }
54
  # Do the request and check the connection.
55
  try:
56
  response = requests.get(
57
- self._base_url + translate_endpoint, params=params)
 
58
  except ConnectionError:
59
  raise ServerException(503)
60
  # If the answer is not success, raise server exception.
@@ -67,7 +75,7 @@ class DeeplTranslator(BaseTranslator):
67
  if not res:
68
  raise TranslationNotFound(text)
69
  # Process and return the response.
70
- return res['translations'][0]['text']
71
 
72
  def translate_file(self, path, **kwargs):
73
  return self._translate_file(path, **kwargs)
@@ -80,7 +88,7 @@ class DeeplTranslator(BaseTranslator):
80
  return self._translate_batch(batch, **kwargs)
81
 
82
 
83
- if __name__ == '__main__':
84
  d = DeeplTranslator(target="en", api_key="some-key")
85
  t = d.translate("Ich habe keine ahnung")
86
  print("text: ", t)
 
2
 
3
  from deep_translator.validate import is_empty, validate_input
4
  from deep_translator.constants import BASE_URLS, DEEPL_LANGUAGE_TO_CODE
5
+ from deep_translator.exceptions import (
6
+ ServerException,
7
+ TranslationNotFound,
8
+ AuthorizationException,
9
+ )
10
  from deep_translator.base import BaseTranslator
11
 
12
 
 
15
  class that wraps functions, which use the DeeplTranslator translator under the hood to translate word(s)
16
  """
17
 
18
+ def __init__(
19
+ self, api_key=None, source="de", target="en", use_free_api=True, **kwargs
20
+ ):
21
  """
22
  @param api_key: your DeeplTranslator api key.
23
  Get one here: https://www.deepl.com/docs-api/accessing-the-api/
 
26
  """
27
  if not api_key:
28
  raise ServerException(401)
29
+ self.version = "v2"
30
  self.api_key = api_key
31
+ url = (
32
+ BASE_URLS.get("DEEPL_FREE").format(version=self.version)
33
+ if use_free_api
34
+ else BASE_URLS.get("DEEPL").format(version=self.version)
35
+ )
36
  super().__init__(
37
  base_url=url,
38
  source=source,
39
  target=target,
40
  languages=DEEPL_LANGUAGE_TO_CODE,
41
+ **kwargs
42
+ )
43
 
44
  def translate(self, text, **kwargs):
45
  """
 
51
  return text
52
 
53
  # Create the request parameters.
54
+ translate_endpoint = "translate"
55
  params = {
56
  "auth_key": self.api_key,
57
  "source_lang": self._source,
58
  "target_lang": self._target,
59
+ "text": text,
60
  }
61
  # Do the request and check the connection.
62
  try:
63
  response = requests.get(
64
+ self._base_url + translate_endpoint, params=params
65
+ )
66
  except ConnectionError:
67
  raise ServerException(503)
68
  # If the answer is not success, raise server exception.
 
75
  if not res:
76
  raise TranslationNotFound(text)
77
  # Process and return the response.
78
+ return res["translations"][0]["text"]
79
 
80
  def translate_file(self, path, **kwargs):
81
  return self._translate_file(path, **kwargs)
 
88
  return self._translate_batch(batch, **kwargs)
89
 
90
 
91
+ if __name__ == "__main__":
92
  d = DeeplTranslator(target="en", api_key="some-key")
93
  t = d.translate("Ich habe keine ahnung")
94
  print("text: ", t)
deep_translator/detection.py CHANGED
@@ -5,7 +5,13 @@ import requests
5
  from requests.exceptions import HTTPError
6
 
7
  # Module global config
8
- config = {"url": 'https://ws.detectlanguage.com/0.2/detect',"headers": {'User-Agent': 'Detect Language API Python Client 1.4.0','Authorization': 'Bearer {}',}}
 
 
 
 
 
 
9
 
10
 
11
  def get_request_body(text, api_key, *args, **kwargs):
@@ -19,20 +25,20 @@ def get_request_body(text, api_key, *args, **kwargs):
19
 
20
  """
21
  if not api_key:
22
- raise Exception("you need to get an API_KEY for this to work. "
23
- "Get one for free here: https://detectlanguage.com/documentation")
 
 
24
  if not text:
25
  raise Exception("Please provide an input text")
26
 
27
  else:
28
  try:
29
- headers = config['headers']
30
- headers['Authorization'] = headers['Authorization'].format(api_key)
31
- response = requests.post(config['url'],
32
- json={'q': text},
33
- headers=headers)
34
 
35
- body = response.json().get('data')
36
  return body
37
 
38
  except HTTPError as e:
@@ -51,11 +57,11 @@ def single_detection(text, api_key=None, detailed=False, *args, **kwargs):
51
  @param detailed: set to True if you want to get detailed information about the detection process
52
  """
53
  body = get_request_body(text, api_key)
54
- detections = body.get('detections')
55
  if detailed:
56
  return detections[0]
57
 
58
- lang = detections[0].get('language', None)
59
  if lang:
60
  return lang
61
 
@@ -69,10 +75,9 @@ def batch_detection(text_list, api_key, detailed=False, *args, **kwargs):
69
  @param detailed: set to True if you want to get detailed information about the detection process
70
  """
71
  body = get_request_body(text_list, api_key)
72
- detections = body.get('detections')
73
  res = [obj[0] for obj in detections]
74
  if detailed:
75
  return res
76
  else:
77
- return [obj['language'] for obj in res]
78
-
 
5
  from requests.exceptions import HTTPError
6
 
7
  # Module global config
8
+ config = {
9
+ "url": "https://ws.detectlanguage.com/0.2/detect",
10
+ "headers": {
11
+ "User-Agent": "Detect Language API Python Client 1.4.0",
12
+ "Authorization": "Bearer {}",
13
+ },
14
+ }
15
 
16
 
17
  def get_request_body(text, api_key, *args, **kwargs):
 
25
 
26
  """
27
  if not api_key:
28
+ raise Exception(
29
+ "you need to get an API_KEY for this to work. "
30
+ "Get one for free here: https://detectlanguage.com/documentation"
31
+ )
32
  if not text:
33
  raise Exception("Please provide an input text")
34
 
35
  else:
36
  try:
37
+ headers = config["headers"]
38
+ headers["Authorization"] = headers["Authorization"].format(api_key)
39
+ response = requests.post(config["url"], json={"q": text}, headers=headers)
 
 
40
 
41
+ body = response.json().get("data")
42
  return body
43
 
44
  except HTTPError as e:
 
57
  @param detailed: set to True if you want to get detailed information about the detection process
58
  """
59
  body = get_request_body(text, api_key)
60
+ detections = body.get("detections")
61
  if detailed:
62
  return detections[0]
63
 
64
+ lang = detections[0].get("language", None)
65
  if lang:
66
  return lang
67
 
 
75
  @param detailed: set to True if you want to get detailed information about the detection process
76
  """
77
  body = get_request_body(text_list, api_key)
78
+ detections = body.get("detections")
79
  res = [obj[0] for obj in detections]
80
  if detailed:
81
  return res
82
  else:
83
+ return [obj["language"] for obj in res]
 
deep_translator/engines.py CHANGED
@@ -1,7 +1,6 @@
1
-
2
- from .base import BaseTranslator
3
 
4
  __engines__ = {
5
- translator.__name__.replace('Translator', '').lower():
6
- translator for translator in BaseTranslator.__subclasses__()
7
  }
 
1
+ from deep_translator.base import BaseTranslator
 
2
 
3
  __engines__ = {
4
+ translator.__name__.replace("Translator", "").lower(): translator
5
+ for translator in BaseTranslator.__subclasses__()
6
  }
deep_translator/exceptions.py CHANGED
@@ -30,9 +30,11 @@ class NotValidPayload(BaseError):
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'):
 
 
36
  super(NotValidPayload, self).__init__(val, message)
37
 
38
 
@@ -41,9 +43,7 @@ class InvalidSourceOrTargetLanguage(BaseError):
41
  exception thrown if the user enters an invalid payload
42
  """
43
 
44
- def __init__(self,
45
- val,
46
- message="Invalid source or target language!"):
47
  super(InvalidSourceOrTargetLanguage, self).__init__(val, message)
48
 
49
 
@@ -52,9 +52,11 @@ class TranslationNotFound(BaseError):
52
  exception thrown if no translation was found for the text provided by the user
53
  """
54
 
55
- def __init__(self,
56
- val,
57
- message='No translation was found using the current translator. Try another translator?'):
 
 
58
  super(TranslationNotFound, self).__init__(val, message)
59
 
60
 
@@ -63,9 +65,9 @@ class ElementNotFoundInGetRequest(BaseError):
63
  exception thrown if the html element was not found in the body parsed by beautifulsoup
64
  """
65
 
66
- def __init__(self,
67
- val,
68
- message='Required element was not found in the API response'):
69
  super(ElementNotFoundInGetRequest, self).__init__(val, message)
70
 
71
 
@@ -75,7 +77,9 @@ class NotValidLength(BaseError):
75
  """
76
 
77
  def __init__(self, val, min_chars, max_chars):
78
- message = "Text length need to be between {} and {} characters".format(min_chars, max_chars)
 
 
79
  super(NotValidLength, self).__init__(val, message)
80
 
81
 
@@ -84,8 +88,11 @@ class RequestError(Exception):
84
  exception thrown if an error occurred during the request call, e.g a connection problem.
85
  """
86
 
87
- def __init__(self, message="Request exception can happen due to an api connection error. "
88
- "Please check your connection and try again"):
 
 
 
89
  self.message = message
90
 
91
  def __str__(self):
@@ -99,7 +106,7 @@ class MicrosoftAPIerror(Exception):
99
 
100
  def __init__(self, api_message):
101
  self.api_message = str(api_message)
102
- self.message="Microsoft API returned the following error"
103
 
104
  def __str__(self):
105
  return "{}: {}".format(self.message, self.api_message)
@@ -110,7 +117,10 @@ class TooManyRequests(Exception):
110
  exception thrown if an error occurred during the request call, e.g a connection problem.
111
  """
112
 
113
- def __init__(self, message="Server Error: You made too many requests to the server. According to google, you are allowed to make 5 requests per second and up to 200k requests per day. You can wait and try again later or you can try the translate_batch function"):
 
 
 
114
  self.message = message
115
 
116
  def __str__(self):
@@ -121,6 +131,7 @@ class ServerException(Exception):
121
  """
122
  Default YandexTranslate exception from the official website
123
  """
 
124
  errors = {
125
  400: "ERR_BAD_REQUEST",
126
  401: "ERR_KEY_INVALID",
@@ -142,5 +153,5 @@ class ServerException(Exception):
142
 
143
  class AuthorizationException(Exception):
144
  def __init__(self, api_key, *args):
145
- msg = 'Unauthorized access with the api key ' + api_key
146
  super().__init__(msg, *args)
 
30
  exception thrown if the user enters an invalid payload
31
  """
32
 
33
+ def __init__(
34
+ self,
35
+ val,
36
+ message="text must be a valid text with maximum 5000 character, otherwise it cannot be translated",
37
+ ):
38
  super(NotValidPayload, self).__init__(val, message)
39
 
40
 
 
43
  exception thrown if the user enters an invalid payload
44
  """
45
 
46
+ def __init__(self, val, message="Invalid source or target language!"):
 
 
47
  super(InvalidSourceOrTargetLanguage, self).__init__(val, message)
48
 
49
 
 
52
  exception thrown if no translation was found for the text provided by the user
53
  """
54
 
55
+ def __init__(
56
+ self,
57
+ val,
58
+ message="No translation was found using the current translator. Try another translator?",
59
+ ):
60
  super(TranslationNotFound, self).__init__(val, message)
61
 
62
 
 
65
  exception thrown if the html element was not found in the body parsed by beautifulsoup
66
  """
67
 
68
+ def __init__(
69
+ self, val, message="Required element was not found in the API response"
70
+ ):
71
  super(ElementNotFoundInGetRequest, self).__init__(val, message)
72
 
73
 
 
77
  """
78
 
79
  def __init__(self, val, min_chars, max_chars):
80
+ message = (
81
+ f"Text length need to be between {min_chars} and {max_chars} characters"
82
+ )
83
  super(NotValidLength, self).__init__(val, message)
84
 
85
 
 
88
  exception thrown if an error occurred during the request call, e.g a connection problem.
89
  """
90
 
91
+ def __init__(
92
+ self,
93
+ message="Request exception can happen due to an api connection error. "
94
+ "Please check your connection and try again",
95
+ ):
96
  self.message = message
97
 
98
  def __str__(self):
 
106
 
107
  def __init__(self, api_message):
108
  self.api_message = str(api_message)
109
+ self.message = "Microsoft API returned the following error"
110
 
111
  def __str__(self):
112
  return "{}: {}".format(self.message, self.api_message)
 
117
  exception thrown if an error occurred during the request call, e.g a connection problem.
118
  """
119
 
120
+ def __init__(
121
+ self,
122
+ message="Server Error: You made too many requests to the server. According to google, you are allowed to make 5 requests per second and up to 200k requests per day. You can wait and try again later or you can try the translate_batch function",
123
+ ):
124
  self.message = message
125
 
126
  def __str__(self):
 
131
  """
132
  Default YandexTranslate exception from the official website
133
  """
134
+
135
  errors = {
136
  400: "ERR_BAD_REQUEST",
137
  401: "ERR_KEY_INVALID",
 
153
 
154
  class AuthorizationException(Exception):
155
  def __init__(self, api_key, *args):
156
+ msg = "Unauthorized access with the api key " + api_key
157
  super().__init__(msg, *args)
deep_translator/google.py CHANGED
@@ -3,7 +3,11 @@ google translator API
3
  """
4
 
5
  from deep_translator.constants import BASE_URLS
6
- from deep_translator.exceptions import TooManyRequests, TranslationNotFound, RequestError
 
 
 
 
7
  from deep_translator.base import BaseTranslator
8
  from deep_translator.validate import validate_input, is_empty
9
  from bs4 import BeautifulSoup
@@ -21,13 +25,15 @@ class GoogleTranslator(BaseTranslator):
21
  @param target: target language to translate to
22
  """
23
  self.proxies = proxies
24
- super().__init__(base_url=BASE_URLS.get("GOOGLE_TRANSLATE"),
25
- source=source,
26
- target=target,
27
- element_tag='div',
28
- element_query={"class": "t0"},
29
- payload_key='q', # key of text in the url
30
- **kwargs)
 
 
31
 
32
  self._alt_element_query = {"class": "result-container"}
33
 
@@ -41,22 +47,22 @@ class GoogleTranslator(BaseTranslator):
41
  text = text.strip()
42
  if self._same_source_target() or is_empty(text):
43
  return text
44
- self._url_params['tl'] = self._target
45
- self._url_params['sl'] = self._source
46
 
47
  if self.payload_key:
48
  self._url_params[self.payload_key] = text
49
 
50
- response = requests.get(self._base_url,
51
- params=self._url_params,
52
- proxies=self.proxies)
53
  if response.status_code == 429:
54
  raise TooManyRequests()
55
 
56
  if response.status_code != 200:
57
  raise RequestError()
58
 
59
- soup = BeautifulSoup(response.text, 'html.parser')
60
 
61
  element = soup.find(self._element_tag, self._element_query)
62
 
@@ -65,9 +71,15 @@ class GoogleTranslator(BaseTranslator):
65
  if not element:
66
  raise TranslationNotFound(text)
67
  if element.get_text(strip=True) == text.strip():
68
- to_translate_alpha = ''.join(ch for ch in text.strip() if ch.isalnum())
69
- translated_alpha = ''.join(ch for ch in element.get_text(strip=True) if ch.isalnum())
70
- if to_translate_alpha and translated_alpha and to_translate_alpha == translated_alpha:
 
 
 
 
 
 
71
  self._url_params["tl"] = self._target
72
  if "hl" not in self._url_params:
73
  return text.strip()
@@ -96,6 +108,6 @@ class GoogleTranslator(BaseTranslator):
96
  return self._translate_batch(batch, **kwargs)
97
 
98
 
99
- if __name__ == '__main__':
100
  t = GoogleTranslator().translate("hallo welt")
101
  print("translation: ", t)
 
3
  """
4
 
5
  from deep_translator.constants import BASE_URLS
6
+ from deep_translator.exceptions import (
7
+ TooManyRequests,
8
+ TranslationNotFound,
9
+ RequestError,
10
+ )
11
  from deep_translator.base import BaseTranslator
12
  from deep_translator.validate import validate_input, is_empty
13
  from bs4 import BeautifulSoup
 
25
  @param target: target language to translate to
26
  """
27
  self.proxies = proxies
28
+ super().__init__(
29
+ base_url=BASE_URLS.get("GOOGLE_TRANSLATE"),
30
+ source=source,
31
+ target=target,
32
+ element_tag="div",
33
+ element_query={"class": "t0"},
34
+ payload_key="q", # key of text in the url
35
+ **kwargs
36
+ )
37
 
38
  self._alt_element_query = {"class": "result-container"}
39
 
 
47
  text = text.strip()
48
  if self._same_source_target() or is_empty(text):
49
  return text
50
+ self._url_params["tl"] = self._target
51
+ self._url_params["sl"] = self._source
52
 
53
  if self.payload_key:
54
  self._url_params[self.payload_key] = text
55
 
56
+ response = requests.get(
57
+ self._base_url, params=self._url_params, proxies=self.proxies
58
+ )
59
  if response.status_code == 429:
60
  raise TooManyRequests()
61
 
62
  if response.status_code != 200:
63
  raise RequestError()
64
 
65
+ soup = BeautifulSoup(response.text, "html.parser")
66
 
67
  element = soup.find(self._element_tag, self._element_query)
68
 
 
71
  if not element:
72
  raise TranslationNotFound(text)
73
  if element.get_text(strip=True) == text.strip():
74
+ to_translate_alpha = "".join(ch for ch in text.strip() if ch.isalnum())
75
+ translated_alpha = "".join(
76
+ ch for ch in element.get_text(strip=True) if ch.isalnum()
77
+ )
78
+ if (
79
+ to_translate_alpha
80
+ and translated_alpha
81
+ and to_translate_alpha == translated_alpha
82
+ ):
83
  self._url_params["tl"] = self._target
84
  if "hl" not in self._url_params:
85
  return text.strip()
 
108
  return self._translate_batch(batch, **kwargs)
109
 
110
 
111
+ if __name__ == "__main__":
112
  t = GoogleTranslator().translate("hallo welt")
113
  print("translation: ", t)
deep_translator/libre.py CHANGED
@@ -4,12 +4,14 @@ LibreTranslate API
4
 
5
  import requests
6
 
7
- from .validate import is_empty, validate_input
8
- from .base import BaseTranslator
9
- from .constants import BASE_URLS,LIBRE_LANGUAGES_TO_CODES
10
- from .exceptions import (ServerException,
11
- TranslationNotFound,
12
- AuthorizationException)
 
 
13
 
14
 
15
  class LibreTranslator(BaseTranslator):
@@ -27,10 +29,12 @@ class LibreTranslator(BaseTranslator):
27
  if not api_key:
28
  raise ServerException(401)
29
  self.api_key = api_key
30
- super().__init__(base_url=BASE_URLS.get("LIBRE"),
31
- source=source,
32
- target=target,
33
- languages=LIBRE_LANGUAGES_TO_CODES)
 
 
34
 
35
  def translate(self, text, **kwargs):
36
  """
@@ -42,19 +46,21 @@ class LibreTranslator(BaseTranslator):
42
  if self._same_source_target() or is_empty(text):
43
  return text
44
 
45
- translate_endpoint = 'translate'
46
  params = {
47
  "q": text,
48
  "source": self._source,
49
  "target": self._target,
50
- "format": 'text'
51
  }
52
  # Add API Key if required
53
  if self.api_key:
54
  params["api_key"] = self.api_key
55
  # Do the request and check the connection.
56
  try:
57
- response = requests.post(self._base_url + translate_endpoint, params=params)
 
 
58
  except ConnectionError:
59
  raise ServerException(503)
60
  # If the answer is not success, raise server exception.
@@ -68,7 +74,7 @@ class LibreTranslator(BaseTranslator):
68
  if not res:
69
  raise TranslationNotFound(text)
70
  # Process and return the response.
71
- return res['translatedText']
72
 
73
  def translate_file(self, path, **kwargs):
74
  """
 
4
 
5
  import requests
6
 
7
+ from deep_translator.validate import is_empty, validate_input
8
+ from deep_translator.base import BaseTranslator
9
+ from deep_translator.constants import BASE_URLS, LIBRE_LANGUAGES_TO_CODES
10
+ from deep_translator.exceptions import (
11
+ ServerException,
12
+ TranslationNotFound,
13
+ AuthorizationException,
14
+ )
15
 
16
 
17
  class LibreTranslator(BaseTranslator):
 
29
  if not api_key:
30
  raise ServerException(401)
31
  self.api_key = api_key
32
+ super().__init__(
33
+ base_url=BASE_URLS.get("LIBRE"),
34
+ source=source,
35
+ target=target,
36
+ languages=LIBRE_LANGUAGES_TO_CODES,
37
+ )
38
 
39
  def translate(self, text, **kwargs):
40
  """
 
46
  if self._same_source_target() or is_empty(text):
47
  return text
48
 
49
+ translate_endpoint = "translate"
50
  params = {
51
  "q": text,
52
  "source": self._source,
53
  "target": self._target,
54
+ "format": "text",
55
  }
56
  # Add API Key if required
57
  if self.api_key:
58
  params["api_key"] = self.api_key
59
  # Do the request and check the connection.
60
  try:
61
+ response = requests.post(
62
+ self._base_url + translate_endpoint, params=params
63
+ )
64
  except ConnectionError:
65
  raise ServerException(503)
66
  # If the answer is not success, raise server exception.
 
74
  if not res:
75
  raise TranslationNotFound(text)
76
  # Process and return the response.
77
+ return res["translatedText"]
78
 
79
  def translate_file(self, path, **kwargs):
80
  """
deep_translator/linguee.py CHANGED
@@ -1,15 +1,16 @@
1
  """
2
  linguee translator API
3
  """
4
- from .validate import validate_input, is_empty
5
- from .constants import BASE_URLS, LINGUEE_LANGUAGES_TO_CODES
6
- from .exceptions import (
7
- TranslationNotFound,
8
- NotValidPayload,
9
- ElementNotFoundInGetRequest,
10
- RequestError,
11
- TooManyRequests)
12
- from .base import BaseTranslator
 
13
  from bs4 import BeautifulSoup
14
  import requests
15
  from requests.utils import requote_uri
@@ -26,14 +27,15 @@ class LingueeTranslator(BaseTranslator):
26
  @param target: target language to translate to
27
  """
28
  self.proxies = proxies
29
- super().__init__(base_url=BASE_URLS.get("LINGUEE"),
30
- source=source,
31
- target=target,
32
- languages=LINGUEE_LANGUAGES_TO_CODES,
33
- element_tag='a',
34
- element_query={'class': 'dictLink featured'},
35
- payload_key=None, # key of text in the url
36
- )
 
37
 
38
  def translate(self, word, return_all=False, **kwargs):
39
  """
@@ -49,7 +51,9 @@ class LingueeTranslator(BaseTranslator):
49
 
50
  if validate_input(word, max_chars=50):
51
  # %s-%s/translation/%s.html
52
- url = "{}{}-{}/translation/{}.html".format(self._base_url, self._source, self._target, word)
 
 
53
  url = requote_uri(url)
54
  response = requests.get(url, proxies=self.proxies)
55
 
@@ -58,7 +62,7 @@ class LingueeTranslator(BaseTranslator):
58
 
59
  if response.status_code != 200:
60
  raise RequestError()
61
- soup = BeautifulSoup(response.text, 'html.parser')
62
  elements = soup.find_all(self._element_tag, self._element_query)
63
  if not elements:
64
  raise ElementNotFoundInGetRequest(elements)
@@ -66,10 +70,12 @@ class LingueeTranslator(BaseTranslator):
66
  filtered_elements = []
67
  for el in elements:
68
  try:
69
- pronoun = el.find('span', {'class': 'placeholder'}).get_text(strip=True)
 
 
70
  except AttributeError:
71
- pronoun = ''
72
- filtered_elements.append(el.get_text(strip=True).replace(pronoun, ''))
73
 
74
  if not filtered_elements:
75
  raise TranslationNotFound(word)
@@ -90,4 +96,3 @@ class LingueeTranslator(BaseTranslator):
90
  for word in words:
91
  translated_words.append(self.translate(word=word, **kwargs))
92
  return translated_words
93
-
 
1
  """
2
  linguee translator API
3
  """
4
+ from deep_translator.validate import validate_input, is_empty
5
+ from deep_translator.constants import BASE_URLS, LINGUEE_LANGUAGES_TO_CODES
6
+ from deep_translator.exceptions import (
7
+ TranslationNotFound,
8
+ NotValidPayload,
9
+ ElementNotFoundInGetRequest,
10
+ RequestError,
11
+ TooManyRequests,
12
+ )
13
+ from deep_translator.base import BaseTranslator
14
  from bs4 import BeautifulSoup
15
  import requests
16
  from requests.utils import requote_uri
 
27
  @param target: target language to translate to
28
  """
29
  self.proxies = proxies
30
+ super().__init__(
31
+ base_url=BASE_URLS.get("LINGUEE"),
32
+ source=source,
33
+ target=target,
34
+ languages=LINGUEE_LANGUAGES_TO_CODES,
35
+ element_tag="a",
36
+ element_query={"class": "dictLink featured"},
37
+ payload_key=None, # key of text in the url
38
+ )
39
 
40
  def translate(self, word, return_all=False, **kwargs):
41
  """
 
51
 
52
  if validate_input(word, max_chars=50):
53
  # %s-%s/translation/%s.html
54
+ url = (
55
+ f"{self._base_url}{self._source}-{self._target}/translation/{word}.html"
56
+ )
57
  url = requote_uri(url)
58
  response = requests.get(url, proxies=self.proxies)
59
 
 
62
 
63
  if response.status_code != 200:
64
  raise RequestError()
65
+ soup = BeautifulSoup(response.text, "html.parser")
66
  elements = soup.find_all(self._element_tag, self._element_query)
67
  if not elements:
68
  raise ElementNotFoundInGetRequest(elements)
 
70
  filtered_elements = []
71
  for el in elements:
72
  try:
73
+ pronoun = el.find("span", {"class": "placeholder"}).get_text(
74
+ strip=True
75
+ )
76
  except AttributeError:
77
+ pronoun = ""
78
+ filtered_elements.append(el.get_text(strip=True).replace(pronoun, ""))
79
 
80
  if not filtered_elements:
81
  raise TranslationNotFound(word)
 
96
  for word in words:
97
  translated_words.append(self.translate(word=word, **kwargs))
98
  return translated_words
 
deep_translator/microsoft.py CHANGED
@@ -3,10 +3,10 @@
3
  import requests
4
  import logging
5
  import sys
6
- from .constants import BASE_URLS
7
- from .exceptions import ServerException, MicrosoftAPIerror
8
- from .base import BaseTranslator
9
- from .validate import validate_input
10
 
11
 
12
  class MicrosoftTranslator(BaseTranslator):
@@ -14,7 +14,15 @@ class MicrosoftTranslator(BaseTranslator):
14
  the class that wraps functions, which use the Microsoft translator under the hood to translate word(s)
15
  """
16
 
17
- def __init__(self, api_key=None, region=None, source=None, target=None, proxies=None, **kwargs):
 
 
 
 
 
 
 
 
18
  """
19
  @params api_key and target are the required params
20
  @param api_key: your Microsoft API key
@@ -41,17 +49,16 @@ class MicrosoftTranslator(BaseTranslator):
41
  source=source,
42
  target=target,
43
  languages=MICROSOFT_CODES_TO_LANGUAGES,
44
- **kwargs
45
  )
46
 
47
  def _get_supported_languages(self):
48
 
49
- microsoft_languages_api_url = \
50
- "https://api.cognitive.microsofttranslator.com/languages?api-version=3.0&scope=translation"
51
  microsoft_languages_response = requests.get(microsoft_languages_api_url)
52
- translation_dict = microsoft_languages_response.json()['translation']
53
 
54
- return {translation_dict[k]['name'].lower(): k for k in translation_dict.keys()}
55
 
56
  def translate(self, text, **kwargs):
57
  """
@@ -63,28 +70,31 @@ class MicrosoftTranslator(BaseTranslator):
63
  # I have not added multiple text processing here since it is covered by the translate_batch method
64
 
65
  if validate_input(text):
66
- self._url_params['from'] = self._source
67
- self._url_params['to'] = self._target
68
 
69
- valid_microsoft_json = [{'text': text}]
70
  try:
71
- requested = requests.post(self._base_url,
72
- params=self._url_params,
73
- headers=self.headers,
74
- json=valid_microsoft_json,
75
- proxies=self.proxies)
 
 
76
  except requests.exceptions.RequestException:
77
  exc_type, value, traceback = sys.exc_info()
78
  logging.warning(f"Returned error: {exc_type.__name__}")
79
 
80
  # Where Microsoft API responds with an api error, it returns a dict in response.json()
81
  if type(requested.json()) is dict:
82
- error_message = requested.json()['error']
83
  raise MicrosoftAPIerror(error_message)
84
  # Where it responds with a translation, its response.json() is a list e.g. [{'translations': [{'text': 'Hello world!', 'to': 'en'}]}]
85
  elif type(requested.json()) is list:
86
- all_translations = [i['text']
87
- for i in requested.json()[0]['translations']]
 
88
  return "\n".join(all_translations)
89
 
90
  def translate_file(self, path, **kwargs):
 
3
  import requests
4
  import logging
5
  import sys
6
+ from deep_translator.constants import BASE_URLS
7
+ from deep_translator.exceptions import ServerException, MicrosoftAPIerror
8
+ from deep_translator.base import BaseTranslator
9
+ from deep_translator.validate import validate_input
10
 
11
 
12
  class MicrosoftTranslator(BaseTranslator):
 
14
  the class that wraps functions, which use the Microsoft translator under the hood to translate word(s)
15
  """
16
 
17
+ def __init__(
18
+ self,
19
+ api_key=None,
20
+ region=None,
21
+ source=None,
22
+ target=None,
23
+ proxies=None,
24
+ **kwargs,
25
+ ):
26
  """
27
  @params api_key and target are the required params
28
  @param api_key: your Microsoft API key
 
49
  source=source,
50
  target=target,
51
  languages=MICROSOFT_CODES_TO_LANGUAGES,
52
+ **kwargs,
53
  )
54
 
55
  def _get_supported_languages(self):
56
 
57
+ microsoft_languages_api_url = "https://api.cognitive.microsofttranslator.com/languages?api-version=3.0&scope=translation"
 
58
  microsoft_languages_response = requests.get(microsoft_languages_api_url)
59
+ translation_dict = microsoft_languages_response.json()["translation"]
60
 
61
+ return {translation_dict[k]["name"].lower(): k for k in translation_dict.keys()}
62
 
63
  def translate(self, text, **kwargs):
64
  """
 
70
  # I have not added multiple text processing here since it is covered by the translate_batch method
71
 
72
  if validate_input(text):
73
+ self._url_params["from"] = self._source
74
+ self._url_params["to"] = self._target
75
 
76
+ valid_microsoft_json = [{"text": text}]
77
  try:
78
+ requested = requests.post(
79
+ self._base_url,
80
+ params=self._url_params,
81
+ headers=self.headers,
82
+ json=valid_microsoft_json,
83
+ proxies=self.proxies,
84
+ )
85
  except requests.exceptions.RequestException:
86
  exc_type, value, traceback = sys.exc_info()
87
  logging.warning(f"Returned error: {exc_type.__name__}")
88
 
89
  # Where Microsoft API responds with an api error, it returns a dict in response.json()
90
  if type(requested.json()) is dict:
91
+ error_message = requested.json()["error"]
92
  raise MicrosoftAPIerror(error_message)
93
  # Where it responds with a translation, its response.json() is a list e.g. [{'translations': [{'text': 'Hello world!', 'to': 'en'}]}]
94
  elif type(requested.json()) is list:
95
+ all_translations = [
96
+ i["text"] for i in requested.json()[0]["translations"]
97
+ ]
98
  return "\n".join(all_translations)
99
 
100
  def translate_file(self, path, **kwargs):
deep_translator/mymemory.py CHANGED
@@ -1,13 +1,14 @@
1
  """
2
  mymemory translator API
3
  """
4
- from .validate import is_empty, validate_input
5
- from .constants import BASE_URLS
6
- from .exceptions import (
7
- TranslationNotFound,
8
- RequestError,
9
- TooManyRequests)
10
- from .base import BaseTranslator
 
11
  import requests
12
 
13
 
@@ -15,18 +16,20 @@ class MyMemoryTranslator(BaseTranslator):
15
  """
16
  class that uses the mymemory translator to translate texts
17
  """
 
18
  def __init__(self, source="auto", target="en", proxies=None, **kwargs):
19
  """
20
  @param source: source language to translate from
21
  @param target: target language to translate to
22
  """
23
  self.proxies = proxies
24
- self.email = kwargs.get('email', None)
25
- super().__init__(base_url=BASE_URLS.get("MYMEMORY"),
26
- source=source,
27
- target=target,
28
- payload_key='q',
29
- )
 
30
 
31
  def translate(self, text, return_all=False, **kwargs):
32
  """
@@ -41,15 +44,15 @@ class MyMemoryTranslator(BaseTranslator):
41
  if self._same_source_target() or is_empty(text):
42
  return text
43
 
44
- self._url_params['langpair'] = '{}|{}'.format(self._source, self._target)
45
  if self.payload_key:
46
  self._url_params[self.payload_key] = text
47
  if self.email:
48
- self._url_params['de'] = self.email
49
 
50
- response = requests.get(self._base_url,
51
- params=self._url_params,
52
- proxies=self.proxies)
53
 
54
  if response.status_code == 429:
55
  raise TooManyRequests()
@@ -60,24 +63,24 @@ class MyMemoryTranslator(BaseTranslator):
60
  if not data:
61
  TranslationNotFound(text)
62
 
63
- translation = data.get('responseData').get('translatedText')
64
  if translation:
65
  return translation
66
 
67
  elif not translation:
68
- all_matches = data.get('matches')
69
- matches = (match['translation'] for match in all_matches)
70
  next_match = next(matches)
71
  return next_match if not return_all else list(all_matches)
72
 
73
  def translate_file(self, path, **kwargs):
74
  """
75
- translate directly from file
76
- @param path: path to the target file
77
- @type path: str
78
- @param kwargs: additional args
79
- @return: str
80
- """
81
  return self._translate_file(path, **kwargs)
82
 
83
  def translate_batch(self, batch=None, **kwargs):
 
1
  """
2
  mymemory translator API
3
  """
4
+ from deep_translator.validate import is_empty, validate_input
5
+ from deep_translator.constants import BASE_URLS
6
+ from deep_translator.exceptions import (
7
+ TranslationNotFound,
8
+ RequestError,
9
+ TooManyRequests,
10
+ )
11
+ from deep_translator.base import BaseTranslator
12
  import requests
13
 
14
 
 
16
  """
17
  class that uses the mymemory translator to translate texts
18
  """
19
+
20
  def __init__(self, source="auto", target="en", proxies=None, **kwargs):
21
  """
22
  @param source: source language to translate from
23
  @param target: target language to translate to
24
  """
25
  self.proxies = proxies
26
+ self.email = kwargs.get("email", None)
27
+ super().__init__(
28
+ base_url=BASE_URLS.get("MYMEMORY"),
29
+ source=source,
30
+ target=target,
31
+ payload_key="q",
32
+ )
33
 
34
  def translate(self, text, return_all=False, **kwargs):
35
  """
 
44
  if self._same_source_target() or is_empty(text):
45
  return text
46
 
47
+ self._url_params["langpair"] = f"{self._source}|{self._target}"
48
  if self.payload_key:
49
  self._url_params[self.payload_key] = text
50
  if self.email:
51
+ self._url_params["de"] = self.email
52
 
53
+ response = requests.get(
54
+ self._base_url, params=self._url_params, proxies=self.proxies
55
+ )
56
 
57
  if response.status_code == 429:
58
  raise TooManyRequests()
 
63
  if not data:
64
  TranslationNotFound(text)
65
 
66
+ translation = data.get("responseData").get("translatedText")
67
  if translation:
68
  return translation
69
 
70
  elif not translation:
71
+ all_matches = data.get("matches")
72
+ matches = (match["translation"] for match in all_matches)
73
  next_match = next(matches)
74
  return next_match if not return_all else list(all_matches)
75
 
76
  def translate_file(self, path, **kwargs):
77
  """
78
+ translate directly from file
79
+ @param path: path to the target file
80
+ @type path: str
81
+ @param kwargs: additional args
82
+ @return: str
83
+ """
84
  return self._translate_file(path, **kwargs)
85
 
86
  def translate_batch(self, batch=None, **kwargs):
deep_translator/papago.py CHANGED
@@ -2,12 +2,12 @@
2
  google translator API
3
  """
4
  import json
5
- from .constants import BASE_URLS, PAPAGO_LANGUAGE_TO_CODE
6
- from .exceptions import TranslationNotFound
7
- from .base import BaseTranslator
8
  import requests
9
 
10
- from .validate import validate_input
11
 
12
 
13
  class PapagoTranslator(BaseTranslator):
@@ -15,14 +15,17 @@ class PapagoTranslator(BaseTranslator):
15
  class that wraps functions, which use google translate under the hood to translate text(s)
16
  """
17
 
18
- def __init__(self, client_id=None, secret_key=None, source="auto", target="en", **kwargs):
 
 
19
  """
20
  @param source: source language to translate from
21
  @param target: target language to translate to
22
  """
23
  if not client_id or not secret_key:
24
  raise Exception(
25
- "Please pass your client id and secret key! visit the papago website for more infos")
 
26
 
27
  self.client_id = client_id
28
  self.secret_key = secret_key
@@ -31,7 +34,7 @@ class PapagoTranslator(BaseTranslator):
31
  source=source,
32
  target=target,
33
  languages=PAPAGO_LANGUAGE_TO_CODE,
34
- **kwargs
35
  )
36
 
37
  def translate(self, text, **kwargs):
@@ -41,21 +44,17 @@ class PapagoTranslator(BaseTranslator):
41
  @return: str: translated text
42
  """
43
  if validate_input(text):
44
- payload = {
45
- "source": self._source,
46
- "target": self._target,
47
- "text": text
48
- }
49
  headers = {
50
- 'X-Naver-Client-Id': self.client_id,
51
- 'X-Naver-Client-Secret': self.secret_key,
52
- 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
53
  }
54
- response = requests.post(
55
- self._base_url, headers=headers, data=payload)
56
  if response.status_code != 200:
57
  raise Exception(
58
- f'Translation error! -> status code: {response.status_code}')
 
59
  res_body = json.loads(response.text)
60
  if "message" not in res_body:
61
  raise TranslationNotFound(text)
 
2
  google translator API
3
  """
4
  import json
5
+ from deep_translator.constants import BASE_URLS, PAPAGO_LANGUAGE_TO_CODE
6
+ from deep_translator.exceptions import TranslationNotFound
7
+ from deep_translator.base import BaseTranslator
8
  import requests
9
 
10
+ from deep_translator.validate import validate_input
11
 
12
 
13
  class PapagoTranslator(BaseTranslator):
 
15
  class that wraps functions, which use google translate under the hood to translate text(s)
16
  """
17
 
18
+ def __init__(
19
+ self, client_id=None, secret_key=None, source="auto", target="en", **kwargs
20
+ ):
21
  """
22
  @param source: source language to translate from
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
 
30
  self.client_id = client_id
31
  self.secret_key = secret_key
 
34
  source=source,
35
  target=target,
36
  languages=PAPAGO_LANGUAGE_TO_CODE,
37
+ **kwargs,
38
  )
39
 
40
  def translate(self, text, **kwargs):
 
44
  @return: str: translated text
45
  """
46
  if validate_input(text):
47
+ payload = {"source": self._source, "target": self._target, "text": text}
 
 
 
 
48
  headers = {
49
+ "X-Naver-Client-Id": self.client_id,
50
+ "X-Naver-Client-Secret": self.secret_key,
51
+ "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
52
  }
53
+ response = requests.post(self._base_url, headers=headers, data=payload)
 
54
  if response.status_code != 200:
55
  raise Exception(
56
+ f"Translation error! -> status code: {response.status_code}"
57
+ )
58
  res_body = json.loads(response.text)
59
  if "message" not in res_body:
60
  raise TranslationNotFound(text)
deep_translator/pons.py CHANGED
@@ -4,15 +4,16 @@ pons translator API
4
  from bs4 import BeautifulSoup
5
  import requests
6
 
7
- from .validate import validate_input, is_empty
8
- from .constants import BASE_URLS, PONS_CODES_TO_LANGUAGES
9
- from .exceptions import (
10
- TranslationNotFound,
11
- NotValidPayload,
12
- ElementNotFoundInGetRequest,
13
- RequestError,
14
- TooManyRequests)
15
- from .base import BaseTranslator
 
16
  from requests.utils import requote_uri
17
 
18
 
@@ -27,15 +28,16 @@ class PonsTranslator(BaseTranslator):
27
  @param target: target language to translate to
28
  """
29
  self.proxies = proxies
30
- super().__init__(base_url=BASE_URLS.get("PONS"),
31
- languages=PONS_CODES_TO_LANGUAGES,
32
- source=source,
33
- target=target,
34
- payload_key=None,
35
- element_tag='div',
36
- element_query={"class": "target"},
37
- **kwargs
38
- )
 
39
 
40
  def translate(self, word, return_all=False, **kwargs):
41
  """
@@ -49,7 +51,7 @@ class PonsTranslator(BaseTranslator):
49
  if validate_input(word, max_chars=50):
50
  if self._same_source_target() or is_empty(word):
51
  return word
52
- url = "{}{}-{}/{}".format(self._base_url, self._source, self._target, word)
53
  url = requote_uri(url)
54
  response = requests.get(url, proxies=self.proxies)
55
 
@@ -59,7 +61,7 @@ class PonsTranslator(BaseTranslator):
59
  if response.status_code != 200:
60
  raise RequestError()
61
 
62
- soup = BeautifulSoup(response.text, 'html.parser')
63
  elements = soup.findAll(self._element_tag, self._element_query)
64
 
65
  if not elements:
@@ -67,9 +69,9 @@ class PonsTranslator(BaseTranslator):
67
 
68
  filtered_elements = []
69
  for el in elements:
70
- temp = ''
71
- for e in el.findAll('a'):
72
- temp += e.get_text() + ' '
73
  filtered_elements.append(temp)
74
 
75
  if not filtered_elements:
@@ -96,4 +98,3 @@ class PonsTranslator(BaseTranslator):
96
  for word in words:
97
  translated_words.append(self.translate(word=word, **kwargs))
98
  return translated_words
99
-
 
4
  from bs4 import BeautifulSoup
5
  import requests
6
 
7
+ from deep_translator.validate import validate_input, is_empty
8
+ from deep_translator.constants import BASE_URLS, PONS_CODES_TO_LANGUAGES
9
+ from deep_translator.exceptions import (
10
+ TranslationNotFound,
11
+ NotValidPayload,
12
+ ElementNotFoundInGetRequest,
13
+ RequestError,
14
+ TooManyRequests,
15
+ )
16
+ from deep_translator.base import BaseTranslator
17
  from requests.utils import requote_uri
18
 
19
 
 
28
  @param target: target language to translate to
29
  """
30
  self.proxies = proxies
31
+ super().__init__(
32
+ base_url=BASE_URLS.get("PONS"),
33
+ languages=PONS_CODES_TO_LANGUAGES,
34
+ source=source,
35
+ target=target,
36
+ payload_key=None,
37
+ element_tag="div",
38
+ element_query={"class": "target"},
39
+ **kwargs,
40
+ )
41
 
42
  def translate(self, word, return_all=False, **kwargs):
43
  """
 
51
  if validate_input(word, max_chars=50):
52
  if self._same_source_target() or is_empty(word):
53
  return word
54
+ url = f"{self._base_url}{self._source}-{self._target}/{word}"
55
  url = requote_uri(url)
56
  response = requests.get(url, proxies=self.proxies)
57
 
 
61
  if response.status_code != 200:
62
  raise RequestError()
63
 
64
+ soup = BeautifulSoup(response.text, "html.parser")
65
  elements = soup.findAll(self._element_tag, self._element_query)
66
 
67
  if not elements:
 
69
 
70
  filtered_elements = []
71
  for el in elements:
72
+ temp = ""
73
+ for e in el.findAll("a"):
74
+ temp += e.get_text() + " "
75
  filtered_elements.append(temp)
76
 
77
  if not filtered_elements:
 
98
  for word in words:
99
  translated_words.append(self.translate(word=word, **kwargs))
100
  return translated_words
 
deep_translator/qcri.py CHANGED
@@ -1,8 +1,7 @@
1
-
2
  import requests
3
- from .constants import BASE_URLS, QCRI_LANGUAGE_TO_CODE
4
- from .exceptions import (ServerException, TranslationNotFound)
5
- from .base import BaseTranslator
6
 
7
 
8
  class QcriTranslator(BaseTranslator):
@@ -24,23 +23,23 @@ class QcriTranslator(BaseTranslator):
24
  "translate": "translate",
25
  }
26
 
27
- self.params = {
28
- "key": self.api_key
29
- }
30
  super().__init__(
31
  base_url=BASE_URLS.get("QcriTranslator"),
32
  source=source,
33
  target=target,
34
  languages=QCRI_LANGUAGE_TO_CODE,
35
- **kwargs
36
  )
37
 
38
  def _get(self, endpoint, params=None, return_text=True):
39
  if not params:
40
  params = self.params
41
  try:
42
- res = requests.get(self._base_url.format(
43
- endpoint=self.api_endpoints[endpoint]), params=params)
 
 
44
  return res.text if return_text else res
45
  except Exception as e:
46
  raise e
@@ -60,9 +59,9 @@ class QcriTranslator(BaseTranslator):
60
  def translate(self, text, **kwargs):
61
  params = {
62
  "key": self.api_key,
63
- "langpair": "{}-{}".format(self._source, self._target),
64
  "domain": kwargs["domain"],
65
- "text": text
66
  }
67
  try:
68
  response = self._get("translate", params=params, return_text=False)
 
 
1
  import requests
2
+ from deep_translator.constants import BASE_URLS, QCRI_LANGUAGE_TO_CODE
3
+ from deep_translator.exceptions import ServerException, TranslationNotFound
4
+ from deep_translator.base import BaseTranslator
5
 
6
 
7
  class QcriTranslator(BaseTranslator):
 
23
  "translate": "translate",
24
  }
25
 
26
+ self.params = {"key": self.api_key}
 
 
27
  super().__init__(
28
  base_url=BASE_URLS.get("QcriTranslator"),
29
  source=source,
30
  target=target,
31
  languages=QCRI_LANGUAGE_TO_CODE,
32
+ **kwargs,
33
  )
34
 
35
  def _get(self, endpoint, params=None, return_text=True):
36
  if not params:
37
  params = self.params
38
  try:
39
+ res = requests.get(
40
+ self._base_url.format(endpoint=self.api_endpoints[endpoint]),
41
+ params=params,
42
+ )
43
  return res.text if return_text else res
44
  except Exception as e:
45
  raise e
 
59
  def translate(self, text, **kwargs):
60
  params = {
61
  "key": self.api_key,
62
+ "langpair": f"{self._source}-{self._target}",
63
  "domain": kwargs["domain"],
64
+ "text": text,
65
  }
66
  try:
67
  response = self._get("translate", params=params, return_text=False)
deep_translator/validate.py CHANGED
@@ -1,6 +1,4 @@
1
-
2
- from .exceptions import NotValidPayload, NotValidLength
3
- import string
4
 
5
 
6
  def is_empty(text: str):
 
1
+ from deep_translator.exceptions import NotValidPayload, NotValidLength
 
 
2
 
3
 
4
  def is_empty(text: str):
deep_translator/yandex.py CHANGED
@@ -2,10 +2,15 @@
2
  Yandex translator API
3
  """
4
  import requests
5
- from .constants import BASE_URLS
6
- from .exceptions import (RequestError, ServerException,
7
- TranslationNotFound, TooManyRequests)
8
- from .base import BaseTranslator
 
 
 
 
 
9
 
10
 
11
  class YandexTranslator(BaseTranslator):
@@ -27,10 +32,7 @@ class YandexTranslator(BaseTranslator):
27
  "translate": "translate",
28
  }
29
  super().__init__(
30
- base_url=BASE_URLS.get("YANDEX"),
31
- source=source,
32
- target=target,
33
- **kwargs
34
  )
35
 
36
  def _get_supported_languages(self):
@@ -44,11 +46,9 @@ class YandexTranslator(BaseTranslator):
44
  def dirs(self, proxies=None):
45
 
46
  try:
47
- url = self._base_url.format(
48
- version=self.api_version, endpoint="getLangs")
49
  print("url: ", url)
50
- response = requests.get(
51
- url, params={"key": self.api_key}, proxies=proxies)
52
  except requests.exceptions.ConnectionError:
53
  raise ServerException(503)
54
  else:
@@ -66,8 +66,7 @@ class YandexTranslator(BaseTranslator):
66
  "key": self.api_key,
67
  }
68
  try:
69
- url = self._base_url.format(
70
- version=self.api_version, endpoint="detect")
71
  response = requests.post(url, data=params, proxies=proxies)
72
 
73
  except RequestError:
@@ -78,8 +77,8 @@ class YandexTranslator(BaseTranslator):
78
  raise ServerException(response.status_code)
79
  else:
80
  response = response.json()
81
- language = response['lang']
82
- status_code = response['code']
83
  if status_code != 200:
84
  raise RequestError()
85
  elif not language:
@@ -91,28 +90,31 @@ class YandexTranslator(BaseTranslator):
91
  params = {
92
  "text": text,
93
  "format": "plain",
94
- "lang": self._target if self._source == "auto" else "{}-{}".format(self._source, self._target),
95
- "key": self.api_key
 
 
96
  }
97
  try:
98
  url = self._base_url.format(
99
- version=self.api_version, endpoint="translate")
 
100
  response = requests.post(url, data=params, proxies=proxies)
101
  except ConnectionError:
102
  raise ServerException(503)
103
  else:
104
  response = response.json()
105
 
106
- if response['code'] == 429:
107
  raise TooManyRequests()
108
 
109
- if response['code'] != 200:
110
- raise ServerException(response['code'])
111
 
112
- if not response['text']:
113
  raise TranslationNotFound()
114
 
115
- return response['text']
116
 
117
  def translate_file(self, path, **kwargs):
118
  """
@@ -129,4 +131,3 @@ class YandexTranslator(BaseTranslator):
129
  @return: list of translations
130
  """
131
  return self._translate_batch(batch, **kwargs)
132
-
 
2
  Yandex translator API
3
  """
4
  import requests
5
+ from deep_translator.constants import BASE_URLS
6
+ from deep_translator.exceptions import (
7
+ RequestError,
8
+ ServerException,
9
+ TranslationNotFound,
10
+ TooManyRequests,
11
+ )
12
+ from deep_translator.base import BaseTranslator
13
+ from deep_translator.validate import validate_input
14
 
15
 
16
  class YandexTranslator(BaseTranslator):
 
32
  "translate": "translate",
33
  }
34
  super().__init__(
35
+ base_url=BASE_URLS.get("YANDEX"), source=source, target=target, **kwargs
 
 
 
36
  )
37
 
38
  def _get_supported_languages(self):
 
46
  def dirs(self, proxies=None):
47
 
48
  try:
49
+ url = self._base_url.format(version=self.api_version, endpoint="getLangs")
 
50
  print("url: ", url)
51
+ response = requests.get(url, params={"key": self.api_key}, proxies=proxies)
 
52
  except requests.exceptions.ConnectionError:
53
  raise ServerException(503)
54
  else:
 
66
  "key": self.api_key,
67
  }
68
  try:
69
+ url = self._base_url.format(version=self.api_version, endpoint="detect")
 
70
  response = requests.post(url, data=params, proxies=proxies)
71
 
72
  except RequestError:
 
77
  raise ServerException(response.status_code)
78
  else:
79
  response = response.json()
80
+ language = response["lang"]
81
+ status_code = response["code"]
82
  if status_code != 200:
83
  raise RequestError()
84
  elif not language:
 
90
  params = {
91
  "text": text,
92
  "format": "plain",
93
+ "lang": self._target
94
+ if self._source == "auto"
95
+ else "{}-{}".format(self._source, self._target),
96
+ "key": self.api_key,
97
  }
98
  try:
99
  url = self._base_url.format(
100
+ version=self.api_version, endpoint="translate"
101
+ )
102
  response = requests.post(url, data=params, proxies=proxies)
103
  except ConnectionError:
104
  raise ServerException(503)
105
  else:
106
  response = response.json()
107
 
108
+ if response["code"] == 429:
109
  raise TooManyRequests()
110
 
111
+ if response["code"] != 200:
112
+ raise ServerException(response["code"])
113
 
114
+ if not response["text"]:
115
  raise TranslationNotFound()
116
 
117
+ return response["text"]
118
 
119
  def translate_file(self, path, **kwargs):
120
  """
 
131
  @return: list of translations
132
  """
133
  return self._translate_batch(batch, **kwargs)
 
poetry.lock CHANGED
@@ -54,6 +54,29 @@ soupsieve = ">1.2"
54
  html5lib = ["html5lib"]
55
  lxml = ["lxml"]
56
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
  [[package]]
58
  name = "bleach"
59
  version = "4.1.0"
@@ -97,6 +120,18 @@ python-versions = ">=3.5.0"
97
  [package.extras]
98
  unicode_backport = ["unicodedata2"]
99
 
 
 
 
 
 
 
 
 
 
 
 
 
100
  [[package]]
101
  name = "colorama"
102
  version = "0.4.4"
@@ -236,6 +271,14 @@ category = "dev"
236
  optional = false
237
  python-versions = ">=3.6"
238
 
 
 
 
 
 
 
 
 
239
  [[package]]
240
  name = "packaging"
241
  version = "21.3"
@@ -247,6 +290,14 @@ python-versions = ">=3.6"
247
  [package.dependencies]
248
  pyparsing = ">=2.0.2,<3.0.5 || >3.0.5"
249
 
 
 
 
 
 
 
 
 
250
  [[package]]
251
  name = "pkginfo"
252
  version = "1.8.2"
@@ -258,6 +309,18 @@ python-versions = "*"
258
  [package.extras]
259
  testing = ["coverage", "nose"]
260
 
 
 
 
 
 
 
 
 
 
 
 
 
261
  [[package]]
262
  name = "pluggy"
263
  version = "1.0.0"
@@ -561,6 +624,14 @@ category = "dev"
561
  optional = false
562
  python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
563
 
 
 
 
 
 
 
 
 
564
  [[package]]
565
  name = "tqdm"
566
  version = "4.62.3"
@@ -597,6 +668,14 @@ rfc3986 = ">=1.4.0"
597
  tqdm = ">=4.14"
598
  urllib3 = ">=1.26.0"
599
 
 
 
 
 
 
 
 
 
600
  [[package]]
601
  name = "typing-extensions"
602
  version = "4.0.1"
@@ -641,7 +720,7 @@ testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-
641
  [metadata]
642
  lock-version = "1.1"
643
  python-versions = "^3.7"
644
- content-hash = "2877a59ad1ac817881dcea5583bd7f07310ab5da4301dda5dadbe598b9ec6511"
645
 
646
  [metadata.files]
647
  alabaster = [
@@ -664,6 +743,31 @@ beautifulsoup4 = [
664
  {file = "beautifulsoup4-4.10.0-py3-none-any.whl", hash = "sha256:9a315ce70049920ea4572a4055bc4bd700c940521d36fc858205ad4fcde149bf"},
665
  {file = "beautifulsoup4-4.10.0.tar.gz", hash = "sha256:c23ad23c521d818955a4151a67d81580319d4bf548d3d49f4223ae041ff98891"},
666
  ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
667
  bleach = [
668
  {file = "bleach-4.1.0-py2.py3-none-any.whl", hash = "sha256:4d2651ab93271d1129ac9cbc679f524565cc8a1b791909c4a51eac4446a15994"},
669
  {file = "bleach-4.1.0.tar.gz", hash = "sha256:0900d8b37eba61a802ee40ac0061f8c2b5dee29c1927dd1d233e075ebf5a71da"},
@@ -728,6 +832,10 @@ charset-normalizer = [
728
  {file = "charset-normalizer-2.0.11.tar.gz", hash = "sha256:98398a9d69ee80548c762ba991a4728bfc3836768ed226b3945908d1a688371c"},
729
  {file = "charset_normalizer-2.0.11-py3-none-any.whl", hash = "sha256:2842d8f5e82a1f6aa437380934d5e1cd4fcf2003b06fed6940769c164a480a45"},
730
  ]
 
 
 
 
731
  colorama = [
732
  {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"},
733
  {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"},
@@ -876,14 +984,26 @@ markupsafe = [
876
  {file = "MarkupSafe-2.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8"},
877
  {file = "MarkupSafe-2.0.1.tar.gz", hash = "sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a"},
878
  ]
 
 
 
 
879
  packaging = [
880
  {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"},
881
  {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"},
882
  ]
 
 
 
 
883
  pkginfo = [
884
  {file = "pkginfo-1.8.2-py2.py3-none-any.whl", hash = "sha256:c24c487c6a7f72c66e816ab1796b96ac6c3d14d49338293d2141664330b55ffc"},
885
  {file = "pkginfo-1.8.2.tar.gz", hash = "sha256:542e0d0b6750e2e21c20179803e40ab50598d8066d51097a0e382cba9eb02bff"},
886
  ]
 
 
 
 
887
  pluggy = [
888
  {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"},
889
  {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"},
@@ -984,6 +1104,10 @@ toml = [
984
  {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"},
985
  {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"},
986
  ]
 
 
 
 
987
  tqdm = [
988
  {file = "tqdm-4.62.3-py2.py3-none-any.whl", hash = "sha256:8dd278a422499cd6b727e6ae4061c40b48fce8b76d1ccbf5d34fca9b7f925b0c"},
989
  {file = "tqdm-4.62.3.tar.gz", hash = "sha256:d359de7217506c9851b7869f3708d8ee53ed70a1b8edbba4dbcb47442592920d"},
@@ -992,6 +1116,32 @@ twine = [
992
  {file = "twine-3.8.0-py3-none-any.whl", hash = "sha256:d0550fca9dc19f3d5e8eadfce0c227294df0a2a951251a4385797c8a6198b7c8"},
993
  {file = "twine-3.8.0.tar.gz", hash = "sha256:8efa52658e0ae770686a13b675569328f1fba9837e5de1867bfe5f46a9aefe19"},
994
  ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
995
  typing-extensions = [
996
  {file = "typing_extensions-4.0.1-py3-none-any.whl", hash = "sha256:7f001e5ac290a0c0401508864c7ec868be4e701886d5b573a9528ed3973d9d3b"},
997
  {file = "typing_extensions-4.0.1.tar.gz", hash = "sha256:4ca091dea149f945ec56afb48dae714f21e8692ef22a395223bcd328961b6a0e"},
 
54
  html5lib = ["html5lib"]
55
  lxml = ["lxml"]
56
 
57
+ [[package]]
58
+ name = "black"
59
+ version = "22.1.0"
60
+ description = "The uncompromising code formatter."
61
+ category = "dev"
62
+ optional = false
63
+ python-versions = ">=3.6.2"
64
+
65
+ [package.dependencies]
66
+ click = ">=8.0.0"
67
+ mypy-extensions = ">=0.4.3"
68
+ pathspec = ">=0.9.0"
69
+ platformdirs = ">=2"
70
+ tomli = ">=1.1.0"
71
+ typed-ast = {version = ">=1.4.2", markers = "python_version < \"3.8\" and implementation_name == \"cpython\""}
72
+ typing-extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""}
73
+
74
+ [package.extras]
75
+ colorama = ["colorama (>=0.4.3)"]
76
+ d = ["aiohttp (>=3.7.4)"]
77
+ jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"]
78
+ uvloop = ["uvloop (>=0.15.2)"]
79
+
80
  [[package]]
81
  name = "bleach"
82
  version = "4.1.0"
 
120
  [package.extras]
121
  unicode_backport = ["unicodedata2"]
122
 
123
+ [[package]]
124
+ name = "click"
125
+ version = "8.0.4"
126
+ description = "Composable command line interface toolkit"
127
+ category = "dev"
128
+ optional = false
129
+ python-versions = ">=3.6"
130
+
131
+ [package.dependencies]
132
+ colorama = {version = "*", markers = "platform_system == \"Windows\""}
133
+ importlib-metadata = {version = "*", markers = "python_version < \"3.8\""}
134
+
135
  [[package]]
136
  name = "colorama"
137
  version = "0.4.4"
 
271
  optional = false
272
  python-versions = ">=3.6"
273
 
274
+ [[package]]
275
+ name = "mypy-extensions"
276
+ version = "0.4.3"
277
+ description = "Experimental type system extensions for programs checked with the mypy typechecker."
278
+ category = "dev"
279
+ optional = false
280
+ python-versions = "*"
281
+
282
  [[package]]
283
  name = "packaging"
284
  version = "21.3"
 
290
  [package.dependencies]
291
  pyparsing = ">=2.0.2,<3.0.5 || >3.0.5"
292
 
293
+ [[package]]
294
+ name = "pathspec"
295
+ version = "0.9.0"
296
+ description = "Utility library for gitignore style pattern matching of file paths."
297
+ category = "dev"
298
+ optional = false
299
+ python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
300
+
301
  [[package]]
302
  name = "pkginfo"
303
  version = "1.8.2"
 
309
  [package.extras]
310
  testing = ["coverage", "nose"]
311
 
312
+ [[package]]
313
+ name = "platformdirs"
314
+ version = "2.5.1"
315
+ description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
316
+ category = "dev"
317
+ optional = false
318
+ python-versions = ">=3.7"
319
+
320
+ [package.extras]
321
+ docs = ["Sphinx (>=4)", "furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx-autodoc-typehints (>=1.12)"]
322
+ test = ["appdirs (==1.4.4)", "pytest (>=6)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)"]
323
+
324
  [[package]]
325
  name = "pluggy"
326
  version = "1.0.0"
 
624
  optional = false
625
  python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
626
 
627
+ [[package]]
628
+ name = "tomli"
629
+ version = "2.0.1"
630
+ description = "A lil' TOML parser"
631
+ category = "dev"
632
+ optional = false
633
+ python-versions = ">=3.7"
634
+
635
  [[package]]
636
  name = "tqdm"
637
  version = "4.62.3"
 
668
  tqdm = ">=4.14"
669
  urllib3 = ">=1.26.0"
670
 
671
+ [[package]]
672
+ name = "typed-ast"
673
+ version = "1.5.2"
674
+ description = "a fork of Python 2 and 3 ast modules with type comment support"
675
+ category = "dev"
676
+ optional = false
677
+ python-versions = ">=3.6"
678
+
679
  [[package]]
680
  name = "typing-extensions"
681
  version = "4.0.1"
 
720
  [metadata]
721
  lock-version = "1.1"
722
  python-versions = "^3.7"
723
+ content-hash = "465ff9b79ec7a4f8f67638bed33190079fbe1dcca8261d36813c7787e30624f2"
724
 
725
  [metadata.files]
726
  alabaster = [
 
743
  {file = "beautifulsoup4-4.10.0-py3-none-any.whl", hash = "sha256:9a315ce70049920ea4572a4055bc4bd700c940521d36fc858205ad4fcde149bf"},
744
  {file = "beautifulsoup4-4.10.0.tar.gz", hash = "sha256:c23ad23c521d818955a4151a67d81580319d4bf548d3d49f4223ae041ff98891"},
745
  ]
746
+ black = [
747
+ {file = "black-22.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1297c63b9e1b96a3d0da2d85d11cd9bf8664251fd69ddac068b98dc4f34f73b6"},
748
+ {file = "black-22.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2ff96450d3ad9ea499fc4c60e425a1439c2120cbbc1ab959ff20f7c76ec7e866"},
749
+ {file = "black-22.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0e21e1f1efa65a50e3960edd068b6ae6d64ad6235bd8bfea116a03b21836af71"},
750
+ {file = "black-22.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2f69158a7d120fd641d1fa9a921d898e20d52e44a74a6fbbcc570a62a6bc8ab"},
751
+ {file = "black-22.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:228b5ae2c8e3d6227e4bde5920d2fc66cc3400fde7bcc74f480cb07ef0b570d5"},
752
+ {file = "black-22.1.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b1a5ed73ab4c482208d20434f700d514f66ffe2840f63a6252ecc43a9bc77e8a"},
753
+ {file = "black-22.1.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:35944b7100af4a985abfcaa860b06af15590deb1f392f06c8683b4381e8eeaf0"},
754
+ {file = "black-22.1.0-cp36-cp36m-win_amd64.whl", hash = "sha256:7835fee5238fc0a0baf6c9268fb816b5f5cd9b8793423a75e8cd663c48d073ba"},
755
+ {file = "black-22.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dae63f2dbf82882fa3b2a3c49c32bffe144970a573cd68d247af6560fc493ae1"},
756
+ {file = "black-22.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fa1db02410b1924b6749c245ab38d30621564e658297484952f3d8a39fce7e8"},
757
+ {file = "black-22.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:c8226f50b8c34a14608b848dc23a46e5d08397d009446353dad45e04af0c8e28"},
758
+ {file = "black-22.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:2d6f331c02f0f40aa51a22e479c8209d37fcd520c77721c034517d44eecf5912"},
759
+ {file = "black-22.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:742ce9af3086e5bd07e58c8feb09dbb2b047b7f566eb5f5bc63fd455814979f3"},
760
+ {file = "black-22.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:fdb8754b453fb15fad3f72cd9cad3e16776f0964d67cf30ebcbf10327a3777a3"},
761
+ {file = "black-22.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5660feab44c2e3cb24b2419b998846cbb01c23c7fe645fee45087efa3da2d61"},
762
+ {file = "black-22.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:6f2f01381f91c1efb1451998bd65a129b3ed6f64f79663a55fe0e9b74a5f81fd"},
763
+ {file = "black-22.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:efbadd9b52c060a8fc3b9658744091cb33c31f830b3f074422ed27bad2b18e8f"},
764
+ {file = "black-22.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8871fcb4b447206904932b54b567923e5be802b9b19b744fdff092bd2f3118d0"},
765
+ {file = "black-22.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ccad888050f5393f0d6029deea2a33e5ae371fd182a697313bdbd835d3edaf9c"},
766
+ {file = "black-22.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:07e5c049442d7ca1a2fc273c79d1aecbbf1bc858f62e8184abe1ad175c4f7cc2"},
767
+ {file = "black-22.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:373922fc66676133ddc3e754e4509196a8c392fec3f5ca4486673e685a421321"},
768
+ {file = "black-22.1.0-py3-none-any.whl", hash = "sha256:3524739d76b6b3ed1132422bf9d82123cd1705086723bc3e235ca39fd21c667d"},
769
+ {file = "black-22.1.0.tar.gz", hash = "sha256:a7c0192d35635f6fc1174be575cb7915e92e5dd629ee79fdaf0dcfa41a80afb5"},
770
+ ]
771
  bleach = [
772
  {file = "bleach-4.1.0-py2.py3-none-any.whl", hash = "sha256:4d2651ab93271d1129ac9cbc679f524565cc8a1b791909c4a51eac4446a15994"},
773
  {file = "bleach-4.1.0.tar.gz", hash = "sha256:0900d8b37eba61a802ee40ac0061f8c2b5dee29c1927dd1d233e075ebf5a71da"},
 
832
  {file = "charset-normalizer-2.0.11.tar.gz", hash = "sha256:98398a9d69ee80548c762ba991a4728bfc3836768ed226b3945908d1a688371c"},
833
  {file = "charset_normalizer-2.0.11-py3-none-any.whl", hash = "sha256:2842d8f5e82a1f6aa437380934d5e1cd4fcf2003b06fed6940769c164a480a45"},
834
  ]
835
+ click = [
836
+ {file = "click-8.0.4-py3-none-any.whl", hash = "sha256:6a7a62563bbfabfda3a38f3023a1db4a35978c0abd76f6c9605ecd6554d6d9b1"},
837
+ {file = "click-8.0.4.tar.gz", hash = "sha256:8458d7b1287c5fb128c90e23381cf99dcde74beaf6c7ff6384ce84d6fe090adb"},
838
+ ]
839
  colorama = [
840
  {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"},
841
  {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"},
 
984
  {file = "MarkupSafe-2.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8"},
985
  {file = "MarkupSafe-2.0.1.tar.gz", hash = "sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a"},
986
  ]
987
+ mypy-extensions = [
988
+ {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"},
989
+ {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"},
990
+ ]
991
  packaging = [
992
  {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"},
993
  {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"},
994
  ]
995
+ pathspec = [
996
+ {file = "pathspec-0.9.0-py2.py3-none-any.whl", hash = "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a"},
997
+ {file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"},
998
+ ]
999
  pkginfo = [
1000
  {file = "pkginfo-1.8.2-py2.py3-none-any.whl", hash = "sha256:c24c487c6a7f72c66e816ab1796b96ac6c3d14d49338293d2141664330b55ffc"},
1001
  {file = "pkginfo-1.8.2.tar.gz", hash = "sha256:542e0d0b6750e2e21c20179803e40ab50598d8066d51097a0e382cba9eb02bff"},
1002
  ]
1003
+ platformdirs = [
1004
+ {file = "platformdirs-2.5.1-py3-none-any.whl", hash = "sha256:bcae7cab893c2d310a711b70b24efb93334febe65f8de776ee320b517471e227"},
1005
+ {file = "platformdirs-2.5.1.tar.gz", hash = "sha256:7535e70dfa32e84d4b34996ea99c5e432fa29a708d0f4e394bbcb2a8faa4f16d"},
1006
+ ]
1007
  pluggy = [
1008
  {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"},
1009
  {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"},
 
1104
  {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"},
1105
  {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"},
1106
  ]
1107
+ tomli = [
1108
+ {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
1109
+ {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
1110
+ ]
1111
  tqdm = [
1112
  {file = "tqdm-4.62.3-py2.py3-none-any.whl", hash = "sha256:8dd278a422499cd6b727e6ae4061c40b48fce8b76d1ccbf5d34fca9b7f925b0c"},
1113
  {file = "tqdm-4.62.3.tar.gz", hash = "sha256:d359de7217506c9851b7869f3708d8ee53ed70a1b8edbba4dbcb47442592920d"},
 
1116
  {file = "twine-3.8.0-py3-none-any.whl", hash = "sha256:d0550fca9dc19f3d5e8eadfce0c227294df0a2a951251a4385797c8a6198b7c8"},
1117
  {file = "twine-3.8.0.tar.gz", hash = "sha256:8efa52658e0ae770686a13b675569328f1fba9837e5de1867bfe5f46a9aefe19"},
1118
  ]
1119
+ typed-ast = [
1120
+ {file = "typed_ast-1.5.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:183b183b7771a508395d2cbffd6db67d6ad52958a5fdc99f450d954003900266"},
1121
+ {file = "typed_ast-1.5.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:676d051b1da67a852c0447621fdd11c4e104827417bf216092ec3e286f7da596"},
1122
+ {file = "typed_ast-1.5.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc2542e83ac8399752bc16e0b35e038bdb659ba237f4222616b4e83fb9654985"},
1123
+ {file = "typed_ast-1.5.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:74cac86cc586db8dfda0ce65d8bcd2bf17b58668dfcc3652762f3ef0e6677e76"},
1124
+ {file = "typed_ast-1.5.2-cp310-cp310-win_amd64.whl", hash = "sha256:18fe320f354d6f9ad3147859b6e16649a0781425268c4dde596093177660e71a"},
1125
+ {file = "typed_ast-1.5.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:31d8c6b2df19a777bc8826770b872a45a1f30cfefcfd729491baa5237faae837"},
1126
+ {file = "typed_ast-1.5.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:963a0ccc9a4188524e6e6d39b12c9ca24cc2d45a71cfdd04a26d883c922b4b78"},
1127
+ {file = "typed_ast-1.5.2-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0eb77764ea470f14fcbb89d51bc6bbf5e7623446ac4ed06cbd9ca9495b62e36e"},
1128
+ {file = "typed_ast-1.5.2-cp36-cp36m-win_amd64.whl", hash = "sha256:294a6903a4d087db805a7656989f613371915fc45c8cc0ddc5c5a0a8ad9bea4d"},
1129
+ {file = "typed_ast-1.5.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:26a432dc219c6b6f38be20a958cbe1abffcc5492821d7e27f08606ef99e0dffd"},
1130
+ {file = "typed_ast-1.5.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7407cfcad702f0b6c0e0f3e7ab876cd1d2c13b14ce770e412c0c4b9728a0f88"},
1131
+ {file = "typed_ast-1.5.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f30ddd110634c2d7534b2d4e0e22967e88366b0d356b24de87419cc4410c41b7"},
1132
+ {file = "typed_ast-1.5.2-cp37-cp37m-win_amd64.whl", hash = "sha256:8c08d6625bb258179b6e512f55ad20f9dfef019bbfbe3095247401e053a3ea30"},
1133
+ {file = "typed_ast-1.5.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:90904d889ab8e81a956f2c0935a523cc4e077c7847a836abee832f868d5c26a4"},
1134
+ {file = "typed_ast-1.5.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:bbebc31bf11762b63bf61aaae232becb41c5bf6b3461b80a4df7e791fabb3aca"},
1135
+ {file = "typed_ast-1.5.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c29dd9a3a9d259c9fa19d19738d021632d673f6ed9b35a739f48e5f807f264fb"},
1136
+ {file = "typed_ast-1.5.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:58ae097a325e9bb7a684572d20eb3e1809802c5c9ec7108e85da1eb6c1a3331b"},
1137
+ {file = "typed_ast-1.5.2-cp38-cp38-win_amd64.whl", hash = "sha256:da0a98d458010bf4fe535f2d1e367a2e2060e105978873c04c04212fb20543f7"},
1138
+ {file = "typed_ast-1.5.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:33b4a19ddc9fc551ebabca9765d54d04600c4a50eda13893dadf67ed81d9a098"},
1139
+ {file = "typed_ast-1.5.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1098df9a0592dd4c8c0ccfc2e98931278a6c6c53cb3a3e2cf7e9ee3b06153344"},
1140
+ {file = "typed_ast-1.5.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42c47c3b43fe3a39ddf8de1d40dbbfca60ac8530a36c9b198ea5b9efac75c09e"},
1141
+ {file = "typed_ast-1.5.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f290617f74a610849bd8f5514e34ae3d09eafd521dceaa6cf68b3f4414266d4e"},
1142
+ {file = "typed_ast-1.5.2-cp39-cp39-win_amd64.whl", hash = "sha256:df05aa5b241e2e8045f5f4367a9f6187b09c4cdf8578bb219861c4e27c443db5"},
1143
+ {file = "typed_ast-1.5.2.tar.gz", hash = "sha256:525a2d4088e70a9f75b08b3f87a51acc9cde640e19cc523c7e41aa355564ae27"},
1144
+ ]
1145
  typing-extensions = [
1146
  {file = "typing_extensions-4.0.1-py3-none-any.whl", hash = "sha256:7f001e5ac290a0c0401508864c7ec868be4e701886d5b573a9528ed3973d9d3b"},
1147
  {file = "typing_extensions-4.0.1.tar.gz", hash = "sha256:4ca091dea149f945ec56afb48dae714f21e8692ef22a395223bcd328961b6a0e"},
pyproject.toml CHANGED
@@ -40,6 +40,7 @@ twine = "^3.4.2"
40
  pytest = "^6.2.4"
41
  pytest-runner = "^5.3.1"
42
  toml = "^0.10.2"
 
43
 
44
  [build-system]
45
  requires = ["poetry-core>=1.0.0"]
 
40
  pytest = "^6.2.4"
41
  pytest-runner = "^5.3.1"
42
  toml = "^0.10.2"
43
+ black = "^22.1.0"
44
 
45
  [build-system]
46
  requires = ["poetry-core>=1.0.0"]
tests/test_cli.py CHANGED
@@ -9,15 +9,13 @@ import sys
9
 
10
  @pytest.fixture
11
  def mock_args():
12
- sys.argv[1:] = ['--source', 'en', '--target', 'de', '--text', 'hello']
13
  return CLI(sys.argv[1:]).parse_args()
14
 
15
 
16
  def test_source(mock_args):
17
- assert mock_args.source == 'en'
18
 
19
 
20
  def test_target(mock_args):
21
- assert mock_args.target == 'de'
22
-
23
-
 
9
 
10
  @pytest.fixture
11
  def mock_args():
12
+ sys.argv[1:] = ["--source", "en", "--target", "de", "--text", "hello"]
13
  return CLI(sys.argv[1:]).parse_args()
14
 
15
 
16
  def test_source(mock_args):
17
+ assert mock_args.source == "en"
18
 
19
 
20
  def test_target(mock_args):
21
+ assert mock_args.target == "de"
 
 
tests/test_data.py CHANGED
@@ -1,4 +1,4 @@
1
- test_text_standard = 'Hello world.'
2
 
3
  TRANSLATED_RESULTS = {
4
  "afrikaans": "Hello Wêreld.",
@@ -108,5 +108,5 @@ TRANSLATED_RESULTS = {
108
  "xhosa": "Molo Lizwe.",
109
  "yiddish": "העלא וועלט.",
110
  "yoruba": "Mo ki O Ile Aiye.",
111
- "zulu": "Sawubona Mhlaba."
112
  }
 
1
+ test_text_standard = "Hello world."
2
 
3
  TRANSLATED_RESULTS = {
4
  "afrikaans": "Hello Wêreld.",
 
108
  "xhosa": "Molo Lizwe.",
109
  "yiddish": "העלא וועלט.",
110
  "yoruba": "Mo ki O Ile Aiye.",
111
+ "zulu": "Sawubona Mhlaba.",
112
  }
tests/test_deepl.py CHANGED
@@ -4,26 +4,26 @@ from deep_translator.deepl import DeeplTranslator
4
  from deep_translator.exceptions import AuthorizationException
5
 
6
 
7
- @patch('deep_translator.deepl.requests')
8
  def test_simple_translation(mock_requests):
9
- translator = DeeplTranslator(api_key='imagine-this-is-an-valid-api-key', source='en', target='es')
 
 
10
  # Set the request response mock.
11
  mock_response = Mock()
12
  mock_response.status_code = 200
13
- mock_response.json.return_value = {
14
- "translations": [{
15
- "text": "hola"
16
- }]
17
- }
18
  mock_requests.get.return_value = mock_response
19
- translation = translator.translate('hello')
20
- assert translation == 'hola'
21
 
22
 
23
- @patch('deep_translator.deepl.requests.get')
24
  def test_wrong_api_key(mock_requests):
25
- translator = DeeplTranslator(api_key='this-is-a-wrong-api-key!', source="en", target="es")
 
 
26
  # Set the response status_code only.
27
  mock_requests.return_value = Mock(status_code=403)
28
  with pytest.raises(AuthorizationException):
29
- translator.translate('Hello')
 
4
  from deep_translator.exceptions import AuthorizationException
5
 
6
 
7
+ @patch("deep_translator.deepl.requests")
8
  def test_simple_translation(mock_requests):
9
+ translator = DeeplTranslator(
10
+ api_key="imagine-this-is-an-valid-api-key", source="en", target="es"
11
+ )
12
  # Set the request response mock.
13
  mock_response = Mock()
14
  mock_response.status_code = 200
15
+ mock_response.json.return_value = {"translations": [{"text": "hola"}]}
 
 
 
 
16
  mock_requests.get.return_value = mock_response
17
+ translation = translator.translate("hello")
18
+ assert translation == "hola"
19
 
20
 
21
+ @patch("deep_translator.deepl.requests.get")
22
  def test_wrong_api_key(mock_requests):
23
+ translator = DeeplTranslator(
24
+ api_key="this-is-a-wrong-api-key!", source="en", target="es"
25
+ )
26
  # Set the response status_code only.
27
  mock_requests.return_value = Mock(status_code=403)
28
  with pytest.raises(AuthorizationException):
29
+ translator.translate("Hello")
tests/test_google.py CHANGED
@@ -12,12 +12,12 @@ def google_translator():
12
  """Sample pytest fixture.
13
  See more at: http://doc.pytest.org/en/latest/fixture.html
14
  """
15
- return GoogleTranslator(target='en')
16
 
17
 
18
  def test_content(google_translator):
19
  """Sample pytest test function with the pytest fixture as an argument."""
20
- assert google_translator.translate(text='좋은') == "good"
21
 
22
 
23
  def test_abbreviations_and_languages_mapping():
@@ -47,9 +47,9 @@ def test_empty_text(google_translator):
47
  def test_payload(google_translator):
48
 
49
  with pytest.raises(exceptions.NotValidPayload):
50
- google_translator.translate(text='1234')
51
- google_translator.translate(text='{}')
52
- google_translator.translate(text='%@')
53
 
54
  with pytest.raises(exceptions.NotValidPayload):
55
  google_translator.translate(text=123)
@@ -61,8 +61,8 @@ def test_payload(google_translator):
61
  google_translator.translate(text=[])
62
 
63
  with pytest.raises(exceptions.NotValidLength):
64
- google_translator.translate("a"*5001)
65
 
66
 
67
  def test_one_character_words():
68
- assert GoogleTranslator(source='es', target='en').translate('o') == 'or'
 
12
  """Sample pytest fixture.
13
  See more at: http://doc.pytest.org/en/latest/fixture.html
14
  """
15
+ return GoogleTranslator(target="en")
16
 
17
 
18
  def test_content(google_translator):
19
  """Sample pytest test function with the pytest fixture as an argument."""
20
+ assert google_translator.translate(text="좋은") == "good"
21
 
22
 
23
  def test_abbreviations_and_languages_mapping():
 
47
  def test_payload(google_translator):
48
 
49
  with pytest.raises(exceptions.NotValidPayload):
50
+ google_translator.translate(text="1234")
51
+ google_translator.translate(text="{}")
52
+ google_translator.translate(text="%@")
53
 
54
  with pytest.raises(exceptions.NotValidPayload):
55
  google_translator.translate(text=123)
 
61
  google_translator.translate(text=[])
62
 
63
  with pytest.raises(exceptions.NotValidLength):
64
+ google_translator.translate("a" * 5001)
65
 
66
 
67
  def test_one_character_words():
68
+ assert GoogleTranslator(source="es", target="en").translate("o") == "or"
tests/test_libre.py CHANGED
@@ -9,24 +9,24 @@ from deep_translator.constants import LIBRE_CODES_TO_LANGUAGES
9
 
10
  @pytest.fixture
11
  def libre():
12
- return LibreTranslator(source="en", target='fr', api_key='some_key')
13
 
14
 
15
  def test_inputs():
16
  with pytest.raises(exceptions.InvalidSourceOrTargetLanguage):
17
- LibreTranslator(source="", target="", api_key='some_key')
18
 
19
  with pytest.raises(exceptions.InvalidSourceOrTargetLanguage):
20
- LibreTranslator(source="auto", target="", api_key='some_key')
21
 
22
  with pytest.raises(exceptions.InvalidSourceOrTargetLanguage):
23
- LibreTranslator(source="", target="en", api_key='some_key')
24
 
25
 
26
  def test_abbreviations_and_languages_mapping():
27
  for abb, lang in LIBRE_CODES_TO_LANGUAGES.items():
28
- l1 = LibreTranslator(abb, api_key='some_key')
29
- l2 = LibreTranslator(lang, api_key='some_key')
30
  assert l1._source == l2._source
31
 
32
 
 
9
 
10
  @pytest.fixture
11
  def libre():
12
+ return LibreTranslator(source="en", target="fr", api_key="some_key")
13
 
14
 
15
  def test_inputs():
16
  with pytest.raises(exceptions.InvalidSourceOrTargetLanguage):
17
+ LibreTranslator(source="", target="", api_key="some_key")
18
 
19
  with pytest.raises(exceptions.InvalidSourceOrTargetLanguage):
20
+ LibreTranslator(source="auto", target="", api_key="some_key")
21
 
22
  with pytest.raises(exceptions.InvalidSourceOrTargetLanguage):
23
+ LibreTranslator(source="", target="en", api_key="some_key")
24
 
25
 
26
  def test_abbreviations_and_languages_mapping():
27
  for abb, lang in LIBRE_CODES_TO_LANGUAGES.items():
28
+ l1 = LibreTranslator(abb, api_key="some_key")
29
+ l2 = LibreTranslator(lang, api_key="some_key")
30
  assert l1._source == l2._source
31
 
32
 
tests/test_linguee.py CHANGED
@@ -8,14 +8,14 @@ from deep_translator import exceptions, LingueeTranslator
8
 
9
  @pytest.fixture
10
  def linguee():
11
- return LingueeTranslator(source="english", target='german')
12
 
13
 
14
  def test_content(linguee):
15
  """Sample pytest test function with the pytest fixture as an argument."""
16
  # from bs4 import BeautifulSoup
17
  # assert 'GitHub' in BeautifulSoup(response.content).title.string
18
- assert linguee.translate(word='good') is not None
19
 
20
 
21
  def test_inputs():
@@ -46,4 +46,4 @@ def test_payload(linguee):
46
  linguee.translate([])
47
 
48
  with pytest.raises(exceptions.NotValidLength):
49
- linguee.translate("a"*51)
 
8
 
9
  @pytest.fixture
10
  def linguee():
11
+ return LingueeTranslator(source="english", target="german")
12
 
13
 
14
  def test_content(linguee):
15
  """Sample pytest test function with the pytest fixture as an argument."""
16
  # from bs4 import BeautifulSoup
17
  # assert 'GitHub' in BeautifulSoup(response.content).title.string
18
+ assert linguee.translate(word="good") is not None
19
 
20
 
21
  def test_inputs():
 
46
  linguee.translate([])
47
 
48
  with pytest.raises(exceptions.NotValidLength):
49
+ linguee.translate("a" * 51)
tests/test_microsoft_trans.py CHANGED
@@ -10,22 +10,31 @@ from deep_translator import exceptions, MicrosoftTranslator
10
 
11
 
12
  # mocked request.post
13
- @patch.object(requests, 'post')
14
  def test_microsoft_successful_post_mock(mock_request_post):
15
- returned_json = [{'translations': [{'text': 'See you later!', 'to': 'en'}]}]
 
16
  def res():
17
  r = requests.Response()
 
18
  def json_func():
19
  return returned_json
 
20
  r.json = json_func
21
  return r
 
22
  mock_request_post.return_value = res()
23
- assert MicrosoftTranslator(api_key="an_api_key", source='de', target="en").translate("auf wiedersehen!") == "See you later!"
 
 
 
 
 
24
 
25
 
26
  def test_MicrosoftAPIerror():
27
  with pytest.raises(exceptions.MicrosoftAPIerror):
28
- MicrosoftTranslator(api_key="empty", source='de', target="en").translate("text")
29
 
30
 
31
  # the remaining tests are actual requests to Microsoft API and use an api key
@@ -36,13 +45,17 @@ APIkey = None
36
 
37
  @pytest.mark.skipif(APIkey is None, reason="api_key is not provided")
38
  def test_microsoft_successful_post_onetarget():
39
- posted = MicrosoftTranslator(api_key=APIkey, target="en").translate("auf wiedersehen!")
 
 
40
  assert isinstance(posted, str)
41
 
42
 
43
  @pytest.mark.skipif(APIkey is None, reason="api_key is not provided")
44
  def test_microsoft_successful_post_twotargets():
45
- posted = MicrosoftTranslator(api_key=APIkey, target=["en", "ru"]).translate("auf wiedersehen!")
 
 
46
  assert isinstance(posted, str)
47
 
48
 
@@ -58,5 +71,5 @@ def test_incorrect_target_attributes():
58
  def test_abbreviations():
59
  m1 = MicrosoftTranslator(api_key=APIkey, source="en", target="fr")
60
  m2 = MicrosoftTranslator(api_key=APIkey, source="English", target="French")
61
- assert ''.join(m1._source) == ''.join(m2._source)
62
- assert ''.join(m1._target) == ''.join(m2._target)
 
10
 
11
 
12
  # mocked request.post
13
+ @patch.object(requests, "post")
14
  def test_microsoft_successful_post_mock(mock_request_post):
15
+ returned_json = [{"translations": [{"text": "See you later!", "to": "en"}]}]
16
+
17
  def res():
18
  r = requests.Response()
19
+
20
  def json_func():
21
  return returned_json
22
+
23
  r.json = json_func
24
  return r
25
+
26
  mock_request_post.return_value = res()
27
+ assert (
28
+ MicrosoftTranslator(api_key="an_api_key", source="de", target="en").translate(
29
+ "auf wiedersehen!"
30
+ )
31
+ == "See you later!"
32
+ )
33
 
34
 
35
  def test_MicrosoftAPIerror():
36
  with pytest.raises(exceptions.MicrosoftAPIerror):
37
+ MicrosoftTranslator(api_key="empty", source="de", target="en").translate("text")
38
 
39
 
40
  # the remaining tests are actual requests to Microsoft API and use an api key
 
45
 
46
  @pytest.mark.skipif(APIkey is None, reason="api_key is not provided")
47
  def test_microsoft_successful_post_onetarget():
48
+ posted = MicrosoftTranslator(api_key=APIkey, target="en").translate(
49
+ "auf wiedersehen!"
50
+ )
51
  assert isinstance(posted, str)
52
 
53
 
54
  @pytest.mark.skipif(APIkey is None, reason="api_key is not provided")
55
  def test_microsoft_successful_post_twotargets():
56
+ posted = MicrosoftTranslator(api_key=APIkey, target=["en", "ru"]).translate(
57
+ "auf wiedersehen!"
58
+ )
59
  assert isinstance(posted, str)
60
 
61
 
 
71
  def test_abbreviations():
72
  m1 = MicrosoftTranslator(api_key=APIkey, source="en", target="fr")
73
  m2 = MicrosoftTranslator(api_key=APIkey, source="English", target="French")
74
+ assert "".join(m1._source) == "".join(m2._source)
75
+ assert "".join(m1._target) == "".join(m2._target)
tests/test_mymemory.py CHANGED
@@ -8,14 +8,14 @@ from deep_translator import exceptions, MyMemoryTranslator
8
 
9
  @pytest.fixture
10
  def mymemory():
11
- return MyMemoryTranslator(source="en", target='fr')
12
 
13
 
14
  def test_content(mymemory):
15
  """Sample pytest test function with the pytest fixture as an argument."""
16
  # from bs4 import BeautifulSoup
17
  # assert 'GitHub' in BeautifulSoup(response.content).title.string
18
- assert mymemory.translate(text='good') is not None
19
 
20
 
21
  def test_inputs():
@@ -46,6 +46,4 @@ def test_payload(mymemory):
46
  mymemory.translate(text=[])
47
 
48
  with pytest.raises(exceptions.NotValidLength):
49
- mymemory.translate(text="a"*501)
50
-
51
-
 
8
 
9
  @pytest.fixture
10
  def mymemory():
11
+ return MyMemoryTranslator(source="en", target="fr")
12
 
13
 
14
  def test_content(mymemory):
15
  """Sample pytest test function with the pytest fixture as an argument."""
16
  # from bs4 import BeautifulSoup
17
  # assert 'GitHub' in BeautifulSoup(response.content).title.string
18
+ assert mymemory.translate(text="good") is not None
19
 
20
 
21
  def test_inputs():
 
46
  mymemory.translate(text=[])
47
 
48
  with pytest.raises(exceptions.NotValidLength):
49
+ mymemory.translate(text="a" * 501)
 
 
tests/test_pons.py CHANGED
@@ -8,14 +8,14 @@ from deep_translator import exceptions, PonsTranslator
8
 
9
  @pytest.fixture
10
  def pons():
11
- return PonsTranslator(source="english", target='french')
12
 
13
 
14
  def test_content(pons):
15
  """Sample pytest test function with the pytest fixture as an argument."""
16
  # from bs4 import BeautifulSoup
17
  # assert 'GitHub' in BeautifulSoup(response.content).title.string
18
- assert pons.translate(word='good') is not None
19
 
20
 
21
  def test_inputs():
@@ -46,4 +46,3 @@ def test_payload(pons):
46
 
47
  with pytest.raises(exceptions.NotValidLength):
48
  pons.translate("a" * 51)
49
-
 
8
 
9
  @pytest.fixture
10
  def pons():
11
+ return PonsTranslator(source="english", target="french")
12
 
13
 
14
  def test_content(pons):
15
  """Sample pytest test function with the pytest fixture as an argument."""
16
  # from bs4 import BeautifulSoup
17
  # assert 'GitHub' in BeautifulSoup(response.content).title.string
18
+ assert pons.translate(word="good") is not None
19
 
20
 
21
  def test_inputs():
 
46
 
47
  with pytest.raises(exceptions.NotValidLength):
48
  pons.translate("a" * 51)