Coding tips
Backend development
Prototyping Python code
For quick prototyping or testing certain functionality, the Kadi shell can prove useful:
kadi shell
>>> app # Imported automatically
<Kadi 'kadi.app'>
>>> dir() # Get an overview of all automatically imported names
This shell is almost exactly the same as a regular interactive Python shell (or as the Flask shell), except that it ensures that a Flask application context is pushed automatically. Additionally, all database model classes and various other names are imported automatically.
Simulating sending emails
To simulate sending emails without using an actual SMTP server, the following command can be used to simply print the emails on the terminal instead using a debugging SMTP server:
kadi utils smtpd
The development configuration of Kadi4Mat already includes the correct values in order to make use of this debugging server, so no further changes should be necessary.
Adjusting or adding database models
For managing incremental changes to the database schema, potentially including existing data, Alembic is used via Flask-Migrate. These tools enable migration scripts to be generated, each script corresponding to the necessary database revisions, allowing another developer or system administrator to run the script and get the same changes in their database.
When adding a new model or adjusting an existing one, a new migration script has to be created to perform the necessary upgrades (see also migrations). To automatically generate such a script, the following command can be used:
kadi migrations migrate -m "Add some new table"
Note
When adding a new model, it needs to be imported somewhere in order for the tools to find it, as otherwise no changes might be detected. Furthermore, the current database schema always needs to be up to date in accordance to the latest migration script for the command to work.
The resulting code of the migration script should be checked and adjusted accordingly, as not all changes to the models may be detected automatically, such as new check constraints. Additionally, further steps may be necessary to migrate any existing data as well when adjusting existing models. Afterwards, the database can be upgraded by running the following command:
kadi migrations upgrade
When making further changes to a model after applying a newly generated migration script during development, it is usually best to recreate the script rather than creating another one. However, before deleting the old script, make sure to downgrade the database, as otherwise it may end up in an inconsistent state in regards to the revisions:
kadi migrations downgrade
Managing dependencies
All Python dependencies are currently specified via the pyproject.toml
file, which
lists all direct or major dependencies used in the project. All package versions are
pinned in order to ensure installations that are (mostly) deterministic. In order to
check for new package versions, the following helper script that is included in the
Kadi4Mat source code can be used:
${HOME}/workspace/kadi/bin/check_requirements.py
Especially in case of major updates, any updated dependencies should always be checked for potentially breaking changes beforehand and for any issues that may arise in the application after the update.
Frontend development
Writing frontend code
To process and package all frontend assets, including Vue.js single file components,
into individual JavaScript bundles runnable in a browser context, webpack is used. The main webpack configuration can be found in
webpack.config.js
, which defines the input and output of the different bundles. When
writing frontend code, it is necessary to run the following in a separate terminal:
kadi assets watch
This way, changes to existing files will be detected and the resulting output in
kadi/static/dist
will be rebuilt automatically. When adding new files, the command
might have to be restarted to pick them up, depending on which directory the files
reside in. See also assets and static.
Managing dependencies
All frontend dependencies are managed using npm, the package
manager of Node.js. The corresponding npm
command uses
the dependencies and configuration options as specified in the package.json
file, so
it must always be run somewhere inside the application’s root directory. Additionally, a
package-lock.json
file is generated automatically each time the package.json
file is updated by npm to ensure deterministic installations. In order to install a new
dependency, the following command can be used.
npm install <package>
This will add the new dependency to package.json
automatically. In order to check
all existing dependencies for updates, the following command can be used:
npm outdated
The outdated packages may be shown in different colors, depending on how each package is
specified in package.json
and on the magnitude of the update in accordance with
Semantic Versioning. To apply any updates, one of the following
commands can be used:
npm update # Automatically update all packages with compatible versions
npm install <package>@x.y.z # Install version x.y.z (e.g. a new major version) of a package
Especially in case of major updates, any updated dependencies should always be checked for potentially breaking changes beforehand and for any issues that may arise in the application after the update.
Security audits
npm offers built-in functionality to check all installed packages and subpackages for
known vulnerabilities. As sometimes certain vulnerabilities may not be relevant for
various reasons, e.g. false positives or the affected package is only used during
development, it is possible to ignore certain vulnerabilities using audit-ci via the audit-ci.json
file.
The modified security audit can then be run using the following command. Note that npm
needs access to the package.json
file, see also the section about managing
frontend dependencies.
npm run audit