In this post, we discuss how to make an application self-installable in editable or development mode; and then prepare it for distribution. Finally, test the distribution in another virtual environment.

023-feature-image.png
Python: Application ( Self ) Installation, Built Distribution and Test the Built Distribution.

For a Python application, we can install required packages individually or via the requirements.txt text file. We can also use the setuptools package to make applications install packages in editable or development mode; and later use wheel to prepare the application built distribution.

In this post, we demonstrate how to do this with a simple Flask web application that has only a single route /hello. We will then install the application built distribution onto another virtual environment and run the application with Waitress web server – https://docs.pylonsproject.org/projects/waitress/en/latest/.

Environments

  1. Python 3.10.1.

Application Directories and Files

These are the directories and files that we will create manually:

F:\self_install\
|
|-- .env
|-- app.py
|-- setup.py
|
|-- src\
|   |
|   |-- self_install\
|       |   
|       |-- __init__.py
|       |-- config.py

Please note, this is my environment only, you can name it whatever you like and where ever suit you most.

Create The Application

Setting up the virtual environment

Change directory to F:\self_install</span>, and run the following three ( 3 ) commands to set up the virtual environment:

C:\PF\Python310\python.exe -m pip install --upgrade pip

C:\PF\Python310\python.exe -m pip install --user virtualenv 

C:\Users\behai\AppData\Roaming\Python\Python310\Scripts\virtualenv.exe venv

Then activate the virtual environment:

.\venv\Scripts\activate.bat

For creating virtual environment, please see Python: Virtual Environment virtualenv for multiple Python versions.

The screen should now look similar to the image below:

023-01.png

setuptools and wheel

After activating venv, install and upgrade setuptools and wheel, run the following command:

.\venv\Scripts\pip.exe install --upgrade setuptools wheel

The output should look similar to the image below:

023-02.png

We should take a glance inside
F:\self_install\venv\Lib\site-packages</span>, and make mental notes of what are in there.

F:\self_install\setup.py

Below are the relevant documentations:

The file setup.py is used to install the application, and via wheel prepare the built distribution.

File F:\self_install\setup.py:
"""Installation script for self_install demo project."""
from pathlib import Path
from setuptools import setup, find_packages

setup(
    name='self-install',
    description='Demonstrate project self installation through pip.',
    version='1.0.0',
    author='Van Be Hai Nguyen',
    author_email='behai_nguyen@hotmail.com',
    packages=find_packages(where="src"),
    package_dir={"": "src"},
    python_requires='>=3.10',
    install_requires=[
        'Flask',
        'python-dotenv',
    ],
)

python-dotenv is required to read .env enviroment file. A further note, this setup requires sub-directory src</span> exists under F:\self_install</span> before we can run the installation.

Install the Application

To install the application in editable mode, run the below command:

.\venv\Scripts\pip.exe install -e .

The output should look similar to the image below:

023-03.png

Please take a look in:

  • F:\self_install\venv\Lib\site-packages\
  • F:\self_install\src\self_install.egg-info\

Create And Run The Application

We are now ready to create the application. It is so simple, so I will just list the content of the files one after another, and will not discuss the content.

File F:\self_install\.env:
FLASK_APP=app.py
FLASK_ENV=development
SECRET_KEY=">s3g;?uV^K=`!(3.#ms_cdfy<c4ty%"
File F:\self_install\src\self_install\__init__.py:
"""Flask app initialization via factory pattern."""
from flask import Flask

from self_install.config import get_config

def create_app():
    app = Flask( 'self_install' )

    app.config.from_object( get_config() )

    # A simple page that says hello
    @app.route('/hello')
    def hello():
        return 'Hello, World!'

    return app
File F:\self_install\src\self_install\config.py:
"""Flask app config settings."""
import os

class Config:
    """Set Flask configuration from .env file."""

    # General Config
    SECRET_KEY = os.getenv( 'SECRET_KEY' )
    FLASK_APP = os.getenv( 'FLASK_APP' )
    FLASK_ENV = os.getenv( 'FLASK_ENV' )

def get_config():
    """Retrieve environment configuration settings."""
    return Config
File F:\self_install\app.py:
"""Flask Application entry point."""

from self_install import create_app

app = create_app()

If everything is working correctly, we should be able to query the application routes with the following command:

.\venv\Scripts\flask.exe routes

The output should look similar to the image below:

023-04.png

We can now run the application with:

.\venv\Scripts\flask.exe run

Paste the following http://127.0.0.1:5000/hello into a browser, and we should get Hello, World! response. The application is now complete. We can now prepare the built distribution.

Prepare and Test the Built Distribution

The following command will do the built distribution:

.\venv\Scripts\python.exe setup.py bdist_wheel

The output should look similar to the image below:

023-05.png

Please note the following two directories created by the above command:

  • F:\self_install\build\
  • F:\self_install\dist\

The output file is F:\self_install\dist\self_install-1.0.0-py3-none-any.whl. The components of this file name are:

{project name}-{version}-{python tag}-{abi tag}-{platform tag}

Please see PEP 427 – The Wheel Binary Package Format 1.0 – https://peps.python.org/pep-0427/#file-format

This file can be copied to another machine, another virtualenv, then install with pip. For this post, I am creating another virtual environment under D:\test</span>, copy self_install-1.0.0-py3-none-any.whl to D:\test</span>, and run the below command:

.\venv\Scripts\pip.exe install self_install-1.0.0-py3-none-any.whl

If everything goes well, the output should look like the image below:

023-01.png

Next, we install the Waitress web server – https://docs.pylonsproject.org/projects/waitress/en/latest/ with:

.\venv\Scripts\pip.exe install waitress

Then we can launch the application with:

.\venv\Scripts\waitress-serve.exe --call self_install:create_app

The output of those two commands above shown below:

023-07.png

Despite http://0.0.0.0 stated by waitress-serve.exe, the correct address is localhost – copy and paste http://localhost:8080/hello into a browser address, we should get Hello, World! response as before.

This concludes this post… I had fun writing this. For me, I found it useful. I hope you get something out of this post, and thank you for reading.