Development Quickstart¶
Setup¶
Your global python version should be at least 3.14.
If necessary you can install it via the deadsnakes ppa.
Make sure to also install the python-dev version!
First install the packages required for the build environment, on debian based distros:
sudo apt-get -y update && apt-get -y install build-essential gettext default-mysql-client libmariadb-dev pkg-config
and on redhat distros:
sudo dnf -y update && dnf -y install gcc gettext mysql-devel pkgconf npx
For some linters you need npm installed, follow the installation guide from their documentation.
Then to install the python dependencies start a new virtual environment and activate it:
Poetry is used to manage the python dependencies of this project.
pip install pipx
pipx install poetry
pipx inject poetry poetry-pre-commit-plugin
You can then add the tab completions for it by:
poetry completions bash >> ~/.bash_completion
Then install all the dependencies to a virtual environment:
poetry install --with dev
Finally you can activate the venv with
poetry run poe venv
You should avoid having the venv inside the workspace as that will brick docker run in most cases.
Depending on your OS, the mysqlclient package may cause problems, this can usually be solved by installing a missing system package.
Testing¶
Linting¶
There are various tools set up for linting and formatting this projects codebase and documentation. The easiest way to run them is via the poe task runner.
poe lint
To enable the gitlab-ci validation, create a .netrc file with permissions 660 in your personal folder. Add the line
machine gitlab.com password <yourapitoken>
Unittests¶
The projects tests are in the test/ directory. You can run them from the project root with
pytest test
Debug build¶
If you want to test your changes manually, you can build the docker image
docker build -f docker/Dockerfile . -t eonvelope-debug
and run it with the docker-compose.debug.yml.
docker compose -f docker/docker-compose.debug.yml up -d
In debug mode, the container uses djangos runserver instead of gunicorn, allowing you to manipulate the source and static files while the server is running, e.g. via docker exec. Additionally, all internal errors will surface as error webpages with full context of the error and the django-debug toolbar will be shown on webpages. For direct database access, you can go to port 9999, where the adminer service of the stack is available. To surveil the celery tasks, there is also a flower service running and available under port 5555.
To test the webui on other devices, like your phone or tablet, add your machines IP to ALLOWED_HOSTS and you will be able to access the debug application from other devices as well.
Validation and Linting¶
You can use the tools in tools/ to lint and check your changes.
The code is formatted using black formatter.
The imports are sorted with ruffs isort.
There are preconfigured githooks in tools/githooks that format, check and lint the code before every commit. Set them for your local repository via
git config core.hooksPath tools/githooks/
Workspace Recommendations¶
VSCodium / VSCode¶
Settings¶
Trim final newlines
"files.trimFinalNewlines": true,
Trim trailing whitespace
"files.trimTrailingWhitespace": true,
Insert final newline
"files.insertFinalNewline": true,
Disable html autoformatting, it messes up django templates on a regular basis
"html.format.enable": false
Extensions¶
everything for python and django
python test, with config
"python.testing.cwd": "/path/to/repo/test/"
ruff, with config
"ruff.configuration": "tools/ruff.toml"
pylint, with config
"pylint.args": ["--rcfile=tools/pylintrc_extension"]
mypy, with config
"mypy-type-checker.args": ["--config-file=tools/mypy.ini"]
black, with config
"black-formatter.args": ["--config=tools/black_config"]
python poetry
ANSI colors (iliazeus.vscode-ansi) (for reports)
reStructuredText (lextudio.restructuredtext) for docs, with config
"restructuredtext.linter.doc8.extraArgs": ["--config tools/doc8.ini"]
bootstrap 5 intellisense etc.
Zed¶
python config:
"Python": {
"formatter": {
"external": {
"command": "black",
"arguments": [
"-",
"--config",
"tools/black_config",
"--stdin-filename",
"{buffer_path}",
],
},
},
"format_on_save": "on",
}
use djlint for HTML autoformatting:
"HTML": {
"format_on_save": "on",
"formatter": {
"external": {
"command": "djlint",
"arguments": [
"-",
"--reformat",
"--configuration",
"tools/djlintrc",
"{buffer_path}",
],
},
},
},
find poetry venvs
"terminal": {
"detect_venv": {
"on": {
"directories": [
".env",
"env",
".venv",
"venv",
"/home/david/.cache/pypoetry/virtualenvs/",
],
"activate_script": "default",
},
},
}
ruff lsp:
"lsp": {
"ruff": {
"initialization_options": {
"settings": {
"configuration": "tools/ruff.toml",
},
},
},
}
markdown formatting
"Markdown": {
"remove_trailing_whitespace_on_save": true
}
js:
"lsp": {
"biome": {
"settings": {
"config_path": "<path>/biome.json"
}
}
}
}
and
"languages":{
"JavaScript": { "formatter": { "language_server": { "name": "biome" } } },
}