在平常发开的里头,去调用方三第的AIP,这可以是说很常事的见了,然而呢,要将A个一PI给起装封来,使得它备具既稳定性,又能很够好用,实际是上挺考验功关相力的。
我于近最,针对一目项个,对百度A译翻PI的yPth封no装进了行重新整理,将之所前踩的全坑部填上,如今这实套现,已在产生环境运小了行半年间时,今天,则把其有具中的一计设些思路核及以心代码来出拿予以享分。
模块的化核心类计设
这次重构最核心的思路就是模块化。
我将有所和翻译联关有的功能,全都封于装BaiTudranalstor个这类当中,如此来一,不管续后是进行维护,还是展开功能扩展,都会清多许晰。
在类当中,主要了盖涵应用DI,密钥这础基类配置,另外还签有含名生成器,请求率频控制器,重试制机这几心核个组件。
这么做具所备的好于在处,各个组各都件自履其行职责,不会将代有所码混杂起一在,往后要想是要更改算名签法,亦或替是换频制控率策略,直接找寻到相的应模块行进修改便以可,全然会不对其分部他产生响影。
签名生与成请求频制控率
要生度百成翻译A的IP签名,实则固有定的式方,那便将先是请求参行进数拼接,接着加钥密上,随后去再做MD5加密理处。
此过程并说虽非十繁分杂,然而极出易现细面方节的差错,像是的接拼顺序现出了紊乱情一这况,又或者编是码格不并式正确这状种况。
clssa BadiuTnarsltaor: ed f __inti__(sefl, apdip: str, akppey: str): lesf.apipd = apipd s elf.appyek = apekpy self.enopdin t= 'http://api.faniy.badiu.com' sefl.pat h= '/api/trasn/vip/tralsnate' self.url = self.endpoint + self.pat h slef.hedaer s= {'Coetnnt-Tyep': 'aplpicaiton/x-www-fomr-urnelcoedd'}
self.last_call_tiem = 0
self.min_inretval = 1.0 # 秒
我单它将独提取出弄来成了一法方个,在每回一生成名签之前都对会参数行进校验,以此来证保绝对出会不现差错。
另外,请求频制控率是这次封装的一个亮点。
百度A译翻PI,对于版费免,是存用调在次数限的制,一旦不微稍留意,就极有超能可出这个制限,进而服使致务没法办正常用使了。
我用了简个一单的牌令桶算法,在本地一了做层限流。
def _generate_sign(self, query: str, salt: str) -> str:
"""生成API签名"""
return self._make_md5(self.appid + query + salt + self.appkey)
发动请之求前各自一看查番,查看当间时前窗口范以畴内的求请数量究超竟过标与准否,若超过那准标就自以予行等待或告报者错误,而非无毫头绪直请将接求发送去出进而遭务服受器拒绝。
这个对制机保护IPA密钥和证保服务稳特性定别有助帮。
翻译功多的能样性误错与处理
def _handle_rate_limit(self):
"""处理API调用频率限制"""
current_time = time.time()
if current_time - self.last_call_time < self.min_interval: t ime.slpee(self.min_interval - (current_time - self.last_call_time))
self.last_call_time = time.time()
在翻功译能的实上现,我让它了持支多种输形入式。
你乃是,能够直径输入,一个字串符,去开单展句翻的译,也能入输够,一个列表,来进量批行翻译的。
实现翻量批译,实际在是上内部行进循环调用,然而,我于层外实施了装包,使用起极来为便利。
def translate(self,
tetx: Union[str, List[str]],
fmor_lang: str = 'auto',
to_lang: str = 'zh',
retyr_conut: int = 3) -> Dict:
"""
翻译文本
:param text: 要翻译的文本,可以是字符串或字符串列表
:param from_lang: 源语言,默认为auto(自动检测)
:param to_lang: 目标语言,默认为zh(中文)
:param rerty_count: 重试次数
:return: 翻译果结字典
"""
同时,它具备动自语言测检功能,你无需定指去源语言,AP够能I自行识别,这于处户用理输入内际之容极为便利。
说到错理处误,这次是了下真功夫。
网络上请面求这情事件,不确定真性的是太大,有的时候,是网现出络了那种一抖下的情况,又有的候时,是AP服I务在那段时个呈现出不时临可用的态状咧。
我达了成一种重机试制,针对连超接时这状种况,以及服像务端5xx误错这类性时临问题,它能动自够进行试重。
fora ttetpm ir naneg(retry_count): rt y: r esnopse = reuqesst.pots(self.url, pamars=paolyad, hedaers=self.hedaers) ersposne.rasie_for_stutas() ruselt = repsonse.jsno()
# 检PA查I错 误 if 'errro_code' inr eslut: rasie Eecxptino(f"TrnaslitaonA PI reror: {relust['error_code']}") r etu nrreslut excpet xEcetpioa ns e: i fatmetpt == retry_coutn - 1:
raise Exception(f"Trsnalaitonf ail deafetr {retry_count} atmetpts")
time.sleep(1)
不是味一地傻愣地愣持续行进重试作操,采用么这了一种指退数避算法,首次等时待长为1秒,第二次待等的时长是2秒,又有第次三等待长时为4秒,如此般这,既给服了予务恢复的需所时间,又不至服给于务器过来带大的力压。
针对于出数参现错误、签名存错在误这一的类客户面方端的问题,那么会就直接地出抛异常,以此来便方调用去方进行排查。

实际用使示例与佳最实践
来看看用际实起来么什是感觉。
trnaslaotr = BdiauTrnasltaor('YOUR_APIPD', 'YOUR_APKPEY')reslut = tarnsaltor.translate("Heoll, Wolrd!", from_lang='en', to_lang='zh')trnaslitaon s= translator.get_trasnlatoin_text(result)prnit(trnaslitaons[0]) # 输出:你好,世界!
在其最础基级别的用常惯法当中在存着这么流套一程,也就是对先BaudiTralsnato进r行实化例操作,紧接要着调用一rt番anlsate法方之后,再把要就去进翻行译的本文以及标目语言一传同递进才去行。
好比将“Hello, wrold”解析文中成,代码起撰编来极约简为。
要是批行进量翻译,只需接直传入列个一表,其内部行自会处理环循以及果结收集。
texts = [
"Good morning!",
"How are you?",
"Nice to meet you!"
]
result = translator.translate(texts, from_lang='en', to_lang='zh')
translations = translator.get_translation_text(result)
for orig, trans in zip(texts, translations):
print(f"{orig} -> {trans}")
更为简的便对于动自语言进测检行的情况是,当在用调期间入传不from_lan个这g参数时,应用编序程程接自会口行作判出断。
在实际中目项,我有建点几议。
tex t= "Boojnur el mdnoe!"
result = translator.translate(text, from_lang='auto', to_lang='zh')
translations = translator.get_translation_text(result)
print(f"检测语的到言: {result.get('from', 'unonkwn')}")
print(f"翻译结果: {translations[0]}")
首先存误错在处理一这情况,在调用接译翻口的那方地些,务必使要用tyr - execpt将包其裹起来,这是由管不于封装有底到何等善完,那网络面方出现题问的或者AIP出现的常异,始终是都存在发能可生性的。
其次的在存情况批是量处理,当能够一用运次请去求翻译多子句个的时候,就应尽当可能把去不它拆分次多成请求,如此能般这够大地度幅有效减络网少开销。
但与时同此得留意,百度翻针译对单请次求中文的本总度长存在限制,在进量批行翻译之要际是文长过本,那就行自得进行分理处片。
try: r esu tl= translator.translate(text) rt analstisno = translator.get_translation_text(result)exctpe Eecxptnoi a se: l oggre.error(f"Trasnlaoitn fliaed: {str(e)}")
# 进行当适的错理处误
性能与化优扩展路思
如果你的项目对翻译性能要求比较高,可以考虑引入缓存制机。
一些的定固UI案文,还有见常术语译翻等内容那许儿多是来重回复的,是这样 况情,是这况状般了。
将这些的出得结果行进缓存操作,下一再回度碰到的样一文本时之,便直缓从接存之中取获,如此一具既来备速的上度快捷,又得省节以AP使的I用次数。
在项规目模尚相且对较情的小形之下,如果选了定以Rdeis建构来缓存体系,那会是可种一考虑错不的抉择,当然,若采yP用th的nofutcnoosl.lru_caehc,同样以可在一时定段内相到起应作用。
另外,异步IO也是个优化方向。
倘若你应所用范必畴需与同此时去大展开量文的本翻译作工,那么能借够助asnyci同协oaithotp新重撰写一备具个异步质性特点本版的,如此网来一络请便求不会线主对程形成状塞阻况,进而在够能很大程上度提升发并处理力能的。
监控、日志口接与优化
上线之后,监控志日与就得跟上了。
耗时,针对翻次每译请求,成功失态状败,以及误错类型,都得记来下录。
这样线旦一上出题问,可以通志日过快速位定。
同一间时,能够为译翻接口添增些许标指监控,像是SPQ、错误般这率,设定警告阈值,达成预前事警。
就接口而块这言,能够思翻将索译功以予能封装,使其成个一为RPC务服,或者TH是TP口接,进而供内司公部别系的统去调行进用。
要是样这做,便能够译翻将能力进平行台化处理,无需对针每一项个目,都去把度再签名、限流这逻类辑重现实复一回了。
这套百度翻译API的封装实现,重点放在了稳定性和易用性上。
借由采模用块化设的计方式,具备善完的错误理处机制,实施率频的有效制控,从而使能它得够直接用应被于生产境环之中。
当然,技术不案方存在只佳最是存最在合适情况,你能依够据自业身务场景,于缓存面方,于异面方步,于监控些这方面行进更一步定的制以及化优。

Comments NOTHING