การใช้ DeepL Translator ด้วย Python (ตอนที่ 2)

ในบทความนี้ เราจะมาแนะนำวิธีการใช้งาน API ของ DeepL ในตอนที่ 2 ซึ่งเป็นเรื่องเกี่ยวกับการแปลไฟล์ (สามารถดูตอนที่ 1 ได้ ที่นี่)
※บทความนี้ตั้งอยู่บนพื้นฐานความรู้เบื้องต้นเกี่ยวกับ Python และ Linux
การแปลไฟล์ข้อความ
หลังจากวอร์มอัพกันเสร็จแล้ว ต่อไปเรามาลองแปลไฟล์กันดูครับ
การแปลไฟล์จำเป็นต้องใช้การเรียก API ร่วมกัน 3 ขั้นตอน
ให้เตรียมไฟล์ข้อความที่มีภาษาญี่ปุ่นอยู่ข้างในชื่อ test.txt ไว้
เราจะมาสร้างกลไกเพื่อแปลไฟล์นั้นเป็นภาษาอังกฤษ (สหรัฐอเมริกา) และบันทึกเป็น test.trans.txt
ขั้นตอนที่ 1: การอัปโหลดไฟล์ภาษาต้นฉบับ
เมื่อส่งคำขอแปลไปยังเซิร์ฟเวอร์ของ DeepL ให้ระบุไฟล์ต้นฉบับ
$ curl https://api.deepl.com/v2/document \
$ -F file=@test.txt \
$ -F auth_key=${auth_key} \
$ -F target_lang=en-us
document_id และ document_key ของไฟล์ที่ได้รับคำขอแปลแล้ว
จะถูกส่งกลับมาจากเซิร์ฟเวอร์ในรูปแบบ JSON เช่นเคย
โค้ด Python สำหรับการประมวลผลจนถึงขั้นตอนการส่งมีดังนี้:
url = 'https://api.deepl.com/v2/document'
files = dict()
files['file'] = open(fn, 'rb')
files['auth_key'] = (None, get_key())
files['target_lang'] = (None, 'en-us')
res = requests.post(url, files=files)
การระบุ auth_key และ target_lang นั้นค่อนข้างซับซ้อนเล็กน้อย
วิธีการระบุรายการใน files นั้นมีหลายวิธี หากใช้ tuple 2 รายการ
รายการแรกคือชื่อไฟล์ และรายการที่สองคือออบเจกต์
หากต้องการระบุเป็นสตริง จะต้องเขียนในลักษณะนี้
อีกวิธีหนึ่งคือการเก็บ auth_key และ target_lang ไว้ใน data (รูปแบบ dict)
เช่นเดียวกับการแปลสตริงในตอนแรก
แล้วส่งทั้ง data และ files ไปยัง requests.post() พร้อมกัน
ขั้นตอนที่ 2: การรับสถานะกระบวนการแปล
ตรวจสอบสถานะการแปลของไฟล์ที่กำลังดำเนินการอยู่:
$ document_id=[documentID]
$ document_key=[documentKey]
$ curl https://api.deepl.com/v2/document/${document_id} \
$ -d auth_key=${auth_key} \
$ -d document_key=${document_key}
สถานะมี 4 แบบ ได้แก่ queued (รับคำขอแล้ว), translating (กำลังแปล),
error (เกิดข้อผิดพลาดในการแปล), และ done (แปลเสร็จสิ้น)
ในกรณีที่เป็น translating ระบบจะส่งค่าประมาณเวลาที่เหลือในการประมวลผลกลับมาด้วย
สมมติว่าได้กำหนดค่าตัวแปร document_id และ document_key เรียบร้อยแล้ว
โค้ด Python สำหรับการประมวลผลจนถึงขั้นตอนการส่งมีดังนี้:
url = f'https://api.deepl.com/v2/document/{document_id}'
data = dict()
data['auth_key'] = get_key()
data['document_key'] = document_key
res = requests.post(url, data=data)
ขั้นตอนที่ 3: การดาวน์โหลดไฟล์ภาษาปลายทาง
เมื่อสถานะการแปลเป็น done แล้ว ให้ดาวน์โหลดไฟล์:
$ curl https://api.deepl.com/v2/document/${document_id}/result \
$ -d auth_key=${auth_key} \
$ -d document_key=${document_key} > test.trans.txt
ดาวน์โหลดได้เพียงครั้งเดียวเท่านั้น
ผลลัพธ์การแปลจะถูกเปลี่ยนเส้นทาง (บันทึก) ไปยัง test.trans.txt
กระบวนการจนถึงขั้นตอนการส่งข้อมูลเมื่อเขียนด้วย Python จะเป็นดังนี้:
url = f'https://api.deepl.com/v2/document/{document_id}/result'
data = dict()
data['auth_key'] = get_key()
data['document_key'] = document_key
res = requests.post(url, data=data)
กระบวนการแปลไฟล์
สุดท้ายนี้ เราจะเชื่อมโยงกระบวนการทั้งหมดเข้าด้วยกัน
เนื่องจากขั้นตอนที่ 2 จะส่งกลับมาเพียงสถานะความคืบหน้าของการแปลเท่านั้น
จึงจำเป็นต้องมีกระบวนการรอเพื่อรับผลลัพธ์ดังกล่าว โดยพื้นฐานแล้ว:
・หากเป็น translating ให้รอ (sleep) ตามจำนวนวินาทีที่เหลืออยู่ใน seconds_remaining
แล้วตรวจสอบสถานะความคืบหน้าอีกครั้ง
・หากเป็น done หรือ error ให้หลุดออกจากลูป
กระบวนการข้างต้นเมื่อเขียนด้วย Python จะเป็นดังนี้:
import requests
import json
from time import sleep
def get_key():
return open('key.txt').read().rstrip()
def upload_src(fn):
'''
ขั้นตอนการแปลไฟล์ 1: อัปโหลดไฟล์ภาษาต้นฉบับ
'''
url = 'https://api.deepl.com/v2/document'
files = dict()
files['file'] = open(fn, 'rb')
files['auth_key'] = (None, get_key())
files['target_lang'] = (None, 'en-us')
res = requests.post(url, files=files)
res_status = res.status_code # หากสำเร็จจะเป็น 200 (ยังไม่ได้ใช้ในตอนนี้)
res_text = res.text
res_data = json.loads(res_text)
document_id = res_data['document_id']
document_key = res_data['document_key']
return document_id, document_key
def get_trans_status(document_id, document_key):
'''
ขั้นตอนย่อยของขั้นตอนที่ 2: ดึงสถานะการประมวลผลการแปล
'''
url = f'https://api.deepl.com/v2/document/{document_id}'
data = dict()
data['auth_key'] = get_key()
data['document_key'] = document_key
res = requests.post(url, data=data)
res_status = res.status_code # หากสำเร็จจะเป็น 200 (ยังไม่ได้ใช้ในตอนนี้)
res_text = res.text
res_data = json.loads(res_text)
return res_data
def check_proceeding(document_id, document_key):
”’
ขั้นตอนการแปลไฟล์ที่ 2: รอการประมวลผลการแปล
”’
while True:
res = get_trans_status(document_id, document_key)
status = res[‘status’]
print(f’status: {status}’, flush=True)
seconds_remaining = 0
if status == ‘done’ or status == ‘error’:
break
elif status == ‘translating’:
if ‘seconds_remaining’ in res:
seconds_remaining = int(res[‘seconds_remaining’])
# ป้องกันข้อผิดพลาด
if seconds_remaining <= 0:
seconds_remaining = 10
else: # เช่น queued
pass
print(f’…waiting for (another) {seconds_remaining}s’, flush=True)
sleep(seconds_remaining)
return status
def download_tgt(fn, document_id, document_key):
”’
ขั้นตอนการแปลไฟล์ที่ 3: ดาวน์โหลดไฟล์ภาษาปลายทาง
”’
url = f’https://api.deepl.com/v2/document/{document_id}/result’
data = dict()
data[‘auth_key’] = get_key()
data[‘document_key’] = document_key
res = requests.post(url, data=data)
res_status = res.status_code # 200 หากสำเร็จ (ยังไม่ได้ใช้ในขณะนี้)
tgt_bin = res._content
with open(fn, ‘w’, encoding=’utf-8′) as f:
print(tgt_bin.decode(‘utf-8’), end=”, file=f)
def main():
fn_src = ‘test.txt’
fn_tgt = fn_src.replace(‘.txt’, ‘.trans.txt’)
print(f’fn_src: {fn_src}’)
print(f’fn_tgt: {fn_tgt}’)
print(f'uploading: {fn_src}')
document_id, document_key = upload_src(fn_src)
status = check_proceeding(document_id, document_key)
if status == 'done':
print(f'downloading: {fn_tgt}')
download_tgt(fn_tgt, document_id, document_key)
if __name__ == '__main__':
main()
การเรียกใช้ API ทั้ง 3 ประเภทมีกระบวนการที่คล้ายคลึงกัน แต่เพื่อจุดประสงค์ในหัวข้อ "การเขียนคำสั่ง curl ด้วย Python"
จึงจงใจเขียนแบบยืดเยื้อโดยไม่รวมเข้าด้วยกัน
สรุปแล้ว ในบทความนี้:
・แปลไฟล์โดยใช้ API ของ DeepL
・สร้างโปรแกรมโดยแปลงเนื้อหาของคำสั่ง curl ให้เป็น Python
ขอบคุณที่อ่านจนจบ





