Uso de la traducción de DeepL desde Python (Parte 2)

En este artículo, presentaremos la segunda parte sobre cómo utilizar la API de DeepL Translator, centrándonos en la traducción de archivos. (La primera parte está aquí)
※Se asumen conocimientos básicos de Python y Linux.

Traducción de archivos de texto

Una vez terminado el calentamiento, intentemos realizar una traducción de archivos.
Para ello, es necesario combinar tres llamadas a la API.
Prepare un archivo de texto test.txt que contenga texto en japonés.
Pensaremos en un mecanismo para traducirlo al inglés (EE. UU.) y guardarlo como test.trans.txt.

Paso 1: Carga del archivo en el idioma original

Al enviar una solicitud de traducción al servidor de DeepL, se especifica el archivo de idioma original.

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

 

El document_id y la document_key del archivo cuya solicitud de traducción ha sido aceptada
se devuelven desde el servidor, también en formato JSON.
El proceso hasta el envío escrito en Python es el siguiente:

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)

 

La especificación de auth_key y target_lang es bastante complicada.
Hay varias formas de especificar el elemento files; en el caso de una tupla de dos elementos,
el primer elemento es el nombre del archivo y el segundo es el objeto.
Si se especifica una cadena de texto, se escribe de esta manera.
Como otro método, auth_key y target_lang
pueden almacenarse en data (formato dict), al igual que en la traducción de cadenas inicial,
y pasar tanto data como files a requests.post().

Paso 2: Obtención del estado del proceso de traducción

Consulte el estado de traducción del archivo que se está traduciendo:

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

 

Los estados son cuatro: queued (aceptado), translating (traduciendo),
error (error de traducción) y done (traducción finalizada).
En el caso de translating, también se devuelve una estimación del tiempo restante de procesamiento.
Suponiendo que ya se han asignado las variables document_id y document_key,
el proceso hasta el envío escrito en Python es el siguiente:

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)

 

Paso 3: Descarga del archivo en el idioma de destino

Una vez que el estado de traducción sea done, descargue el archivo:

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

 

La descarga se realiza una sola vez.
Estamos redirigiendo (guardando) el resultado de la traducción en test.trans.txt.
El proceso hasta el envío escrito en Python sería el siguiente:

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)

 

Proceso de traducción de archivos

Por último, conectamos los procesos anteriores.
Dado que el paso 2 solo devuelve el estado de progreso de la traducción,
es necesario un proceso de espera para recibir dicho resultado. Básicamente:
・Si es translating , se debe esperar (sleep) durante los seconds_remaining
segundos restantes y volver a verificar el estado del progreso.
・Si aparece done o error , se sale del bucle.
El proceso anterior escrito en Python sería el siguiente:

import requests
import json
from time import sleep

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

def upload_src(fn):
”’
Paso 1 de la traducción de archivos: subir el archivo de idioma original
”’
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 si tiene éxito (no se usa por ahora)
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):
”’
Subpaso 2: obtener el estado del proceso de traducción
”’
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 si tiene éxito (no se usa por ahora)
res_text = res.text
res_data = json.loads(res_text)
return res_data

def check_proceeding(document_id, document_key):
    ”’
    Paso 2 de traducción de archivos: esperando el procesamiento de traducción
    ”’
    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’])
                # Evitar errores
                if seconds_remaining <= 0:
                    seconds_remaining = 10
        else: # queued, etc.
            pass
        print(f’…waiting for (another) {seconds_remaining}s’, flush=True)
        sleep(seconds_remaining)
    return status

def download_tgt(fn, document_id, document_key):
    ”’
    Paso 3 de traducción de archivos: descarga del archivo en el idioma de destino
    ”’
    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 si tiene éxito (no se usa actualmente)
    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()

 

Los tres tipos de llamadas a la API tienen procesos similares, pero
con el fin de tratar el tema de "escribir comandos curl en Python",
he optado deliberadamente por no combinarlos y escribir el código de forma redundante.

En resumen, en este artículo:

・He traducido archivos utilizando la API de DeepL.
・He creado un programa representando el contenido del comando curl en Python.

Gracias por leer.