Photo by Daniel McCullough on Unsplash
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:
source ./env/bin/activate
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.
Installing dependencies
Let's install 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 -
et voilà!
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 python
command:
~/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
command:
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 theapp.py
Python file if thevenv
is active. If it's not it will create the virtual environment and install its dependencies. If norequirements.txt
file is found, then nothing will happen. -
freeze
: will update therequirements.txt
with all the libraries installed withpip
. 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!
Using Make
is really easy, just type make
and the command you want to execute, e.g:
make run
Please, not that you need to have make installed. In a mac you can do it with brew
(brew install make
), in Linux is usually installed or available in the software repositories (apt
, 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!
Top comments (1)
Good post for beginners.
Thanks!