Added test cases and support for translate_batch and translate_file
Browse files- deep_translator/libre.py +34 -4
- deep_translator/main.py +9 -1
- examples/libre.py +2 -4
- tests/test_libre.py +46 -6
deep_translator/libre.py
CHANGED
@@ -3,8 +3,6 @@ LibreTranslate API
|
|
3 |
"""
|
4 |
|
5 |
import requests
|
6 |
-
from bs4 import BeautifulSoup
|
7 |
-
from requests.models import Response
|
8 |
from .parent import BaseTranslator
|
9 |
from .constants import BASE_URLS,LIBRE_LANGUAGES_TO_CODES, LIBRE_CODES_TO_LANGUAGES
|
10 |
from .exceptions import (ServerException,
|
@@ -21,7 +19,7 @@ class LibreTranslator(BaseTranslator):
|
|
21 |
_languages = LIBRE_LANGUAGES_TO_CODES
|
22 |
supported_languages = list(_languages.keys())
|
23 |
|
24 |
-
def __init__(self, base_url = BASE_URLS.get("LIBRE_FREE"), api_key=
|
25 |
"""
|
26 |
@param source: source language to translate from
|
27 |
List of LibreTranslate nedpoints can be found at : https://github.com/LibreTranslate/LibreTranslate#mirrors
|
@@ -86,8 +84,11 @@ class LibreTranslator(BaseTranslator):
|
|
86 |
"q": text,
|
87 |
"source": self.source,
|
88 |
"target": self.target,
|
89 |
-
"
|
90 |
}
|
|
|
|
|
|
|
91 |
# Do the request and check the connection.
|
92 |
try:
|
93 |
response = requests.post(self.__base_url + translate_endpoint, params=params)
|
@@ -105,3 +106,32 @@ class LibreTranslator(BaseTranslator):
|
|
105 |
raise TranslationNotFound(text)
|
106 |
# Process and return the response.
|
107 |
return res['translatedText']
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
"""
|
4 |
|
5 |
import requests
|
|
|
|
|
6 |
from .parent import BaseTranslator
|
7 |
from .constants import BASE_URLS,LIBRE_LANGUAGES_TO_CODES, LIBRE_CODES_TO_LANGUAGES
|
8 |
from .exceptions import (ServerException,
|
|
|
19 |
_languages = LIBRE_LANGUAGES_TO_CODES
|
20 |
supported_languages = list(_languages.keys())
|
21 |
|
22 |
+
def __init__(self,source="auto", target="en", base_url = BASE_URLS.get("LIBRE_FREE"), api_key=None, **kwargs):
|
23 |
"""
|
24 |
@param source: source language to translate from
|
25 |
List of LibreTranslate nedpoints can be found at : https://github.com/LibreTranslate/LibreTranslate#mirrors
|
|
|
84 |
"q": text,
|
85 |
"source": self.source,
|
86 |
"target": self.target,
|
87 |
+
"format": 'text'
|
88 |
}
|
89 |
+
# Add API Key if required
|
90 |
+
if self.api_key:
|
91 |
+
params["api_key"] = self.api_key
|
92 |
# Do the request and check the connection.
|
93 |
try:
|
94 |
response = requests.post(self.__base_url + translate_endpoint, params=params)
|
|
|
106 |
raise TranslationNotFound(text)
|
107 |
# Process and return the response.
|
108 |
return res['translatedText']
|
109 |
+
|
110 |
+
def translate_file(self, path, **kwargs):
|
111 |
+
"""
|
112 |
+
translate directly from file
|
113 |
+
@param path: path to the target file
|
114 |
+
@type path: str
|
115 |
+
@param kwargs: additional args
|
116 |
+
@return: str
|
117 |
+
"""
|
118 |
+
try:
|
119 |
+
with open(path) as f:
|
120 |
+
text = f.read().strip()
|
121 |
+
return self.translate(text)
|
122 |
+
except Exception as e:
|
123 |
+
raise e
|
124 |
+
|
125 |
+
def translate_batch(self, batch=None, **kwargs):
|
126 |
+
"""
|
127 |
+
translate a list of texts
|
128 |
+
@param batch: list of texts you want to translate
|
129 |
+
@return: list of translations
|
130 |
+
"""
|
131 |
+
if not batch:
|
132 |
+
raise Exception("Enter your text list that you want to translate")
|
133 |
+
arr = []
|
134 |
+
for i, text in enumerate(batch):
|
135 |
+
translated = self.translate(text, **kwargs)
|
136 |
+
arr.append(translated)
|
137 |
+
return arr
|
deep_translator/main.py
CHANGED
@@ -10,6 +10,7 @@ from .pons import PonsTranslator
|
|
10 |
from .yandex import YandexTranslator
|
11 |
from .microsoft import MicrosoftTranslator
|
12 |
from .papago import PapagoTranslator
|
|
|
13 |
|
14 |
CONTEXT_SETTINGS = dict(help_option_names=["-h", "--help"])
|
15 |
@click.group()
|
@@ -64,6 +65,11 @@ def translate(translator, source, target, text, api_key):
|
|
64 |
source=source,
|
65 |
target=target,
|
66 |
api_key=api_key)
|
|
|
|
|
|
|
|
|
|
|
67 |
else:
|
68 |
raise AttributeError("The given translator is not supported.")
|
69 |
|
@@ -105,6 +111,8 @@ def languages(translator, api_key):
|
|
105 |
translator = MicrosoftTranslator(api_key=api_key)
|
106 |
elif translator == "papago":
|
107 |
translator = PapagoTranslator(api_key=api_key)
|
|
|
|
|
108 |
else:
|
109 |
raise AttributeError("The given translator is not supported.")
|
110 |
|
@@ -117,7 +125,7 @@ def languages(translator, api_key):
|
|
117 |
@cli.command()
|
118 |
def list():
|
119 |
"""Lists available translators."""
|
120 |
-
click.echo("Available translators include: Google, MyMemory, QCRI, Linguee, Pons, Yandex, Microsoft (Bing), and
|
121 |
return 0
|
122 |
|
123 |
if __name__ == "__main__":
|
|
|
10 |
from .yandex import YandexTranslator
|
11 |
from .microsoft import MicrosoftTranslator
|
12 |
from .papago import PapagoTranslator
|
13 |
+
from .libre import LibreTranslator
|
14 |
|
15 |
CONTEXT_SETTINGS = dict(help_option_names=["-h", "--help"])
|
16 |
@click.group()
|
|
|
65 |
source=source,
|
66 |
target=target,
|
67 |
api_key=api_key)
|
68 |
+
elif translator == "libre":
|
69 |
+
translator= LibreTranslator(
|
70 |
+
source=source,
|
71 |
+
target=target
|
72 |
+
)
|
73 |
else:
|
74 |
raise AttributeError("The given translator is not supported.")
|
75 |
|
|
|
111 |
translator = MicrosoftTranslator(api_key=api_key)
|
112 |
elif translator == "papago":
|
113 |
translator = PapagoTranslator(api_key=api_key)
|
114 |
+
elif translator == "libre":
|
115 |
+
translator = LibreTranslator
|
116 |
else:
|
117 |
raise AttributeError("The given translator is not supported.")
|
118 |
|
|
|
125 |
@cli.command()
|
126 |
def list():
|
127 |
"""Lists available translators."""
|
128 |
+
click.echo("Available translators include: Google, MyMemory, QCRI, Linguee, Pons, Yandex, Microsoft (Bing), Papago and LibreTranslate.")
|
129 |
return 0
|
130 |
|
131 |
if __name__ == "__main__":
|
examples/libre.py
CHANGED
@@ -1,7 +1,5 @@
|
|
1 |
-
|
2 |
from deep_translator import LibreTranslator
|
3 |
|
|
|
4 |
|
5 |
-
|
6 |
-
|
7 |
-
# print(res)
|
|
|
|
|
1 |
from deep_translator import LibreTranslator
|
2 |
|
3 |
+
res = LibreTranslator(source='de', target='en').translate('laufen')
|
4 |
|
5 |
+
print(res)
|
|
|
|
tests/test_libre.py
CHANGED
@@ -4,7 +4,29 @@
|
|
4 |
|
5 |
import pytest
|
6 |
from deep_translator import exceptions, LibreTranslator
|
7 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8 |
|
9 |
@pytest.fixture
|
10 |
def libre():
|
@@ -17,6 +39,13 @@ def test_content(libre):
|
|
17 |
# assert 'GitHub' in BeautifulSoup(response.content).title.string
|
18 |
assert libre.translate(text='good') is not None
|
19 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
|
21 |
def test_inputs():
|
22 |
with pytest.raises(exceptions.LanguageNotSupportedException):
|
@@ -25,11 +54,12 @@ def test_inputs():
|
|
25 |
with pytest.raises(exceptions.LanguageNotSupportedException):
|
26 |
LibreTranslator(source="auto", target="nothing")
|
27 |
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
|
|
33 |
|
34 |
def test_payload(libre):
|
35 |
with pytest.raises(exceptions.NotValidPayload):
|
@@ -47,3 +77,13 @@ def test_payload(libre):
|
|
47 |
|
48 |
def test_one_character_words():
|
49 |
assert LibreTranslator(source='es', target='en').translate('y') == 'and'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
|
5 |
import pytest
|
6 |
from deep_translator import exceptions, LibreTranslator
|
7 |
+
from deep_translator.constants import LIBRE_CODES_TO_LANGUAGES
|
8 |
+
import random
|
9 |
+
|
10 |
+
test_text_standard = 'Hello world.'
|
11 |
+
TRANSLATED_RESULTS = {
|
12 |
+
'English': 'Hello world.',
|
13 |
+
'Arabic': 'مرحبا العالم.',
|
14 |
+
'Chinese': '霍洛美世界。',
|
15 |
+
'French': 'Bonjour.',
|
16 |
+
'German': 'Hallo Welt.',
|
17 |
+
'Hindi': 'नमस्ते दुनिया।',
|
18 |
+
'Indonesian': 'Halo dunia.',
|
19 |
+
'Irish': 'Dia duit domhan.',
|
20 |
+
'Italian': 'Ciao mondo.',
|
21 |
+
'Japanese': 'こんにちは。',
|
22 |
+
'Korean': '안녕하세요.',
|
23 |
+
'Polish': 'Hello world (ang.).',
|
24 |
+
'Portuguese': 'Olá, mundo.',
|
25 |
+
'Russian': 'Привет мир.',
|
26 |
+
'Spanish': 'Hola mundo.',
|
27 |
+
'Turkish': 'Merhaba dünya.',
|
28 |
+
'Vietnamese': 'Xin chào.'
|
29 |
+
}
|
30 |
|
31 |
@pytest.fixture
|
32 |
def libre():
|
|
|
39 |
# assert 'GitHub' in BeautifulSoup(response.content).title.string
|
40 |
assert libre.translate(text='good') is not None
|
41 |
|
42 |
+
def test_random_tranlations_cases_multiple_names():
|
43 |
+
random_sample_size = 2
|
44 |
+
d = dict.fromkeys(list(TRANSLATED_RESULTS.keys()))
|
45 |
+
random_lang_names = random.sample(list(d.keys()), random_sample_size)
|
46 |
+
random_subset_dict = {k: TRANSLATED_RESULTS[k] for k in random_lang_names}
|
47 |
+
for lang, translation in random_subset_dict.items():
|
48 |
+
assert LibreTranslator(source='en', target=lang).translate(test_text_standard) == translation
|
49 |
|
50 |
def test_inputs():
|
51 |
with pytest.raises(exceptions.LanguageNotSupportedException):
|
|
|
54 |
with pytest.raises(exceptions.LanguageNotSupportedException):
|
55 |
LibreTranslator(source="auto", target="nothing")
|
56 |
|
57 |
+
def test_abbreviations_and_languages_mapping():
|
58 |
+
for abb, lang in LIBRE_CODES_TO_LANGUAGES.items():
|
59 |
+
if abb != 'en':
|
60 |
+
l1 = LibreTranslator(abb)
|
61 |
+
l2 = LibreTranslator(lang)
|
62 |
+
assert l1.source == l2.source
|
63 |
|
64 |
def test_payload(libre):
|
65 |
with pytest.raises(exceptions.NotValidPayload):
|
|
|
77 |
|
78 |
def test_one_character_words():
|
79 |
assert LibreTranslator(source='es', target='en').translate('y') == 'and'
|
80 |
+
|
81 |
+
def test_translate_batch():
|
82 |
+
words_to_translate = ['How are you','Good','Thank You']
|
83 |
+
translated_words = ['¿Cómo estás?','Bien.','Gracias.']
|
84 |
+
assert LibreTranslator(source='en',target='es').translate_batch((words_to_translate)) == translated_words
|
85 |
+
|
86 |
+
def test_translate_file():
|
87 |
+
filePath = 'examples/test.txt'
|
88 |
+
translatedText='Un párrafo es una serie de frases relacionadas que desarrollan una idea central, llamada el tema. Trate de pensar en los párrafos en términos de unidad temática: un párrafo es una frase o un grupo de oraciones que apoya una idea central y unificada. Los párrafos añaden una idea a la vez a su argumento más amplio.'
|
89 |
+
assert LibreTranslator(source='en',target='es').translate_file(filePath) == translatedText
|