Table of contents
I like to try out new technologies and programming languages, and one of the first blockers I face is how to start a project. I absolutely love the way you can start a NodeJS project with
npm init. You can do something similar with Python.
In this article, you’ll learn how to start a Python project assuring that its dependencies won’t interfere with other projects' dependencies. And how to use Make to distribute your project to be easily installed in other development machines in no time.
Check your versions
First, check your versions. I’m working with Python 3.10, but this will work with any version of Python 3.
λ python --version Python 3.10.8
Creating the virtual environment
First, create a folder to store your project.
mkdir ~/Development/python-starter-example cd ~/Development/python-starter-example
Now, you need to create “the project” itself, aka the virtual environment. The
venv module allows you to have all the dependencies and configuration for your Python project inside the project directory, something like NodeJS projects having all the dependencies in
node_modules. Let’s do this.
cd ~/Development/python-starter-example python -m venv env
Working with the virtual environment
Now, the environment is created, but we need to go “inside”, by activating it:
Every time you go back to the project directory, you’ll need to activate it.
How I know that I’m inside the environment?
Easy-peasy: You’ll see a little
(env) text in the prompt of your terminal.
Now, every Python command you run inside the environment will be executed in that context, so, if you install a Python library, it won’t interfere with other versions of that library from other python projects.
Flask, for example:
# (env) => we are inside the environment pip install flask
The moment of truth: let’s check that
Flask was installed inside the environment.
~/Development/python-starter-example env λ ls env/lib/python3.10/site-packages/flask __init__.py app.py config.py globals.py logging.py sessions.py testing.py wrappers.py __main__.py blueprints.py ctx.py helpers.py py.typed signals.py typing.py __pycache__ cli.py debughelpers.py json scaffold.py templating.py views.py
So it’s there! But.. what about the Flask binary? Remember that some Python libraries come with a binary you need to execute sometimes. Those binaries will be under the
env/bin folder inside your project. See:
~/Development/python-starter-example env λ ls env/bin Activate.ps1 activate.csh flask pip3 python python3.10 activate activate.fish pip pip3.10 python3
Running the project
Let’s use the example
Flask application from its documentation. Create a file called
app.py in the project and edit it:
from flask import Flask app = Flask(__name__) @app.route("/") def hello_world(): return "<p>Hello, World!</p>"
Now, run it. Remember that the project need to use the
Flask version under the environment:
env/bin/flask --app app run * Serving Flask app 'app' * Debug mode: off WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. * Running on http://127.0.0.1:5000 Press CTRL+C to quit 127.0.0.1 - - [22/Jan/2023 13:12:24] "GET / HTTP/1.1" 200 - 127.0.0.1 - - [22/Jan/2023 13:12:24] "GET /favicon.ico HTTP/1.1" 404 -
You could also run it directly using the
python command. You just need to tweak the code a little.
import os from flask import Flask app = Flask(__name__) @app.route("/") def hello_world(): return "<p>Hello, World!</p>" if __name__ == '__main__': port = int(os.environ.get('PORT', 3000)) app.run(host='127.0.0.1', port=port)
Now you can run it with the
~/Development/python-starter-example 10s env λ python app.py * Serving Flask app 'app' * Debug mode: off WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. * Running on http://127.0.0.1:3000 Press CTRL+C to quit 127.0.0.1 - - [22/Jan/2023 13:16:37] "GET / HTTP/1.1" 200 - 127.0.0.1 - - [22/Jan/2023 13:16:38] "GET /favicon.ico HTTP/1.1" 404 -
Create the requirements file
If you want to distribute your project with the rest of your team, or in a git repository, you need to create the
requirements.txt file that will contain all the dependencies that your project’s using. Since you installed everything using
pip, the easiest way of creating this file is using the
pip freeze command.
pip freeze > requirements.txt
Now you have your requirements file - something like this:
~/Development/python-starter-example env λ cat requirements.txt click==8.1.3 Flask==2.2.2 itsdangerous==2.1.2 Jinja2==3.1.2 MarkupSafe==2.1.2 Werkzeug==2.2.2
Now that the dependencies are documented in the
requirements.txt file, anyone can install them with a simple
pip install -r requirements.txt
Creating an application runner with Make
Now, let’s automatize it. What if we could create a way of automatically create the virtual env with everything installed in it? I like doing this with
Make. Create a file called
Makefile inside the project directory and start with this:
.PHONY: all env/bin/activate: requirements.txt python -m venv env ./env/bin/pip install -r requirements.txt run: env/bin/activate ./env/bin/python app.py freeze: env/bin/pip ./env/bin/pip freeze > requirements.txt clean: rm -rf __pycache__ rm -rf ./env
Let’s break down this
Makefile. It has three commands:
run: will run the
app.pyPython file if the
venvis active. If it’s not it will create the virtual environment and install its dependencies. If no
requirements.txtfile is found, then nothing will happen.
freeze: will update the
requirements.txtwith all the libraries installed with
pip. This is useful if you installed new libraries.
clean: will delete the Python cache and the environment. You can use this safely, because if you run your application again, everything will be re-created!
Make is really easy, just type
make and the command you want to execute, e.g:
Please, not that you need to have make installed. In a mac you can do it with
brew install make), in Linux is usually installed or available in the software repositories (
dnf…), and in Windows you can use WSL to install a Linux distribution inside Windows and run make from there.
Let’s sum up
In this article, you learned how to create a Python project in its own virtual environment, and also how to create a Makefile to run everything from it. Now, when someone clones that project, they only will need to type
make run and it automatically creates the environment, install the dependencies and run the project. Yay!
I hope you found this interesting. Of course this isn’t the only way to manage a Python project. This is the way I use to do it. If there’s something I missed, please, ping me, and I’ll update the article. Thanks!