Part of the greater e-mission project.
This library contains code used by multiple e-mission components including e-mission-server, e-mission-phone, em-public-dashboard, and op-admin-dashboard.
This repository uses the Transcrypt library to compile Python code to JavaScript. This allows us to write and maintain code in 1 language and import it for use in all 4 of the above repos.
. bin/setup.shThis will:
- Retrieve setup scripts from
e-mission-serverand use them to set up a conda environment calledemcommonwith the dependencies listed inbin/environment.ymlThis way, theemcommonenvironment uses the same Python version ase-mission-server. - Run
npm install.
Re-run this if you change the dependencies in environment.yml or package.json.
- Make your changes to Python code under the
srcdirectory. - Run
bash bin/compile_to_js.shto build the JavaScript. This will produce output JS files in theemcommon_jsdirectory. - Commit changes from both the
srcandemcommon_jsdirectories to your branch.
-
Use the
emcommon.loggermodule for all logs; it is set up to work in both languages.import emcommon.logger as Log
-
When you need to run a snippet in Python but not in JavaScript, you can use the
skippragma to skip one line or multiple lines.Log.info("This line executes in both Python and JavaScript") Log.info("But this line only executes in in Python") # __: skip # __pragma__('skip') Log.info("This whole block of lines only executes in Python") Log.info("JS ignores anything between the skip and noskip pragma comments") # __pragma__('noskip') Log.info("This line is back to executing in both Python and JavaScript")
-
When you need to run something in JavaScript but not in Python, you can use an "executable comment", which starts with
'''?and ends with?'''.Log.info("This line executes in both Python and JavaScript") '''? Log.info("This only executes in JavaScript") Log.info("The Transcrypt compiler will convert this to JavaScript code") Log.info("But regular Python will just see it as a comment and ignore it") ?'''
-
If you need to insert raw JavaScript code, you can use the
jspragma.Log.info("This is Python code that executes in both Python and JavaScript") # __pragma__('js', '{}', 'alert("This is raw JavaScript code that executes in JavaScript")')
If you need multiple lines of raw JavaScript, you can wrap the
jspragma in an "executable comment".'''? __pragma__('js', '{}', """ let msg = "This is raw JavaScript code that executes in JavaScript"; msg += ", and it can be multiple lines"; alert(msg); """) ?'''
For more detail, refer to the Transcrypt docs on the many kinds of pragmas available.
To test local changes:
- Make your local changes in the
src/directory. - From your other repo, run
pip install -e <path_to_this_repo>to use the local version of e-mission-common.
To use a remote branch or tag in your Python project:
-
Use
pip install git+https://github.com/e-mission/e-mission-common@master-OR-
-
List
git+https://github.com/e-mission/e-mission-common@masterin anenvironment.yml
To test local changes:
- Make your local changes in the
src/directory. - Run
bash bin/compile_to_js.shto build the JavaScript. - From this repo, run
npm linkto establish a symlink to your local version of e-mission-common. - From the other repo, run
npm link e-mission-commonto use the symlinked version of this repo.
To use a remote branch or tag in your JavaScript project:
- Add
"e-mission-common": "github:e-mission/e-mission-common#master"to yourdependenciesinpackage.json.
Due to the nature of this library, it is critical to test both the Python source and the compiled JavaScript. Ideally, we can write a test suite in a .py file and have it run in both Python and JavaScript environments.
This is possible, to a degree, using transcrypt to compile test files to JavaScript, and then running jest on the compiled JavaScript.
pytestwas chosen overunittestbecause it is more flexible, allowing tests to be written in a way that can be compiled to Jest-compatible JavaScript. (It is also more concise and friendly to write.)
See the tests directory for .py files that are not accompanied by a .js file. These files are intended to be run in both Python and JavaScript environments.
There may be testing scenarios that must significantly diverge between Python and JavaScript versions. In these cases, we can write a separate .js file next to the .py file of the same name. In this case, no compilation is necessary; pytest will run the .py file and jest will run the .js.
. bin/run_pytest.sh. bin/run_jest.shThe unit tests also run via an Actions workflow, which executes both run_pytest.sh and run_jest.sh on each commit or PR to master.