27
Beauty of Poetry ✨
Disclaimer: Here, in this article, the word "Poetry" is not referred to as something related to English Literature, history, religion, or stuff. :)
First things first, I'm on a Ubuntu 20.04 LTS operating system. Few things might be different for you according to your operating system. So, without any further ado, lets get started🚀
PS: If you directly want to get into what's Poetry and its functions, feel free to skip the
Introduction
part.
I'm primarily a JavaScript, React developer where the dependency management(adding, removing, upgrading) is taken care of by npm
or yarn
. I always wanted to try out a Python web framework & that is when I came across Flask which is a lightweight framework to develop web applications, RESTful APIs and much more. In this article, I'll be using some analogies in JavaScript to describe how things work in Python.
Normally, npm install <dependency>
will install a dependency in that project itself by generating a node_modules folder and if we add a -g
or --global
flag, it will install the dependency globally. But things are a little different in Python. In Python, we have to create something called a virtual environment which is essentially a Python environment such that the Python interpreter, libraries and scripts installed into it are isolated from other virtual environments or those libraries installed in a System Python i.e., one which is installed as part of your operating system.
Lets take an instance for example: Suppose you're working on a project with five other developers and lets say you have flask version 1.1.2
version installed globally whereas the project requires flask version 1.1.3
. That is where conflicts might or might not arise due to different flask versions. To be on the safer side, we use virtual environments.
Before coming on to what Poetry actually is, let me explain its use cases and how it makes our life easier. The two major issues that we face using python are:
In python, we can use many ways to make virtual environments with venv
being its standard library. Few other libraries include virtualenv
, and conda
. For beginners, it is recommended to use the pip
& virtualenv
combo.
To create a virtual environment:
- With
venv
:
$ python3 -m venv .venv
- With
virtualenv
:
$ virtualenv venv
To activate a virtual environment:
$ .venv/Scripts/Activate.ps1
Voila! our virtual environment is activated. Now, we can install any dependency using pip install
. But if you see the process, it is very much time consuming.
Generally, we can export requirements.txt
which defines all the dependencies we've installed using pip
. We can export it by:
$ pip freeze > requirements.txt
What we get from it is a plain text file with all the dependencies as well as their versions listed.
bcrypt==3.2.0
dnspython==2.1.0
email-validator==1.1.2
Flask==1.1.2
Flask-Bcrypt==0.7.1
Flask-Login==0.5.0
Flask-SQLAlchemy==2.5.1
Flask-WTF==0.14.3
gunicorn==20.1.0
itsdangerous==1.1.0
Jinja2==2.11.3
MarkupSafe==1.1.1
Pillow==8.2.0
pycparser==2.20
SQLAlchemy==1.4.7
Werkzeug==1.0.1
WTForms==2.3.3
yapf==0.31.0
But again, here we have to lock requirements.txt
everytime we add or remove a dependency. Also, it becomes difficult to audit all dependencies & bring them up-to date when needed.
Thus, we need something which can isolate the project as well as it can manage our dependencies & their versions as well as lock everything that gets installed just like we have a package.json
in Javascript which is like a manifest for your project, a place where npm
or yarn
stores all the dependencies with their version & package-lock.json
or yarn.lock
if you're using npm
or yarn
respectively which keeps track of the exact version of every package that is installed so that a product is 100% reproducible in the same way even if packages are updated by the maintainers.
This is where Poetry comes to rescue and saves us from the above mentioned problems. Let us learn more about what is Poetry in the next section.
So, Poetry is a tool for dependency management and packaging in Python. According to their official documentation, it allows us to declare the libraries our project depends on and it will manage (add/remove/update) them for us. IMO, Poetry is by far best dependency as well as virtual environment management tool I've come across in python programming. Initialising a Poetry project produces two main files, namely pyproject.toml
which works like a package.json
& poetry.lock
that works like package-lock.json
or yarn.lock
. In other words, we can say that Poetry resembles npm/yarn. Bear with me, I won't give much analogies from now onwards XD. Now, let's see how we can download & use Poetry,
Poetry has a well documented set of instructions on how to install it and the best thing is that almost every operating systems (eg: Windows, Linux, MacOS) supports Poetry. Poetry is also available on PyPi
but it is not recommended to install using pip because it will also install Poetry’s dependencies which might cause conflicts with other packages.
Prerequisite: If you don't have
curl
installed, you can do so by:
$ sudo apt update
$ sudo apt install curl
The installation guidelines as stated in the official documentation are listed below!
# osx / linux / bashonwindows install instructions
$ curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python -
# windows powershell install instructions
$ (Invoke-WebRequest -Uri https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py -UseBasicParsing).Content | python -
# Installing with pip
$ pip install --user poetry
Voila! Poetry will be now installed in your system. To confirm it, you can:
$ poetry --version
Poetry version 1.1.6
Before we get started with Poetry, we have to make sure of some configurations. You can always type poetry --help
and it'll display the set of commands & arguments and how to use them else refer to their configuration documentation. I've listed below the required configurations. Make sure you do the same.
# To list all the configurations
$ poetry config --list
cache-dir = "/home/john/.cache/pypoetry"
experimental.new-installer = true
installer.parallel = true
virtualenvs.create = true
virtualenvs.in-project = true
virtualenvs.path = "{cache-dir}/virtualenvs" # /home/john/.cache/pypoetry/virtualenvs
To change or modify any configuration for instance, virtualenvs.create
, you can:
$ poetry config virtualenvs.create false
Else, if you want to modify the configuration only for a specific project, Poetry provides a --local
option to the config command to do the same.
$ poetry config virtualenvs.create false --local
If you want to remove a configuration, you can:
$ poetry config virtualenvs.path --unset
Now we are all set to get started with Poetry. Yayy!!
So, we will be initialising a Poetry project in the Desktop directory. To initialise an empty project, we can type:
~/Desktop$ poetry new poetry-kickstart
Created package poetry_kickstart in poetry-kickstart
A new package named poetry-kickstart
will now be created in your Desktop. We are going to modify the structure a little bit.
We will be having the following contents inside the poetry-kickstart
package.
poetry-kickstart
├── pyproject.toml
├── README.rst
├── poetry-kickstart.py
└── tests
├── __init__.py
└── test_poetry_demo.py
Then, we will spawn a shell using poetry shell
command and install flask
.
~/Desktop/poetry-kickstart$ poetry shell
Spawning shell within Desktop/poetry-kickstart/.venv
. Desktop/poetry-kickstart/.venv/bin/activate
(.venv) ~/Desktop/poetry-kickstart$ poetry add flask
Using version ^2.0.1 for Flask
Updating dependencies
Resolving dependencies... (0.8s)
Writing lock file
Package operations: 6 installs, 0 updates, 0 removals
• Installing markupsafe (2.0.1)
• Installing click (8.0.1)
• Installing itsdangerous (2.0.1)
• Installing jinja2 (3.0.1)
• Installing werkzeug (2.0.1)
• Installing flask (2.0.1)
Spawning a shell will make a virtual environment and automatically activate it. Thus, the contents inside the poetry-kickstart package will be:
poetry-kickstart
├── .venv
├── poetry.lock
├── pyproject.toml
├── README.rst
├── poetry-kickstart.py
└── tests
├── __init__.py
└── test_poetry_demo.py
Now, we are inside a virtual environment with flask installed. Let us make a simple route returning "Hello World!" in poetry-kickstart.py
.
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return 'Hello, World!'
if __name__ == '__main__':
app.run(debug=True)
We have a simple route. Now, let's check if it's working or not. But before that, do ensure if your python interpreter is pointing towards the one in the virtual environment.
To check the sample API,
(.venv) $ poetry run python -m poetry-kickstart
* Serving Flask app 'poetry-kickstart' (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: on
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 117-620-034
Again, you can click ctrl+c
to kill the process & then type exit
to exit from the virtual environment.
This article demonstrates only the basic usage of Poetry. However, there are ton other things that you can do using Poetry. I would prefer their official documentation anytime since it is well structured. But, this is not the end. In my next article, I'll be demonstrating how you can run tests using Poetry, & how to deploy a poetry project to Heroku. Heroku is the go-to service for many developers because it requires less configuration and has quick deployment. But Heroku
doesn't have a standard buildpack
for Poetry. Thus, we will be using another open-source buildpack for Poetry and trust me, it works just fine. Last but not the least, I would like to thank The Open Bio-informatics Foundation for giving me this opportunity & also my mentors @João Paulo Tiz & @Yo Yehudi for their constant support and guidance.
27