Python Dev Environment Part 1: setup.py, venv, and pip
Tags: python
Published: 2020-07-22 10:54:20

While [Poetry] and similar tools are being utilized more and more, I sometimes find that my Python development needs are satisfied by built-in Python features.

The tools [venv] and [pip], and pip's cousin dependency [setuptools], are [usually included](https://pip.pypa.io/en/stable/installing/) in your Python distribution. Add a robust and well-documented Python test framework like [pytest], as introduced in [Part 2], and you are golden.

In this first article, we will set up a simple directory structure, write a Python module, configure the distribution package using `setup.py`, and install our new package in a virtual environment.

## Create a new directory

Create a new directory for the project. We'll call the directory `pygreet`. Now `cd` into that directory in your favorite terminal so that it is your current working directory.

## Create package directory

While a variety of ways to structure your distribution package exist, I like the approach of [placing Python code in a `src` directory](https://blog.ionelmc.ro/2014/05/25/python-packaging/).

So, let's create the `src` directory. Now your directory structure should look something like this:

```bash
pygreet/
└── src
```

## Write the code

Now let's edit greet.py:

```python
"""Functions useful for sending greetings."""

def greet(greeting="Hello", recipient="World"):
    """Greet someone."""
    return f"{greeting}, {recipient}"
```

Friendly. Flexible.

(This is a simple module. Want to make a more complex package with submodules, or still deciding which to do? You might enjoy reading [my article on Python modules and packages](https://dev.to/bowmanjd/python-module-vs-package-4m8e).)

## Define the distribution package in `setup.py`

Now we create the `setup.py` file to define the distribution package. Here is a basic one that should serve the needs of the moment:

```python
"""Package configuration."""
from setuptools import find_packages, setup

setup(
    name="pygreet",
    version="0.1",
    packages=find_packages(where="src"),
    package_dir={"": "src"},
)
```

Explicitly specifying the `src` directory is necessary, since we have our code in that location.

See the [Python Packaging Guide](https://packaging.python.org/tutorials/packaging-projects/) for more details about setup.py and packaging in general.

## Create and activate a Python virtual environment

Within the `pygreet` directory (or any other directory) use the following to set up a new virtual environment with the Python you specify and its own dependencies, etc.

```bash
python -m venv venv
```

To parse that out a bit more: use the Python executable you want to use in the virtual environment. That might be called `python`, as above, or it might be `python3` or `python3.8` or `python3.9`; you get the idea. Then tell it to execute the `venv` module, followed by the name of the directory in which you want the virtual environment to reside. As seen above, I usually use the name `venv`.

List the contents of your directory (using `ls` or `dir`) and you should see the new directory (likely named `venv`).

Now activate the virtual environment with

```bash
source ./venv/bin/activate
```

or, on Windows:

```powershell
.\venv\Scripts\Activate.ps1
```

If not using Bash or Powershell, you might look in the `./venv/bin` or `.\venv\Scripts` directory to see other options for CMD, fish, or csh.

## Install the new distribution package in the virtual environment

We can use [pip] to install the package. When a package is still under active development, I like to install with pip using ["editable mode"](https://pip.pypa.io/en/stable/reference/pip_install/#editable-installs). That way, I can make changes to the package and continue testing and development without needing to reinstall.

```bash
pip install -e .
```

Of course, if `pygreet` is not your current working directory (and you don't want it to be), then adjust the path. For instance, if you put `pygreet` in your `my_dev` directory in your home directory, then something like this may work for you: `pip install -e ~/my_dev/pygreet/`

Now, try it out:

```python
>>> import greet
>>> greet.greet()
'Hello, World'
```

If the above works, then you have built and installed a Python distribution package!

See [Part 2] for adding tests with pytest.

[Poetry]: https://python-poetry.org/
[pip]: https://pip.pypa.io/
[venv]: https://docs.python.org/3/library/venv.html
[setuptools]: https://pypi.org/project/setuptools/
[pytest]: https://docs.pytest.org/
[Part 2]: https://dev.to/bowmanjd/python-dev-environment-part-2-testing-with-pytest-5a1h