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" } } },
}