Getting Started
Quickstart
The following steps should get you quickly set up. You find more detailed instructions in the rest of this document.
The recommended development environment is Linux.
Clone the repository from Github.
Activate a virtual environment and run
pip install -r requirements-dev.txtto install the dependencies.Set the following environment variables in the terminal:
export FLASK_APP=dev.development_server
export WOCO_SERVER_NAME=127.0.0.1:5000
export DEV_SECRET_KEY="my_secret_key"
export WOCO_TEST_DB=sqlite:///${PWD}/workers_control_test.db
export WOCO_DEV_DB=sqlite:///${PWD}/workers_control_dev.db
Run
pytestto run the testsuite.Run
python -m build_support.translations compile(only if you need translations in the development app)Run
flask run --debugto start the development app.
Database Setup
We support both PostgreSQL and SQLite databases for testing, development and production. In testing and development, by default, two SQLite databases are created automatically in the project’s root directory when starting tests or the development server. No manual setup is necessary.
You may use your own databases by setting the environment variables
WOCO_DEV_DB and/or WOCO_TEST_DB to point to
databases of your choice. See Environment Variables for details.
Virtual Environment via Nix
You may use Nix as package manager and virtual environment. While this is NOT obligatory and you may use venv and pip instead (see below), it is indeed needed for the specific task of changing or updating dependencies (see Update Dependencies).
If you are working with Nix, go to the top-level directory of the repo
and enter nix develop at the command prompt. This will cause Nix to
read the dependency description in nix.flake and fulfill those
dependencies in a local virtual environment. You can quit the
virtual environment by typing exit at the command prompt.
Using Nix will give you the option to access a development environment with any of the supported
python versions via nix develop. Check flake.nix for the
supported environments under the key devShells. For example to
enter a development shell with python3.12 set as the default
interpreter run nix develop .#python312. This will drop you into a
shell with python3.12 as the default python interpreter. This won’t
change anything else on your machine and the respective python
interpreter will be garbage collected the next time you run
nix-collect-garbage.
When working with Nix, you may add the line use flake
at the top of an .envrc file in the top-level directory of the repo.
When you have Direnv installed, this will automatically invoke Nix and install
all dependencies in the virtual environment every time you enter the root code directory.
For the line use flake to have effect you might need to install nix-direnv.
A note for Mac users: By default, during Nix installation, commands are added to configure path and environment variables within scripts located in the global /etc directory. However, macOS updates can overwrite these scripts, leading to Nix becoming inaccessible. To address this issue, consider adding the following command to your ~/.zshrc file:
# Nix if [ -e '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh' ]; then source '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh' fi # End Nixsee https://github.com/NixOs/nix/issues/3616 for more details.
Virtual Environment via Venv
If you decide to use venv
instead of Nix, create a virtual environment
with python -m venv venv.
Then, to execute the virtual environment source ./venv/bin/activate.
Within the venv environment, install all required packages:
pip install -r requirements-dev.txt. You can deactivate the
virtual environment by typing deactivate at the command prompt.
Environment Variables
Before you can start developing, you first have to define some environment variables. We recommend that you define these in an .envrc file in the top-level directory of the repo, and install direnv to automatically load these variables when you enter the top-level directory of the repo.
Database URIs should be in the form
used by SQLAlchemy: dialect[+driver]://user:password@host:port/database[?options].
Commented out variables are optional.
export FLASK_APP=dev.development_server
export WOCO_SERVER_NAME=127.0.0.1:5000
export DEV_SECRET_KEY="my_secret_key"
export WOCO_TEST_DB=sqlite:///${PWD}/workers_control_test.db
export WOCO_DEV_DB=sqlite:///${PWD}/workers_control_dev.db
# export ALLOWED_OVERDRAW_MEMBER=1000
# export DEFAULT_USER_TIMEZONE="Europe/Berlin"
# export AUTO_MIGRATE=true
Development server
You can start a development app on your local machine to test your
latest changes with the command flask run --debug.
Note the following features of the development app:
There are several CLI commands to perform automated actions against the development database (create companies, file plans, register consumption, etc.). Run
flask --helpto see the available options.When manually filing plans, you need at least one accountant to approve them. Invite accountants from the terminal, using the command
flask invite-accountant example@mail.de.Confirmation emails (e.g., for user account creation) are printed to
stdout(your terminal). Click the confirmation links shown there.The app uses the configured development database. You can manually upgrade or downgrade the development database. Run
flask db --helpto see the options. If the environment variableAUTO_MIGRATEis set totrue, the database will automatically be upgraded when the development server starts.
Code Formatting and Analysis
Run ./format_code.py to format Python files automatically.
The script uses black and
isort. Currently, the script applies automatic
formatting to a limited selection of paths. You can add more paths by
adding lines to .autoformattingrc.
We use type hints. You can check the consistency of the type hints
via the mypy command. Furthermore flake8 is employed to
prevent certain mistakes, such as unused imports or
uninitialized variables. Invoke both commands without arguments to
test all the eligible code.
Testing
You can run the tests by executing pytest in the root folder
of this project.
You are encouraged to use the ./run-checks command before you
submit changes in a pull request. This program runs several
checks and the test suite.
If you have chosen to use a nix environment, the command nix flake check will test
the app against both databases, several python and nixpkgs versions. This command
is run as part of our CI Tests on Github, as well.
You can run only the tests for the part of the application on which you are working. For example, if you are working on the business logic, you can use the following command to quickly run all the interactor tests:
pytest tests/interactors
It is possible to disable tests that require a database to run via an environment variable:
DISABLED_TESTS="database_required" pytest
You can generate a code coverage report at htmlcov/index.html via
the command:
coverage run -m pytest && coverage html
Profiling
This project uses flask_profiler to provided a very basic
graphical user interface for response times. You can access this interface
at /profiling in the development server.
Documentation
To generate the developer documentation, run from the root folder of the project:
make clean
make html
Open the documentation in your
browser at build/html/index.html. The HTML code is generated from
documentation files in the docs folder.
The docs are hosted on Read the Docs and are automatically updated when changes are pushed to the master branch.
Benchmarking
Included in the source code for this project is a rudimentary
framework for testing the running time of our code.
You can run all the benchmarks via
python -m dev.benchmark.
This benchmarking tool can be
used to compare runtime characteristics across changes to the codebase.
A contributor to the workers control app might want to compare
the results of those benchmarks from the master branch to the results
from their changes. The output of this tool is in JSON.
Using a Binary Cache for Nix
You can access the binary cache hosted on cachix in your development environment if you are using Nix to manage your development environment. The binary cache is called “arbeitszeit”. Check the cachix docs on how to set this up locally. The benefit of this for you is that you can avoid building dependencies that are already built once in the continuous integration (CI) pipeline.