Sử dụng DeepL Translator từ Python (Phần 2)

Trong bài viết này, chúng tôi sẽ giới thiệu phần thứ hai về cách sử dụng API của DeepL Translator, đó là dịch tệp. (Phần 1 có tại đây)
※Giả định rằng bạn đã có kiến thức cơ bản về Python và Linux.
Dịch tệp văn bản
Sau khi đã khởi động xong, hãy cùng thử dịch tệp nhé.
Việc này đòi hỏi phải kết hợp ba lệnh gọi API.
Hãy chuẩn bị một tệp văn bản test.txt có chứa nội dung tiếng Nhật phù hợp.
Chúng ta sẽ xây dựng cơ chế để dịch tệp đó sang tiếng Anh (Mỹ) và lưu lại dưới tên test.trans.txt.
Bước 1: Tải tệp ngôn ngữ gốc lên
Khi gửi yêu cầu dịch đến máy chủ DeepL, bạn cần chỉ định tệp ngôn ngữ gốc.
$ curl https://api.deepl.com/v2/document \
$ -F file=@test.txt \
$ -F auth_key=${auth_key} \
$ -F target_lang=en-us
document_id và document_key của tệp đã tiếp nhận yêu cầu dịch,
sẽ được máy chủ trả về dưới định dạng json.
Quy trình xử lý cho đến khi gửi đi được viết bằng Python như sau:
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)
Việc chỉ định auth_key và target_lang khá là phức tạp.
Có một vài cách để chỉ định mục files, nếu là tuple 2 phần tử,
phần tử thứ nhất là tên tệp, phần tử thứ hai là đối tượng.
Nếu chỉ định chuỗi ký tự, cách viết sẽ như thế này.
Một cách khác là, auth_key và target_lang,
giống như dịch chuỗi ký tự ban đầu, bạn có thể lưu trữ vào data (định dạng dict),
và truyền cả data lẫn files vào requests.post().
Bước 2: Lấy trạng thái xử lý dịch
Truy vấn trạng thái dịch của tệp đang trong quá trình dịch:
$ 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}
Có 4 trạng thái: queued (đã tiếp nhận), translating (đang dịch),
error (xảy ra lỗi dịch), done (đã dịch xong).
Trong trường hợp translating, thời gian dự kiến còn lại của quá trình xử lý cũng sẽ được trả về.
Giả sử đã gán xong các biến document_id và document_key,
quy trình xử lý cho đến khi gửi đi được viết bằng Python như sau:
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)
Bước 3: Tải tệp ngôn ngữ đích xuống
Khi trạng thái dịch trở thành done, hãy tải tệp xuống:
$ curl https://api.deepl.com/v2/document/${document_id}/result \
$ -d auth_key=${auth_key} \
$ -d document_key=${document_key} > test.trans.txt
Việc tải xuống chỉ thực hiện một lần duy nhất.
Kết quả dịch được chuyển hướng (lưu) vào test.trans.txt.
Quy trình xử lý cho đến khi gửi đi được viết bằng Python như sau:
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)
Xử lý dịch tệp
Cuối cùng, chúng ta kết nối các quy trình trên lại với nhau.
Vì bước 2 chỉ trả về trạng thái tiến độ dịch,
nên cần có quy trình chờ đợi để nhận kết quả đó. Về cơ bản:
・Nếu là translating , hãy sleep trong số giây seconds_remaining còn lại
rồi kiểm tra lại tiến độ.
・Nếu xuất hiện done hoặc error , hãy thoát khỏi vòng lặp.
Quy trình xử lý trên được viết bằng Python như sau:
import requests
import json
from time import sleep
def get_key():
return open('key.txt').read().rstrip()
def upload_src(fn):
”’
Xử lý dịch tệp bước 1: Tải tệp ngôn ngữ gốc lên
”’
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 nếu thành công (hiện tại chưa dùng)
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):
”’
Sub bước 2: Lấy trạng thái xử lý dịch
”’
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 nếu thành công (hiện tại không dùng)
res_text = res.text
res_data = json.loads(res_text)
return res_data
def check_proceeding(document_id, document_key):
”’
Bước dịch tệp 2: Chờ xử lý dịch
”’
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’])
# Tránh lỗi
if seconds_remaining <= 0:
seconds_remaining = 10
else: # ví dụ như 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):
”’
Bước dịch tệp 3: Tải xuống tệp ngôn ngữ đích
”’
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 nếu thành công (hiện tại không dùng)
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()
Ba loại lệnh gọi API có quy trình xử lý tương tự nhau,
nhưng vì chủ đề là "viết lệnh curl bằng Python",
nên tôi cố tình không gộp lại mà viết theo cách dài dòng.
Tóm lại, trong bài viết này:
・Đã dịch tệp bằng cách sử dụng API của DeepL.
・Đã tạo chương trình bằng cách biểu diễn nội dung của lệnh curl trong Python.
Cảm ơn bạn đã đọc bài viết.





