Usando o DeepL Translator com Python (Parte 2)

Neste artigo, apresentaremos a segunda parte sobre como usar a API de tradução do DeepL, focando na tradução de arquivos. (A primeira parte está aqui)
※Pressupõe-se conhecimento básico de Python e Linux.

Tradução de arquivos de texto

Agora que o aquecimento terminou, vamos tentar fazer a tradução de arquivos.
Para isso, é necessário combinar três chamadas de API.
Prepare um arquivo de texto test.txt contendo algum texto em japonês.
Vamos criar um mecanismo para traduzi-lo para inglês (EUA) e salvá-lo como test.trans.txt.

Passo 1: Upload do arquivo no idioma original

Ao enviar uma solicitação de tradução para o servidor do DeepL, você especifica o arquivo no idioma original.

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

 

O document_id e a document_key do arquivo que teve a solicitação de tradução aceita
são retornados pelo servidor, também em formato JSON.
O processamento até o envio escrito em Python é o seguinte:

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)

 

A especificação de auth_key e target_lang é bastante complicada.
Existem várias maneiras de especificar o item 'files'; no caso de uma tupla de dois itens,
o primeiro item é o nome do arquivo e o segundo é o objeto.
Ao especificar uma string, escreve-se desta forma.
Como outra alternativa, auth_key e target_lang podem ser,
assim como na tradução de strings inicial, armazenados no 'data' (formato dict),
e passar tanto 'data' quanto 'files' para o requests.post().

Passo 2: Obtenção do status do processo de tradução

Consulta o status da tradução do arquivo que está sendo traduzido:

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

 

Existem quatro status: queued (aceito), translating (traduzindo),
error (erro de tradução ocorrido) e done (tradução concluída).
No caso de 'translating', uma estimativa do tempo restante de processamento também é retornada.
Assumindo que a atribuição das variáveis document_id e document_key já foi feita,
o processamento até o envio escrito em Python é o seguinte:

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)

 

Passo 3: Download do arquivo no idioma de destino

Quando o status da tradução for done, baixe o arquivo:

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

 

O download é feito apenas uma vez.
O resultado da tradução está sendo redirecionado (salvo) em test.trans.txt.
O processo até o envio, escrito em Python, é o seguinte:

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)

 

Processamento de tradução de arquivos

Por fim, conectamos os processos acima.
Como o passo 2 apenas retorna o progresso da tradução,
é necessário um processo de espera para receber o resultado. Basicamente:
・Se for translating , aguarde (sleep) pelo número de segundos em seconds_remaining
e verifique o progresso novamente.
・Se for done ou error , saia do loop.
O processo acima, escrito em Python, é o seguinte:

import requests
import json
from time import sleep

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

def upload_src(fn):
"""
Passo 1 da tradução de arquivo: upload do arquivo 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 se bem-sucedido (não utilizado no momento)
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-passo 2: obtenção do status do processamento de tradução
"""
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 se bem-sucedido (não utilizado no momento)
res_text = res.text
res_data = json.loads(res_text)
return res_data

def check_proceeding(document_id, document_key):
    ”’
    Passo 2 da tradução de arquivo: aguardando processamento de tradução
    ”’
    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 erro
                if seconds_remaining <= 0:
                    seconds_remaining = 10
        else: # queued etc.
            pass
        print(f’…aguardando por (mais) {seconds_remaining}s’, flush=True)
        sleep(seconds_remaining)
    return status

def download_tgt(fn, document_id, document_key):
    ”’
    Passo 3 da tradução de arquivo: download do arquivo no 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 se bem-sucedido (não usado no momento)
    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()

 

Os três tipos de chamadas de API são processos semelhantes, mas
para o tema de "escrever comandos curl em Python",
optei por não resumi-los e escrevê-los de forma redundante.

Em resumo, neste artigo:

・Traduzi arquivos usando a API do DeepL.
・Criei um programa representando o conteúdo do comando curl em Python.

Obrigado por ler.