Using DeepL Translator with Python (Part 2)

In this article, we will introduce file translation, the second part of how to use the DeepL Translator API. (Part 1 is here)
*Assumes basic knowledge of Python and Linux.

Translating text files

Now that the warm-up is over, let's try file translation.
This requires combining three API calls.
Please prepare a text file test.txt containing some Japanese text.
We will design a mechanism to translate it into English (US) and save it as test.trans.txt.

Step 1: Uploading the source language file

When sending a translation request to the DeepL server, you specify the source language file.

$ curl https://api.deepl.com/v2/document \
$ -F file=@test.txt \
$ -F auth_key=${auth_key} \
$ -F target_lang=en-us

 

The document_id and document_key of the file for which the translation request was accepted
are returned from the server, also in JSON format.
The Python code for the process up to transmission is as follows:

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)

 

Specifying auth_key and target_lang is quite tricky.
There are several ways to specify the files item; in the case of a 2-item tuple,
the first item is the filename and the second is the object.
When specifying a string, it is written like this.
As another method, auth_key and target_lang can also be
stored in data (dict format), similar to the initial text translation,
and both data and files can be passed to requests.post().

Step 2: Retrieving the translation process status

Query the translation status of the file being translated:

$ 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}

 

There are four statuses: queued (accepted), translating (translating),
error (translation error occurred), and done (translation finished).
In the case of translating, an estimate of the remaining processing time is also returned.
Assuming that the variables document_id and document_key have been assigned,
the Python code for the process up to transmission is as follows:

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)

 

Step 3: Downloading the target language file

Once the translation status becomes done, download the file:

$ curl https://api.deepl.com/v2/document/${document_id}/result \
$ -d auth_key=${auth_key} \
$ -d document_key=${document_key} > test.trans.txt

 

The download is performed only once.
The translation result is redirected (saved) to test.trans.txt.
The process up to the submission can be written in Python as follows:

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)

 

File translation process

Finally, we connect the above processes.
Since step 2 only returns the translation progress status,
a waiting process is required to receive that result. Basically:
・If translating , sleep for the number of seconds in seconds_remaining
and check the progress status again.
・If done or error is returned, exit the loop.
The above process can be written in Python as follows:

import requests
import json
from time import sleep

def get_key():
return open('key.txt').read().rstrip()

def upload_src(fn):
'''
File translation step 1: Uploading the source language file
'''
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 if successful (not used for now)
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):
    ”’
    Step 2 sub: Get translation processing status
    ”’
    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 if successful (not used for now)
    res_text = res.text
    res_data = json.loads(res_text)
    return res_data

def check_proceeding(document_id, document_key):
    ”’
    File translation step 2: Waiting for translation processing
    ”’
    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’])
                # Avoid errors
                if seconds_remaining <= 0:
                    seconds_remaining = 10
        else: # e.g., 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):
    ”’
    File translation step 3: Download target language file
    ”’
    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 if successful (not used for now)
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()

 

The three types of API calls are similar processes, but
for the theme of "writing curl commands in Python,"
I have intentionally written them redundantly without consolidating them.

In summary, this article has:

・I translated the file using the DeepL API.
・I created a program by expressing the curl command content in Python.

Thank you for reading.