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.