New Project Setup
=================
This guideline shows how to set up a standard Python project. It features, how
to structure the project and installing helping packages.
.. _project_dev_packages_overview:
Used packages :footcite:p:`popular_python_project_tools`
--------------------------------------------------------
.. csv-table:: Essential project tools
:file: _file/project_tools.csv
:header-rows: 1
:widths: auto
\* optional
Create project structure
------------------------
`Cookiecutter `__ creates a
project structure based on predefined templates. This saves you the effort of
manually adding various files and folder structures.
Because you need *cookiecutter* only once, at the beginning of your project, it
is recommended to install it outside of your :ref:`project's virtual environment `.
Cookiecutter installation
`````````````````````````
A recommendation is to make both tools globally available using
`pipx `_.
The installation only must be done once (afterwards you can use *cookiecutter*
command from anywhere).
First, let's create a virtual environment for *pipx* (here: via *pyenv*):
.. note::
The must not be the same as the future project's interpreter.
Choose the latest version, which both *cookiecutter and *pipx* itself support:
* `pipx `__
* `cookiecutter `__
.. code-block:: bash
$ pyenv virtualenv pipx
Activate the environment:
.. code-block:: bash
$ pyenv activate pipx
Next, let's install pipx:
.. code-block:: bash
(pipx) $ pip install pipx
Now, we have to ensure that the packages installed via pipx are added to our PATH
variable. This ensures that those are executable from anywhere (only must to be done once):
.. code-block:: bash
(pipx) $ pipx ensurepath
Now we're ready to install cookiecutter & pip-tools in it:
.. code-block:: bash
(pipx) pipx install cookiecutter
Open a new terminal window and run ``cookiecutter -V``, which should print the
installed cookiecutter package's version.
Adjust cookiecutter template
````````````````````````````
First you must select a template, from which to generate your project structure.
Browse https://github.com/search?q=cookiecutter&type=Repositories to find the best match
for the technology, you want to use.
A general purpose template from the original author of cookiecutter is
https://github.com/audreyfeldroy/cookiecutter-pypackage. Follow the instructions on
https://cookiecutter.readthedocs.io/en/1.7.2/usage.html#usage to clone the template and
make adaptions on ``cookiecutter.json``.
There is already an adapted version of this template available at
https://github.com/arnewohletz/my-cookiecutter-pypackage, which we use in
this tutorial.
The template sets up a `makefile `_, which
features commands for
* building distribution & documentation (as well as link checks)
* executing tests (regular & code coverage)
* linting code
* static type check
* installing the package (into your active Python environment)
* cleaning, build, test, determine test coverage of Python artifacts
and more.
Create project
``````````````
Now we're ready to create the project based on our slightly adapted template:
.. code-block:: bash
$ cd /my/project/root/dir
$ cookiecutter /path/to/cookiecutter/template/root/dir
For example:
.. code-block:: bash
$ mkdir ~/best_practice_project
$ cd ~/best_practice_project
$ cookiecutter ~/my_templates/cookiecutter-pypackage
Define your project parameters in the wizard.
.. _setup_virtual_environment:
Create your project's virtual environment
-----------------------------------------
We recommended to create a virtual environment using ``pyenv ``
(with the pyenv-virtualenv extensions).
Create virtual environment via:
.. code-block:: bash
$ pyenv virtualenv
Alternatively, use may use Python's built-in `venv `_
via
.. code-block:: bash
$ python -m venv
It uses the venv module and creates a virtual environment named inside
your current directory (you may also specify an absolute path).
As a second alternative, the module `virtualenv `_ can
also be used. Although, it has to be installed into the Python environment (from which to
create the virtual environment from) first:
.. code-block:: bash
$ pip install virtualenv
$ virtualenv
Same as for Python's built in *venv* module, it creates a virtual environment in your
current directory.
A major difference of *virtualenv* is that its created environment is autonomous of its
originating interpreter. The virtual environment from *venv* and *pyenv* require
resources from the original interpreter (Pro: they are smaller).
Install dependencies
````````````````````
First, install `pip-tools `_, which we use
to manage our dependencies (activate your project's virtual environment first):
.. code-block:: bash
(project_venv) $ pip install pip-tools
.. important::
*pip-tools* must be installed into the project's virtual environment. You must
not use a pip-tools installation from a different environment (e.g. from a
*pipx* installation), because ``pip-sync`` installs into the environment it
is called from.
Run ``pip-compile --version`` and ``pip-sync --version`` to verify the installation success.
All requirements for development as mentioned in the :ref:`overview table `
are already listed in ``requirements-dev.in``. To create a ``requirements-dev.txt``,
execute:
.. code-block:: bash
(project_venv) $ pip-compile requirements-dev.in -o requirements-dev.txt
This produces the \*.txt file containing our dependencies plus all required
packages for those dependencies (all using pinned versions). To install all these
dependencies, execute:
.. code-block:: bash
(project_venv) $ pip-sync requirements-dev.txt
.. hint::
All dependencies which are required to **execute** our project are gathered
in ``requirements.in``. Same workflow here:
.. code-block:: bash
(project_venv) $ pip-compile requirements.in -o requirements.txt
(project_venv) $ pip-sync requirements.txt
.. footbibliography::