Package: deepl
DeepL Python LibraryTheDeepL APIis a language translation API that allows other
computer programs to send texts and documents to DeepL's servers and receive
high-quality translations. This opens a whole universe of opportunities for
developers: any translation product you can imagine can now be built on top of
DeepL's best-in-class translation technology.The DeepL Python library offers a convenient way for applications written in
Python to interact with the DeepL API. We intend to support all API functions
with the library, though support for new features may be added to the library
after they’re added to the API.Getting an authentication keyTo use the DeepL Python Library, you'll need an API authentication key. To get a
key,please create an account here. With a DeepL API Free
account you can translate up to 500,000 characters/month for free.InstallationThe library can be installed fromPyPIusing pip:pipinstall--upgradedeeplIf you need to modify this source code, install the dependencies using poetry:poetryinstallOn Ubuntu 22.04 an error might occur:ModuleNotFoundError: No module named  'cachecontrol'. Use the workaroundsudo apt install python3-cachecontrolas
explained in thisbug report.RequirementsThe library is tested with Python versions 3.6 to 3.11.Therequestsmodule is used to perform HTTP requests; the minimum is version
2.0.Starting in 2024, we will drop support for older Python versions that have
reached official end-of-life. You can find the Python versions and support
timelineshere.
To continue using this library, you should update to Python 3.8+.UsageImport the package and construct aTranslator. The first argument is a string
containing your API authentication key as found in yourDeepL Pro Account.Be careful not to expose your key, for example when sharing source code.importdeeplauth_key="f63c02c5-f056-..."# Replace with your keytranslator=deepl.Translator(auth_key)result=translator.translate_text("Hello, world!",target_lang="FR")print(result.text)# "Bonjour, le monde !"This example is for demonstration purposes only. In production code, the
authentication key should not be hard-coded, but instead fetched from a
configuration file or environment variable.Translatoraccepts additional options, seeConfigurationfor more information.Translating textTo translate text, calltranslate_text(). The first argument is a string
containing the text you want to translate, or a list of strings if you want to
translate multiple texts.source_langandtarget_langspecify the source and target language codes
respectively. Thesource_langis optional, if it is unspecified the source
language will be auto-detected.Language codes arecase-insensitivestrings according to ISO 639-1, for
example'DE','FR','JA''. Some target languages also include the regional
variant according to ISO 3166-1, for example'EN-US', or'PT-BR'. The full
list of supported languages is in theAPI documentation.There are additional optional arguments to control translation, seeText translation optionsbelow.translate_text()returns aTextResult, or a list ofTextResults
corresponding to your input text(s).TextResulthas two properties:textis
the translated text, anddetected_source_langis the detected source language
code.# Translate text into a target language, in this case, French:result=translator.translate_text("Hello, world!",target_lang="FR")print(result.text)# "Bonjour, le monde !"# Translate multiple texts into British Englishresult=translator.translate_text(["お元気ですか？","¿Cómo estás?"],target_lang="EN-GB")print(result[0].text)# "How are you?"print(result[0].detected_source_lang)# "JA" the language code for Japaneseprint(result[1].text)# "How are you?"print(result[1].detected_source_lang)# "ES" the language code for Spanish# Translate into German with less and more Formality:print(translator.translate_text("How are you?",target_lang="DE",formality="less"))# 'Wie geht es dir?'print(translator.translate_text("How are you?",target_lang="DE",formality="more"))# 'Wie geht es Ihnen?'Text translation optionsIn addition to the input text(s) argument, the availabletranslate_text()arguments are:source_lang: Specifies the source language code, but may be omitted to
auto-detect the source language.target_lang: Required. Specifies the target language code.split_sentences: specify how input text should be split into sentences,
default:'on'.'on''(SplitSentences.ON): input text will be split into sentences
using both newlines and punctuation.'off'(SplitSentences.OFF): input text will not be split into
sentences. Use this for applications where each input text contains only
one sentence.'nonewlines'(SplitSentences.NO_NEWLINES): input text will be split
into sentences using punctuation but not newlines.preserve_formatting: controls automatic-formatting-correction. Set toTrueto prevent automatic-correction of formatting, default:False.formality: controls whether translations should lean toward informal or
formal language. This option is only available for some target languages, seeListing available languages.'less'(Formality.LESS): use informal language.'more'(Formality.MORE): use formal, more polite language.glossary: specifies a glossary to use with translation, either as a string
containing the glossary ID, or aGlossaryInfoas returned byget_glossary().context: specifies additional context to influence translations, that is not
translated itself. Note this is analpha feature: it may be deprecated at
any time, or incur charges if it becomes generally available.
See theAPI documentationfor more information and
example usage.tag_handling: type of tags to parse before translation, options are'html'and'xml'.The following options are only used iftag_handlingis'xml':outline_detection: specifyFalseto disable automatic tag detection,
default isTrue.splitting_tags: list of XML tags that should be used to split text into
sentences. Tags may be specified as an array of strings (['tag1', 'tag2']),
or a comma-separated list of strings ('tag1,tag2'). The default is an empty
list.non_splitting_tags: list of XML tags that should not be used to split text
into sentences. Format and default are the same as forsplitting_tags.ignore_tags: list of XML tags that containing content that should not be
translated. Format and default are the same as forsplitting_tags.For a detailed explanation of the XML handling options, see theAPI documentation.Translating documentsTo translate documents, you may call eithertranslate_document()using file IO
objects, ortranslate_document_from_filepath()using file paths. For both
functions, the first and second arguments correspond to the input and output
files respectively.Just as for thetranslate_text()function, thesource_langandtarget_langarguments specify the source and target language codes.There are additional optional arguments to control translation, seeDocument translation optionsbelow.# Translate a formal document from English to Germaninput_path="/path/to/Instruction Manual.docx"output_path="/path/to/Bedienungsanleitung.docx"try:# Using translate_document_from_filepath() with file pathstranslator.translate_document_from_filepath(input_path,output_path,target_lang="DE",formality="more")# Alternatively you can use translate_document() with file IO objectswithopen(input_path,"rb")asin_file,open(output_path,"wb")asout_file:translator.translate_document(in_file,out_file,target_lang="DE",formality="more")exceptdeepl.DocumentTranslationExceptionaserror:# 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.iddoc_key=error.document_handle.keyprint(f"Error after uploading ${error}, id: ${doc_id}key: ${doc_key}")exceptdeepl.DeepLExceptionaserror:# Errors during upload raise a DeepLExceptionprint(error)translate_document()andtranslate_document_from_filepath()are convenience
functions that wrap multiple API calls: uploading, polling status until the
translation is complete, and downloading. If your application needs to execute
these steps individually, you can instead use the following functions directly:translate_document_upload(),translate_document_get_status()(ortranslate_document_wait_until_done()), andtranslate_document_download()Document translation optionsIn addition to the input file, output file,source_langandtarget_langarguments, the availabletranslate_document()andtranslate_document_from_filepath()arguments are:formality: same as inText translation options.glossary: same as inText translation options.output_format: (translate_document()only)
file extension of desired format of translated file, for example:'pdf'. If
unspecified, by default the translated file will be in the same format as the
input file.GlossariesGlossaries allow you to customize your translations using user-defined terms.
Multiple glossaries can be stored with your account, each with a user-specified
name and a uniquely-assigned ID.Creating a glossaryYou can create a glossary with your desired terms and name usingcreate_glossary(). Each glossary applies to a single source-target language
pair. Note: Glossaries are only supported for some language pairs, seeListing available glossary languagesfor more information. The entries should be specified as a dictionary.If successful, the glossary is created and stored with your DeepL account, and
aGlossaryInfoobject is returned including the ID, name, languages and entry
count.# Create an English to German glossary with two terms:entries={"artist":"Maler","prize":"Gewinn"}my_glossary=translator.create_glossary("My glossary",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")# Example: Created 'My glossary' (559192ed-8e23-...) EN->DE containing 2 entriesYou can also upload a glossary downloaded from the DeepL website usingcreate_glossary_from_csv(). Instead of supplying the entries as a dictionary,
specify the CSV data ascsv_dataeither as a file-like object or string or
bytes containing file content:# Open the CSV file assuming UTF-8 encoding. If your file contains a BOM,# consider using encoding='utf-8-sig' instead.withopen('/path/to/glossary_file.csv','r',encoding='utf-8')ascsv_file:csv_data=csv_file.read()# Read the file contents as a stringmy_csv_glossary=translator.create_glossary_from_csv("CSV glossary",source_lang="EN",target_lang="DE",csv_data=csv_data,)TheAPI documentationexplains the expected CSV format in
detail.Getting, listing and deleting stored glossariesFunctions to get, list, and delete stored glossaries are also provided:get_glossary()takes a glossary ID and returns aGlossaryInfoobject for a
stored glossary, or raises an exception if no such glossary is found.list_glossaries()returns a list ofGlossaryInfoobjects corresponding to
all of your stored glossaries.delete_glossary()takes a glossary ID orGlossaryInfoobject and deletes
the stored glossary from the server, or raises an exception if no such
glossary is found.# Retrieve a stored glossary using the IDglossary_id="559192ed-8e23-..."my_glossary=translator.get_glossary(glossary_id)# Find and delete glossaries named 'Old glossary'glossaries=translator.list_glossaries()forglossaryinglossaries:ifglossary.name=="Old glossary":translator.delete_glossary(glossary)Listing entries in a stored glossaryTheGlossaryInfoobject does not contain the glossary entries, but instead
only the number of entries in theentry_countproperty.To list the entries contained within a stored glossary, useget_glossary_entries()providing either theGlossaryInfoobject or glossary
ID:entries=translator.get_glossary_entries(my_glossary)print(entries)# "{'artist': 'Maler', 'prize': 'Gewinn'}"Using a stored glossaryYou can use a stored glossary for text translation by setting theglossaryargument to either the glossary ID orGlossaryInfoobject. You must also
specify thesource_langargument (it is required when using a glossary):text="The artist was awarded a prize."with_glossary=translator.translate_text(text,source_lang="EN",target_lang="DE",glossary=my_glossary,)print(with_glossary)# "Der Maler wurde mit einem Gewinn ausgezeichnet."# For comparison, the result without a glossary:without_glossary=translator.translate_text(text,target_lang="DE")print(without_glossary)# "Der Künstler wurde mit einem Preis ausgezeichnet."Using a stored glossary for document translation is the same: set theglossaryargument and specify thesource_langargument:translator.translate_document(in_file,out_file,source_lang="EN",target_lang="DE",glossary=my_glossary,)Thetranslate_document(),translate_document_from_filepath()andtranslate_document_upload()functions all support theglossaryargument.Checking account usageTo check account usage, use theget_usage()function.The returnedUsageobject contains three usage subtypes:character,documentandteam_document. Depending on your account type, some usage
subtypes may be invalid; this can be checked using thevalidproperty. For API
accounts:usage.character.validisTrue,usage.document.validandusage.team_document.validareFalse.Each usage subtype (if valid) hascountandlimitproperties giving the
amount used and maximum amount respectively, and thelimit_reachedproperty
that checks if the usage has reached the limit. The top levelUsageobject has
theany_limit_reachedproperty to check all usage subtypes.usage=translator.get_usage()ifusage.any_limit_reached:print('Translation limit reached.')ifusage.character.valid:print(f"Character usage:{usage.character.count}of{usage.character.limit}")ifusage.document.valid:print(f"Document usage:{usage.document.count}of{usage.document.limit}")Listing available languagesYou can request the list of languages supported by DeepL for text and documents
using theget_source_languages()andget_target_languages()functions. They
both return a list ofLanguageobjects.Thenameproperty gives the name of the language in English, and thecodeproperty gives the language code. Thesupports_formalityproperty only appears
for target languages, and indicates whether the target language supports the
optionalformalityparameter.print("Source languages:")forlanguageintranslator.get_source_languages():print(f"{language.name}({language.code})")# Example: "German (DE)"print("Target languages:")forlanguageintranslator.get_target_languages():iflanguage.supports_formality:print(f"{language.name}({language.code}) supports formality")# Example: "Italian (IT) supports formality"else:print(f"{language.name}({language.code})")# Example: "Lithuanian (LT)"Listing available glossary languagesGlossaries are supported for a subset of language pairs. To retrieve those
languages use theget_glossary_languages()function, which returns an array
ofGlossaryLanguagePairobjects. Each hassource_langandtarget_langproperties indicating that that pair of language codes is supported.glossary_languages=translator.get_glossary_languages()forlanguage_pairinglossary_languages:print(f"{language_pair.source_lang}to{language_pair.target_lang}")# Example: "EN to DE", "DE to EN", etc.You can also find the list of supported glossary language pairs in theAPI documentation.Note that glossaries work for all target regional-variants: a glossary for the
target language English ("EN") supports translations to both American English
("EN-US") and British English ("EN-GB").Writing a PluginIf you use this library in an application, please identify the application withdeepl.Translator.set_app_info, which needs the name and version of the app:translator=deepl.Translator(...).set_app_info("sample_python_plugin","1.0.2")This information is passed along when the library makes calls to the DeepL API.
Both name and version are required. Please note that setting theUser-Agentheader
viadeepl.http_client.user_agentwill override this setting, if you need to use this,
please manually identify your Application in theUser-Agentheader.ExceptionsAll module functions may raisedeepl.DeepLExceptionor one of its subclasses.
If invalid arguments are provided, they may raise the standard exceptionsValueErrorandTypeError.ConfigurationLoggingLogging can be enabled to see the HTTP requests sent and responses received by
the library. Enable and control logging using Python'sloggingmodule, for
example:importlogginglogging.basicConfig()logging.getLogger('deepl').setLevel(logging.DEBUG)Server URL configurationYou can override the URL of the DeepL API by specifying theserver_urlargument when constructing adeepl.Translator. This may be useful for testing
purposes. Youdo notneed to specify the URL to distinguish API Free and API
Pro accounts, the library selects the correct URL automatically.server_url="http://user:pass@localhost:3000"translator=deepl.Translator(...,server_url=server_url)Proxy configurationYou can configure a proxy by specifying theproxyargument when constructing adeepl.Translator:proxy="http://user:pass@10.10.1.10:3128"translator=deepl.Translator(...,proxy=proxy)The proxy argument is passed to the underlyingrequestssession, see thedocumentation for requests; a dictionary of schemes to
proxy URLs is also accepted.Override SSL verificationYou can control howrequestsperforms SSL verification by specifying theverify_ssloption when constructing adeepl.Translator, for example to
disable SSL certificate verification:translator=deepl.Translator(...,verify_ssl=False)This option is passed to the underlyingrequestssession as theverifyoption, see thedocumentation for requests.Anonymous platform informationBy default, we send some basic information about the platform the client library is running on with each request, seehere for an explanation. This data is completely anonymous and only used to improve our product, not track any individual users. If you do not wish to send this data, you can opt-out when creating yourdeepl.Translatorobject by setting thesend_platform_infoflag like so:translator=deepl.Translator(...,send_platform_info=False)You can also customize theuser_agentby setting its value explicitly before constructing yourdeepl.Translatorobject.deepl.http_client.user_agent='my custom user agent'translator=deepl.Translator(os.environ["DEEPL_AUTH_KEY"])Command Line InterfaceThe library can be run on the command line supporting all API functions. Use the--helpoption for usage information:python3-mdeepl--helpThe CLI requires your DeepL authentication key specified either as theDEEPL_AUTH_KEYenvironment variable, through thekeyringmodule, or
using the--auth-keyoption, for example:python3-mdeepl--auth-key=YOUR_AUTH_KEYusageNote that the--auth-keyargument must appearbeforethe command argument.
To use thekeyringmodule, set theDEEPL_AUTH_KEYfield in the servicedeeplto your API key.
The recognized commands are:CommandDescriptiontexttranslate text(s)documenttranslate document(s)usageprint usage information for the current billing periodlanguagesprint available languagesglossarycreate, list, and remove glossariesFor example, to translate text:python3-mdeepl--auth-key=YOUR_AUTH_KEYtext--to=DE"Text to be translated."Wrap text arguments in quotes to prevent the shell from splitting sentences into
words.IssuesIf you experience problems using the library, or would like to request a new
feature, please open anissue.DevelopmentWe welcome Pull Requests, please read thecontributing guidelines.TestsExecute the tests usingpytest. The tests communicate with the DeepL API using
the auth key defined by theDEEPL_AUTH_KEYenvironment variable.Be aware that the tests make DeepL API requests that contribute toward your API
usage.The test suite may instead be configured to communicate with the mock-server
provided bydeepl-mock. Although most test cases work for either,
some test cases work only with the DeepL API or the mock-server and will be
otherwise skipped. The test cases that require the mock-server trigger server
errors and test the client error-handling. To execute the tests using
deepl-mock, run it in another terminal while executing the tests. Execute the
tests usingpytestwith theDEEPL_MOCK_SERVER_PORTandDEEPL_SERVER_URLenvironment variables defined referring to the mock-server.