Python에서 DeepL 번역 사용하기 (제2회)

이 기사에서는 DeepL 번역 API 사용법 제2회로, 파일 번역에 대해 소개합니다. (제1회는 여기)
※Python과 Linux의 기초 지식을 전제로 합니다.
텍스트 파일 번역
워밍업이 끝났으니, 다음으로 파일 번역을 해봅시다.
이는 3개의 API 호출을 조합할 필요가 있습니다.
적당한 일본어가 들어간 텍스트 파일 test.txt를 준비해 주세요.
그것을 영어(미국)로 번역하여 test.trans.txt로 저장하는 구조를 생각해 봅니다.
1단계: 원본 언어 파일 업로드
DeepL 서버에 번역 요청을 보낼 때 원본 언어 파일을 지정합니다.
$ curl https://api.deepl.com/v2/document \
$ -F file=@test.txt \
$ -F auth_key=${auth_key} \
$ -F target_lang=en-us
번역 요청을 접수한 파일의 document_id와 document_key가
역시 json 형식으로 서버에서 반환됩니다.
전송까지의 처리를 Python으로 작성하면 다음과 같습니다:
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)
auth_key와 target_lang의 지정이 상당히 까다롭네요.
files 항목 지정에는 몇 가지 방법이 있는데, 2항 튜플의 경우
1항목은 파일명, 2항목은 객체입니다.
문자열을 지정하는 경우에는 이런 식으로 작성합니다.
다른 방법으로는 auth_key와 target_lang을
첫 번째 문자열 번역과 마찬가지로 data(dict 형식) 쪽에 저장하고
requests.post()에 data와 files를 모두 전달하는 방법도 있습니다.
2단계: 번역 처리 상태 가져오기
번역 중인 파일의 번역 상태를 조회합니다:
$ 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}
상태는 queued(접수됨), translating(번역 중),
error(번역 오류 발생), done(번역 완료)의 4가지입니다.
translating의 경우에는 처리 예상 시간도 반환됩니다.
변수 document_id와 document_key의 대입을 마쳤다고 가정하고
전송까지의 처리를 Python으로 작성하면 다음과 같습니다:
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)
3단계: 대상 언어 파일 다운로드
번역 상태가 done이 되면 파일을 다운로드합니다:
$ curl https://api.deepl.com/v2/document/${document_id}/result \
$ -d auth_key=${auth_key} \
$ -d document_key=${document_key} > test.trans.txt
다운로드는 한 번만 수행합니다.
번역 결과는 test.trans.txt로 리다이렉트(저장)하고 있습니다.
전송까지의 처리를 Python으로 작성하면 다음과 같습니다:
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)
파일 번역 처리
마지막으로, 이상의 처리를 연결합니다.
2단계는 번역 진행 상황만 반환되므로,
그 결과를 받아 대기하는 처리가 필요합니다. 기본적으로는:
・translating인 경우 남은 시간 seconds_remaining의
초만큼 sleep하고 다시 진행 상황을 확인합니다.
・done이나 error가 나오면 루프를 빠져나옵니다.
이상의 처리를 Python으로 작성하면 다음과 같습니다:
import requests
import json
from time import sleep
def get_key():
return open('key.txt').read().rstrip()
def upload_src(fn):
”’
파일 번역 1단계: 원본 언어 파일 업로드
”’
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(현재는 사용 안 함)
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):
”’
단계 2의 sub: 번역 처리 상태 가져오기
”’
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 (현재는 사용 안 함)
res_text = res.text
res_data = json.loads(res_text)
return res_data
def check_proceeding(document_id, document_key):
”’
파일 번역 단계 2: 번역 처리 대기
”’
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’])
# 오류 회피
if seconds_remaining <= 0:
seconds_remaining = 10
else: # 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):
”’
파일 번역 단계 3: 대상 언어 파일 다운로드
”’
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 (현재는 사용 안 함)
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()
3종류의 API 호출은 비슷한 처리이지만,
'curl 명령어를 Python으로 작성한다'는 주제를 위해
일부러 통합하지 않고 장황하게 작성했습니다.
이상, 이 글에서는:
・DeepL API를 사용하여 파일을 번역했습니다.
・curl 명령어 내용을 Python으로 표현하여 프로그램을 작성했습니다.
읽어주셔서 감사합니다.





