How to Manage Dependencies with Poetry for a Flask app on Ubuntu 24.04
Poetry is an open-source tool for managing and packaging dependencies for Python projects. Poetry maintains a clean view of your dependency tree, streamlines the installation and management of dependencies, and simplifies packaging and distribution to PyPI.
This article explains how to install Poetry and manage dependencies for a Flask application on Ubuntu 24.04. You'll install Poetry with Pipx, create a virtual environment, and run a Flask application using Poetry and Gunicorn.
Prerequisites
Before you begin, you need to:
- Have access to an Ubuntu 24.04 instance.
Install Poetry with Pipx
Install Poetry in an isolated environment to prevent conflicts between Poetry’s internal dependencies and system-wide dependencies. Follow these steps to install Pipx and use it to install Poetry.
Update the APT package index.
console$ sudo apt update
Install Pipx.
console$ sudo apt install pipx -y
Add the Pipx libraries to your system’s PATH.
console$ pipx ensurepath
Enable tab completions for Pipx commands.
console$ echo 'eval "$(register-python-argcomplete pipx)"' >> ~/.bashrc
Reload the
.bashrc
shell configuration to apply the changes in your active session.console$ source ~/.bashrc
Install Poetry using Pipx.
console$ pipx install poetry
Your output should be similar to the one below.
installed package poetry 2.0.0, installed using Python 3.12.3 These apps are now globally available - poetry done! ✨ 🌟 ✨
View the installed Poetry version.
console$ poetry --version
Your output should be similar to the one below:
Poetry (version 2.0.0)
Create a Poetry Project
Initialize Poetry in an existing Python project or create a new project to use Poetry as a dependency manager. Creating a new Poetry project from scratch allows Poetry to create the project structure and configuration files. Follow the steps below to create a new Poetry project to manage dependencies.
Create a new
flask-app
Poetry project.console$ poetry new flask-app
The above command creates a
flask-app
directory with the following files:flask_app
: Contains an__init__.py
file that specifies all Flask code, including modules, functions, and other related support components.pyproject.toml
: Includes information about the Project, Poetry configuration, and installed dependencies.README.md
: Includes basic documentation about the Project.tests
: Integrating and organizes the project’s test cases.
Your output should be similar to the one below:
Created package flask_app in flask-app
Switch to the
flask-app
project directory.console$ cd flask-app
Create a Virtual Environment and Install Flask
Follow the steps below to create a virtual environment and install Flask.
Specify the Python interpreter for Poetry and create a new virtual environment.
console$ poetry env use python3
The above command instructs Poetry to use the default Python3 interpreter on your system. You can also use a specific version such as Python 3.11. For example,
poetry env use python3.11
if Python 3.11 is installed on your workstation.Your output should be similar to the one below:
Creating virtualenv flask-app-vnQ3DaWl-py3.12 in /home/linuxuser/.cache/pypoetry/virtualenvs Using virtualenv: /home/linuxuser/.cache/pypoetry/virtualenvs/flask-app-vnQ3DaWl-py3.12
Activate the virtual environment.
console$ poetry env activate
The above command outputs the command to run in order to activate the virtual environment manually.
Your output should be similar to the one below:
source /home/linuxuser/.cache/pypoetry/virtualenvs/flask-app-vnQ3DaWl-py3.12/bin/activate
Activate the virtual environment using its path.
console$ source /home/linuxuser/.cache/pypoetry/virtualenvs/flask-app-vnQ3DaWl-py3.12/bin/activate
Your output should be similar to the one below when the virtual environment is activated.
(flask-app-py3.12) linuxuser@:~/flask-app$
Install Flask using Poetry.
console$ poetry add flask
The above command modifies the project directory with the following functionalities:
- Install Flask with all dependencies in the active virtual environment.
- Adds the installed Flask version to your Project’s
pyproject.toml
file. - Creates a
Poetry.lock
file for deterministic builds.
Your output should be similar to the one below:
Using version ^3.1.0 for flask Updating dependencies Resolving dependencies... (0.2s) Package operations: 7 installs, 0 updates, 0 removals - Installing markupsafe (3.0.2) - Installing blinker (1.9.0) - Installing click (8.1.8) - Installing itsdangerous (2.2.0) - Installing jinja2 (3.1.5) - Installing werkzeug (3.1.3) - Installing flask (3.1.0) Writing lock file
Deactivate the virtual environment.
console$ deactivate
Set up Firewall Rules
Uncomplicated firewall (UFW) is active on most Ubuntu 24.04 servers by default. Configure UFW to allow connections to the Flask application port such as 5000
on your server. Follow the steps below to allow port 5000
and reload the firewall configuration.
Allow connections to the Flask application port
5000
.console$ sudo ufw allow 5000/tcp
Reload UFW to apply the firewall configuration changes.
console$ sudo ufw reload
View the UFW status and verify that the rule is active.
console$ sudo ufw status
Your output should be similar to the one below:
Status: active To Action From -- ------ ---- 22/tcp ALLOW Anywhere 5000/tcp ALLOW Anywhere 22/tcp (v6) ALLOW Anywhere (v6) 5000/tcp (v6) ALLOW Anywhere (v6)
Run the Flask App with Poetry
Poetry not only helps manage dependencies and create virtual environments but also allows you to run Poetry-managed Python projects. Follow the steps below to set up and run a Flask application with Poetry.
Retrieve the command to reactivate the virtual environment.
console$ poetry env activate
Your output should be similar to the one below:
source /home/linuxuser/.cache/pypoetry/virtualenvs/flask-app-vnQ3DaWl-py3.12/bin/activate
Activate the virtual environment.
console$ source /home/linuxuser/.cache/pypoetry/virtualenvs/flask-app-vnQ3DaWl-py3.12/bin/activate
Navigate to the
flask_app
directory.console$ cd flask_app
Create a file
app.py
using nano.console$ nano app.py
Add the following code.
pythonfrom flask import Flask app = Flask(__name__) @app.route('/') def home(): return "<h1>Greetings from Vultr</h1>" if __name__ == '__main__': app.run(host='0.0.0.0', port='5000')
Save the file by pressing Ctrl+X, followed by Y and then hit Enter.
This creates a webpage that returns Greetings from Vultr on the home route
/
.Run the Flask application.
console$ poetry run python app.py
Your output should be similar to the one below:
* 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 all addresses (0.0.0.0) * Running on http://127.0.0.1:5000 * Running on http://<SERVER-IP>:5000 Press CTRL+C to quit
Access your Flask app using the following address in a web browser. Replace
<SERVER-IP>
with your server’s IP address.http://<SERVER-IP>:5000
To stop the Flask app press Ctrl+C in your terminal session.
Create Group Dependencies
Poetry allows you to manage dependencies using groups. Follow the steps below to create a group called dev
and install Pytest for testing.
Install Pytest in the
dev
dependency group.console$ poetry add pytest --group dev
This creates a new section in the
pyroject.toml
file -[tool.poetry.group.dev.dependencies]
, which includes the dependencies such aspytest ="^8.3.4"
, under thedev
group.Production dependencies should not be added to any group. But instead should be part of the root dependencies -
[tool.poetry.dependencies]
. This ensures that production dependencies are included in the application without being segregated into specific groups, avoiding any exclusions during deployment or packaging for production.Navigate to your project’s
tests
directory.console$ cd ~/flask-app/tests
Create a new directory named
unit
.console$ mkdir unit
Navigate in the
unit
directory.console$ cd unit
Create an
__init__.py
file.console$ touch __init__.py
__init__.py
files allow you to mark a directory as a Python package allowing you to import modules from it. For more information refer to the official Python documentation.Create a test file
test_app.py
usingnano
.console$ nano test_app.py
Add the following code in the file.
pythonimport pytest from flask_app.app import app @pytest.fixture def client(): with app.test_client() as client: yield client def test_the_home_route(client): response = client.get('/') assert response.status_code == 200 assert b"<h1>Greetings from Vultr</h1>" in response.data
Save the file by pressing Ctrl+X, followed by Y and then hit Enter.
This checks that the response body from
app.py
in theflask_app
package contains the markup<h1>Greetings from Vultr</h1>
.Run the test.
console$ pytest
Your output should be similar to the one below:
platform linux -- Python 3.12.3, pytest-8.3.4, pluggy-1.5.0 rootdir: /home/linuxuser/flask-app configfile: pyproject.toml collected 1 item test_app.py . [100%] ============================= 1 passed in 0.11s ==============================
Install Gunicorn a WSGI HTTP Server with Flask
A WSGI HTTP server such as Gunicorn allows handling client's requests concurrently and efficiently, making it ideal for production-grade Flask applications. Follow the steps below to add Gunicorn as a dependency with Poetry and configure the Flask app to run with Gunicorn.
Navigate to the
flask_app
directory.console$ cd ~/flask-app/flask_app
Add Gunicorn as a root dependency.
console$ poetry add gunicorn
Create a
wsgi.py
file using nano.console$ nano wsgi.py
Add the following Python code.
pythonfrom app import app if __name__ == '__main__': app.run()
Save the file by pressing Ctrl+X, followed by Y and then hit Enter.
Run the Flask app with Gunicorn.
console$ gunicorn --bind 0.0.0.0:5000 wsgi:app
Check that your Flask app is still accessible.
http://<SERVER-IP>:5000
Press Ctrl+C to stop the server.
Manage the Virtual Environment
Poetry virtual environments consume space, though they can be managed and can be recreated. Follow the steps below to remove your active virtual environment and verify that it can be recreated.
Exit the virtual environment.
console$ deactivate
List all virtual environments for your project.
console$ poetry env list
The environment labeled (Activated) is the one in use.
Your output should be similar to the one below:
flask-app-vnQ3DaWl-py3.12 (Activated)
Copy the environment name from the previous command output and remove the virtual environment.
console$ poetry env remove flask-app-vnQ3DaWl-py3.12
Your output should be similar to the one below:
Deleted virtualenv: /home/linuxuser/.cache/pypoetry/virtualenvs/flask-app-vnQ3DaWl-py3.12
Recreate the virtual environment.
console$ poetry env use python3
Retrieve the command to reactivate the virtual environment.
console$ poetry env activate
Your output should be similar to the one below:
source /home/linuxuser/.cache/pypoetry/virtualenvs/flask-app-vnQ3DaWl-py3.12/bin/activate
Activate the virtual environment by copying and running the activation command from the previous step:
console$ source /home/linuxuser/.cache/pypoetry/virtualenvs/flask-app-vnQ3DaWl-py3.12
Install all the dependencies from the
pyproject.toml
file.console$ poetry install
With the
pyproject.toml
file present, the virtual environment and dependencies can always be recreated and reinstalled.
Modify the Virtual Environment Location
By default, Poetry creates a virtual environment in /.cache/pypoetry/virtualenvs
. However, to keep the virtual environment organized alongside your project files, you can modify its location.
Follow the steps below to set the virtual environment at the root of your project.
Exit the virtual environment.
console$ deactivate
List the virtual environments for your project.
console$ poetry env list
The environment labeled (Activated) is the one in use.
Your output should be similar to the one below:
flask-app-vnQ3DaWl-py3.12 (Activated)
Remove the virtual environment.
console$ poetry env remove flask-app-vnQ3DaWl-py3.12
Configure Poetry to allow the virtual environment to be created at the root of your project.
console$ poetry config virtualenvs.in-project true
The above command will overwrite the default configuration set by Poetry and allows the virtual environment to be created in the root of your project.
Verify that the configuration change is applied.
console$ poetry config virtualenvs.in-project
Your output should be similar to the one below:
true
Create a virtual environment to verify.
console$ poetry env use python3
Your output should be similar to the one below:
Creating virtualenv flask-app in /home/linuxuser/flask-app/.venv Using virtualenv: /home/linuxuser/flask-app/.venv
Retrieve the command to activate the virtual environment.
console$ poetry env activate
Your output should be similar to the one below:
source /home/linuxuser/flask-app/.venv/bin/activate
Activate the virtual environment.
console$ source /home/linuxuser/flask-app/.venv/bin/activate
View your virtual environment information.
console$ poetry env info
Your output should be similar to the one below:
Virtualenv Python: 3.12.3 Implementation: CPython Path: /home/linuxuser/flask-app/.venv Executable: /home/linuxuser/flask-app/.venv/bin/python Valid: True Base Platform: linux OS: posix Python: 3.12.3 Path: /usr Executable: /usr/bin/python3.12
Install all the dependencies in this new environment.
console$ poetry install
Run the Flask app using Gunicorn to verify that everything is running in the new environment.
console$ gunicorn --bind 0.0.0.0:5000 wsgi:app
Check that your Flask app is accessible.
http://<SERVER-IP>:5000
Conclusion
You have installed Poetry on your Ubuntu 24.04 server and used it to manage dependencies for a Flask application. You created a Poetry project, set up a virtual environment, and configured Gunicorn to serve the Flask application. Additionally, you managed the virtual environment, streamlining your development workflow. For more information about Poetry, please visit the official Poetry documentation.