Translatee

Scripts to facilitate translations in daily workflows

28 Sep 2024

I have been using DeepL regularly for the last couple of years now.

Best translation solution in my experience, out of Germany.

Been using first the web interface, then the mac app.

Aiming now to streamline my daily workflow with a script that can be called with an Alfred keyword (see Alfred).

So goal is to be able to:

1) copy text in English
2) type 2 characters (eg td for Translate to DE) and translation gets pasted in place

API

Glossaries

See https://developers.deepl.com/docs/api-reference/glossaries

Create a glossary

"""
STEPS:
- create a glossary & get its ID
- update the glossary ID in global_context.py so it's used across the scripts
TODO: understand how to update glossary (create a new one each time?) & add logic to update global_context.py
"""

translator = deepl.Translator(DEEPL_API_KEY)

## Create an English to German glossary with two terms:

entries = {
    "Bonjour": "Bonjour", 
    "Best,": "VG aus dem Münchner Umland",
    }

my_glossary = translator.create_glossary(
    "Nic_Glossary_EN_DE",
    source_lang="EN",
    target_lang="DE",
    entries=entries,
)
print(
    f"Created '{my_glossary.name}' ({my_glossary.glossary_id}) "
    f"{my_glossary.source_lang}->{my_glossary.target_lang} "
    f"containing {my_glossary.entry_count} entries"
)


# ## Listing entries in a glossary

# entries = translator.get_glossary_entries("7a63d77f-0356-4cd0-9280-a6db7a704a00")
# print(entries)  

Python SDK

To translate documents:

# Translate a formal document from English to German
input_path = "/path/to/Instruction Manual.docx"
output_path = "/path/to/Bedienungsanleitung.docx"
try:
    # Using translate_document_from_filepath() with file paths 
    translator.translate_document_from_filepath(
        input_path,
        output_path,
        target_lang="DE",
        formality="more"
    )

    # Alternatively you can use translate_document() with file IO objects
    with open(input_path, "rb") as in_file, open(output_path, "wb") as out_file:
        translator.translate_document(
            in_file,
            out_file,
            target_lang="DE",
            formality="more"
        )

except deepl.DocumentTranslationException as error:
    # If an error occurs during document translation after the document was
    # already uploaded, a DocumentTranslationException is raised. The
    # document_handle property contains the document handle that may be used to
    # later retrieve the document from the server, or contact DeepL support.
    doc_id = error.document_handle.id
    doc_key = error.document_handle.key
    print(f"Error after uploading ${error}, id: ${doc_id} key: ${doc_key}")
except deepl.DeepLException as error:
    # Errors during upload raise a DeepLException
    print(error)

Script

Install the deepl package:

pip install deepl

Execute the following script:

import os
DEEPL_API_KEY = os.getenv("DEEPL_API_KEY")

import subprocess
import deepl
from pynput.keyboard import Key, Controller
keyb = Controller()

import global_context

def write_to_clipboard(output):
    process = subprocess.Popen(
        'pbcopy', env={'LANG': 'en_US.UTF-8'}, stdin=subprocess.PIPE)
    process.communicate(output.encode('utf-8'))
    print(f"\nOUTPUT COPIED TO CLIPBOARD\n{output}")

def paste():
    with keyb.pressed(Key.cmd):
        keyb.press('f')
        keyb.release('f')


def translate_text(input_text, target_language_code, formality="formal"):
    global DEEPL_API_KEY

    translator = deepl.Translator(DEEPL_API_KEY)

    if formality == "formal":
        formality = "more"
    elif formality == "informal":
        formality = "less"

    result = translator.translate_text(
        text=input_text,
        source_lang="EN",
        target_lang=target_language_code,
        context=global_context.context,
        split_sentences=1,
        preserve_formatting=1,
        formality=formality, # "less", "more", "prefer_more", "prefer_less"
        # show_billed_characters=True,
    )

    output = result.text

    print(f"\n\ntranslate_text:\n{output}\n\n")

    return result.text


clipboard_content = subprocess.check_output(['pbpaste']).decode('utf-8')


print()
translated_text = translate_text(clipboard_content, 'DE')
write_to_clipboard(translated_text)

paste()

Or create Alfred workflow:

#! /bin/zsh

source /Users/xxx/translatee/venv/bin/activate

python3 /Users/xxx/translatee/translate_to_de.py

links

social