Detecting document language
Routing a document often starts with one question: what language is it in? An incoming invoice in German goes to one queue, the same form in Japanese to another — and the OCR step downstream needs the right language before it can read a single word. Language detection answers that question up front, per page, without sending anything to a server.
This sample shows how to detect the language and text direction of a document using Nutrient Python SDK. Detection runs fully offline — no network, no API keys.
Download sampleHow Nutrient helps
Nutrient Python SDK runs the full offline detection pipeline behind a single method call. The SDK handles:
- Rendering each page to a bitmap
- Identifying the writing script(s) present on the page (Latin, Cyrillic, Arabic, Han, and so on)
- Reading the page’s text in the full repertoire of those scripts, preserving diacritics and tone marks
- Identifying the specific language(s) in that text — distinguishing, for example, French from Spanish within the Latin script
- Serializing the per-page result to JSON
The result is a predicted language plus a per-page breakdown, each with its detected language(s) and text direction.
How detection works
For each page, the SDK first determines which writing scripts are present, then reads the page’s text and identifies the language. Languages are reported as ISO 639-2 three-letter codes (eng, fra, rus, vie). Right-to-left scripts (Arabic, Hebrew) report a rltb text direction; everything else reports lrtb.
Detection runs fully offline; resources for non-Latin scripts are fetched once on first use. Language detection requires the OCR feature in your license.
Detecting multiple languages and scripts
By default, detection reports the single dominant script and language of each page — the fastest path and the right choice for single-language documents. Documents that mix scripts (Cyrillic and Han on the same page) or mix languages within one script (English and French) need detection to consider more than one, so the sample raises two OCR settings before detecting:
max_scriptsbounds how many distinct writing scripts a page is read in.max_languagesbounds how many languages are reported.
Both default to 1. With them raised, each page’s detected languages list contains every language found, ordered most-prominent first.
Multi-page documents
Every page is detected independently and reported in its own entry, so a document whose pages are in different languages surfaces each page’s language rather than collapsing to one. The top-level predictedLanguage is the first page’s language, a convenient default for single-language documents.
Complete implementation
Import the classes used in the sample:
from nutrient_sdk import Document, Vision, NutrientExceptionDetecting a document’s language
Open the document in a context manager(opens in a new tab) so resources are cleaned up after processing, raise the script and language caps, create a vision instance bound to it with Vision.set(document), then call detect_languages():
def main(): try: with Document.open("input_ocr_multiple_languages.png") as document: # Read each page in up to two scripts and report up to two languages. document.settings.ocr_settings.max_scripts = 2 document.settings.ocr_settings.max_languages = 2
vision = Vision.set(document) result_json = vision.detect_languages()
with open("output.json", "w") as f: f.write(result_json) except NutrientException as e: print(f"Error: {e}")
if __name__ == "__main__": main()Understanding the output
detect_languages() returns JSON with a top-level languageDetection object:
predictedLanguage— The primary detected language as an ISO 639-2 code. For a document, this is the first page’s language.textDirection— The primary text direction (lrtbleft-to-right,rltbright-to-left).pages— One entry per page, each with itspageNumber, detectedlanguages, andtextDirection.
{ "languageDetection": { "predictedLanguage": "fra", "textDirection": "lrtb", "pages": [ { "pageNumber": 1, "languages": ["fra"], "textDirection": "lrtb" } ] }}Detecting the language of text you already have
When you already have the text — an email body, a database field, your own extraction pipeline — and no file to open, skip the document entirely and call the static Vision.detect_languages_text("…"). Nothing is opened or rendered; the text is scored directly, and the result has the same shape with an empty pages array:
{ "languageDetection": { "predictedLanguage": "rus", "textDirection": "lrtb", "pages": [] }}Error handling
Vision API raises VisionException (a NutrientException) when detection fails. Common failure scenarios include:
- The document can’t be read due to path or permission issues
- A script model is missing or inaccessible, or the OCR feature isn’t licensed
- No document and no text were supplied (detection has nothing to work on)
In production code:
- Catch
NutrientException. - Return a clear error message.
- Log failure details for debugging.
Conclusion
The workflow for offline language detection is:
- Open the source document using a context manager(opens in a new tab) for automatic resource cleanup.
- Raise
max_scripts/max_languageswhen a page mixes scripts or languages. - Create a vision instance with
Vision.set()and calldetect_languages()to detect every page and export the result as JSON (or call the staticVision.detect_languages_text()for text you already have). - Write the JSON to a file for routing or downstream processing.
- Handle
NutrientExceptionfor robust error recovery.
For related extraction workflows, refer to the Python SDK guides.
Download this ready-to-use sample package to explore language detection.