This repository has been archived by the owner on May 29, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathsogou_translate.py
200 lines (164 loc) · 6.11 KB
/
sogou_translate.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
import requests
import hashlib
import json
import random
from enum import Enum
ERROR_DICT = {
'1001': 'Translate API: Unsupported language type',
'1002': 'Translate API: Text too long',
'1003': 'Translate API: Invalid PID',
'1004': 'Translate API: Trial PID limit reached',
'1005': 'Translate API: PID traffic too high',
'1006': 'Translate API: Insufficient balance',
'1007': 'Translate API: Random number does not exist',
'1008': 'Translate API: Signature does not exist',
'1009': 'Translate API: The signature is incorrect',
'10010': 'Translate API: Text does not exist',
'1050': 'Translate API: Internal server error',
}
class SogouTranslateException(Exception):
def __init__(self, message):
super().__init__(message)
def _error_code_to_exception(code: str) -> SogouTranslateException:
return SogouTranslateException(ERROR_DICT[code])
class SogouLanguages(Enum):
AR = 'ar' # Arabic
ET = 'et' # Estonian
BG = 'bg' # Bulgarian
PL = 'pl' # Polish
KO = 'ko' # Korean
BS_LATN = 'bs-Latn' # Bosnian (Latin)
FA = 'fa' # Persian
MWW = 'mww' # Hmong Daw
DA = 'da' # Danish
DE = 'de' # German
RU = 'ru' # Russian
FR = 'fr' # French
FI = 'fi' # Finnish
TLH_QAAK = 'tlh-Qaak' # Klingon (pIqaD)
TLH = 'tlh' # Klingon
HR = 'hr' # Croatian
OTQ = 'otq' # Querétaro Otomi
CA = 'ca' # Catalan
CS = 'cs' # Czech
RO = 'ro' # Romanian
LV = 'lv' # Latvian
HT = 'ht' # Haitian Creole
LT = 'lt' # Lithuanian
NL = 'nl' # Dutch
MS = 'ms' # Malay
MT = 'mt' # Maltese
PT = 'pt' # Portuguese
JA = 'ja' # Japanese
SL = 'sl' # Slovenian
TH = 'th' # Thai
TR = 'tr' # Turkish
SR_LATN = 'sr-Latn' # Serbian (Latin)
SR_CYRL = 'sr-Cyrl' # Serbian (Cyrillic)
SK = 'sk' # Slovak
SW = 'sw' # Kiswahili
AF = 'af' # South African Common Dutch
NO = 'no' # Norwegian
EN = 'en' # English
ES = 'es' # Spanish
UK = 'uk' # Ukrainian
UR = 'ur' # Urdu
EL = 'el' # Greek
HU = 'hu' # Hungarian
CY = 'cy' # Welsh
YUA = 'yua' # Yucatec Maya
HE = 'he' # Hebrew
ZH_CHS = 'zh-CHS' # Chinese Simplified
IT = 'it' # Italian
HI = 'hi' # Hindi
ID = 'id' # Indonesian
ZH_CHT = 'zh-CHT' # Chinese Traditional
VI = 'vi' # Vietnamese
SV = 'sv' # Swedish
YUE = 'yue' # Cantonese
FJ = 'fj' # fijian
FIL = 'fil' # Filipino
SM = 'sm' # Samoan language
TO = 'to' # lea fakatonga
TY = 'ty' # Tahiti language
MG = 'mg' # Malagasy language
BN = 'bn' # Bengali
class SogouTranslate:
SOGOU_API_URL = 'https://fanyi.sogou.com/reventondc/api/sogouTranslate'
def __init__(self, pid: str, secret_key: str):
"""Initialize SogouTranslate
Arguments:
pid {str} -- pid for this service
secret_key {str} -- secret key for this server
Raises:
SogouTranslateException -- while exeception occurs calling this service, detailed exception message will be provided.
"""
if (not pid) or (not secret_key):
raise SogouTranslateException('pid or secret key cannot be empty')
self.pid = pid
self.secret_key = secret_key
def _generate_salt(self) -> str:
"""Generate salt string
Returns:
str -- the salt string
"""
return hashlib.sha256(str(random.getrandbits(256)).encode('utf-8')).hexdigest()[:19]
def _compute_sign(self, source_text: str, salt: str) -> str:
"""Compute the sign string according to Sogou's requirement (https://deepi.sogou.com/docs/fanyiDoc)
Arguments:
source_text {str} -- The text to be translated
salt {str} -- the salt string
Returns:
[str] -- The sign string
"""
text = self.pid + source_text + salt + self.secret_key
return hashlib.md5(text.encode('utf-8')).hexdigest()
def _generate_data(self, source_text: str, from_language: SogouLanguages,
to_language: SogouLanguages):
"""Generate the data for requesting the translating service
Arguments:
source_text {str} -- the text to be translated
from_language {SogouLanguages} -- the language type of source_text
to_language {SogouLanguages} -- the language for translation
Returns:
dict -- a dictionary containing the data to be posted to Sogou's API server
"""
salt = self._generate_salt()
data = {
'q': source_text, # text
'from': from_language.value, # from language
'to': to_language.value, # to language
'pid': self.pid, # pid
'salt': salt, # salt
'sign': self._compute_sign(source_text, salt), # sign
'charset': 'utf-8', # charset
# 'callback': '', # optional for CORs
}
return data
def translate(self, source_text: str, from_language: SogouLanguages,
to_language: SogouLanguages) -> str:
"""The translate API
Arguments:
source_text {str} -- the text to be translated
from_language {SogouLanguages} -- the source language type
to_language {SogouLanguages} -- the target lanaguage type
Raises:
SogouTranslateException -- while exeception occurs calling this service, detailed exception message will be provided
Returns:
[str] -- the translated text
"""
if not source_text:
raise SogouTranslateException('Source text does not exist')
data = self._generate_data(
source_text, from_language, to_language
)
res = requests.post(self.SOGOU_API_URL, data=data)
if not res.ok:
raise SogouTranslateException(
'Translation request is not successful'
)
json_res = json.loads(res.text)
error_code = json_res['errorCode']
if error_code != '0':
raise _error_code_to_exception(error_code)
return json_res['translation']