ALERT
Virtual environments are not necessary, but are frequently considered a best practice when handling multiple Python projects.
$ workon QlikSenseAAI
Now, ensuring you are in the ‘QlikSenseAAI’ folder that you created (if you have followed another guide, it might redirect you to a prior working directory if you've set a default, execute the following commands to create and navigate into your project’s folder structure:
$ cd QlikSenseAAI
$ mkdir Translate
$ cd Translate
Optionally, you can bind the current working directory as the virtual environment’s default. Execute (Note the period!):
$ setprojectdir .
We have now set the stage for our environment. To navigate back into this project in the future, simply execute:
$ workon QlikSenseAAI
This will take you back into the environment with the default directory that we set above. To change the directory for future projects within the same environment, change your directory to the desired path and reset the working directory with ‘setprojectdir .’
$ workon QlikSenseAAI
Note that we cannot use the googletrans library in the interim as Google has changed the way they send tokens, which has broken the repo. Updated install below 10.29.18.
$ pip install grpcio
$ python -m pip install grpcio-tools
$ git clone https://github.com/BoseCorp/py-googletrans.git
$ cd ./py-googletrans
$ python setup.py install
$ pip install hyper
$ python __main__.py
Example function calls:
Translate text from English to Japense:
PythonTranslate.Translate(text,’en’,’ja’)
Translate text from German to English:
PythonTranslate.Translate(text,’de’,’en’)
There is another script function exposed called TranslateScript(). This function can only be used in the script and is leveraged via the LOAD ... EXTENSION ... mechanism which was added as of the February 2018 release of Qlik Sense. This function takes four fields:
text, a numeric id, source language, destination language
See the below example of how to utilize the TranslateScript() function in the load script.
*Note that if you are using QlikView and cannot use the TranslateScript() function, you can still use the Translate() function in the script just like any other native function--just be aware that this will operate as a scalar function and will be called record-by-record vs a single time. This will have a large performance impact but will still work.
Data:
FIRST 10
LOAD
business_id,
"date",
RecNo() AS review_id,
stars,
"text",
"type",
user_id,
cool,
useful,
funny,
'en' AS English,
'ja' AS Japanese,
'tr' AS Turkish,
'sv' AS Swedish,
'ru' AS Russian,
'fr' AS French,
'ar' AS Arabic
FROM [lib://Builds (qlik_qservice)/TranslationData\yelp.csv]
(txt, utf8, embedded labels, delimiter is ',', msq);
// PYTHON
Japanese:
LOAD
Field1 AS review_id,
Field2 AS "Translated Text (Japanese)"
EXTENSION PythonTranslate.TranslateScript(Data{text,"review_id",English,Japanese});
Turkish:
LOAD
Field1 AS review_id,
Field2 AS "Translated Text (Turkish)"
EXTENSION PythonTranslate.TranslateScript(Data{text,"review_id",English,Turkish});
DROP FIELDS English, Japanese, Turkish;
The core concept is that translation can be done in the script and physically loaded into the model, or done dynamically on the front-end. You could implement section access so that a user only has access to a single language code, and then have that language code automatically fill in the “destination” argument of the function, thereby applying custom real-time translation per user without any data loaded.
The two-letter codes below are what are accepted as the “source” and “destination” arguments for both Python functions"
LANGUAGES = {
'af': 'afrikaans',
'sq': 'albanian',
'am': 'amharic',
'ar': 'arabic',
'hy': 'armenian',
'az': 'azerbaijani',
'eu': 'basque',
'be': 'belarusian',
'bn': 'bengali',
'bs': 'bosnian',
'bg': 'bulgarian',
'ca': 'catalan',
'ceb': 'cebuano',
'ny': 'chichewa',
'zh-cn': 'chinese (simplified)',
'zh-tw': 'chinese (traditional)',
'co': 'corsican',
'hr': 'croatian',
'cs': 'czech',
'da': 'danish',
'nl': 'dutch',
'en': 'english',
'eo': 'esperanto',
'et': 'estonian',
'tl': 'filipino',
'fi': 'finnish',
'fr': 'french',
'fy': 'frisian',
'gl': 'galician',
'ka': 'georgian',
'de': 'german',
'el': 'greek',
'gu': 'gujarati',
'ht': 'haitian creole',
'ha': 'hausa',
'haw': 'hawaiian',
'iw': 'hebrew',
'hi': 'hindi',
'hmn': 'hmong',
'hu': 'hungarian',
'is': 'icelandic',
'ig': 'igbo',
'id': 'indonesian',
'ga': 'irish',
'it': 'italian',
'ja': 'japanese',
'jw': 'javanese',
'kn': 'kannada',
'kk': 'kazakh',
'km': 'khmer',
'ko': 'korean',
'ku': 'kurdish (kurmanji)',
'ky': 'kyrgyz',
'lo': 'lao',
'la': 'latin',
'lv': 'latvian',
'lt': 'lithuanian',
'lb': 'luxembourgish',
'mk': 'macedonian',
'mg': 'malagasy',
'ms': 'malay',
'ml': 'malayalam',
'mt': 'maltese',
'mi': 'maori',
'mr': 'marathi',
'mn': 'mongolian',
'my': 'myanmar (burmese)',
'ne': 'nepali',
'no': 'norwegian',
'ps': 'pashto',
'fa': 'persian',
'pl': 'polish',
'pt': 'portuguese',
'pa': 'punjabi',
'ro': 'romanian',
'ru': 'russian',
'sm': 'samoan',
'gd': 'scots gaelic',
'sr': 'serbian',
'st': 'sesotho',
'sn': 'shona',
'sd': 'sindhi',
'si': 'sinhala',
'sk': 'slovak',
'sl': 'slovenian',
'so': 'somali',
'es': 'spanish',
'su': 'sundanese',
'sw': 'swahili',
'sv': 'swedish',
'tg': 'tajik',
'ta': 'tamil',
'te': 'telugu',
'th': 'thai',
'tr': 'turkish',
'uk': 'ukrainian',
'ur': 'urdu',
'uz': 'uzbek',
'vi': 'vietnamese',
'cy': 'welsh',
'xh': 'xhosa',
'yi': 'yiddish',
'yo': 'yoruba',
'zu': 'zulu'
}
Using NSSM is my personal favorite way to turn a Python SSE into a Windows Service. You will want to run your SSEs as services so that they startup automatically and run in the background.
Example: