A standard way to develop and distribute packages in Python

I didn't know the standard way to develop and distribute packages in Python, so I looked it up. Poetry is easier, but it's useful to remember when working on a human-made project.

Creating a virtual environment

Start with the latest Python, such as Python 3.7.7, ready to run with python commands. In order to develop a package from now on, first create a virtual environment so that other Python programs and libraries used are not mixed. The standard way to create a virtual environment is to use the venv module https://docs.python.org/ja/3/tutorial/venv.html. There is no fixed location for the virtual environment, but the .venv folder is often used.

mkdir packaging_tutorial
cd packaging_tutorial
python -m venv .venv
source .venv/bin/activate

The final source .venv / bin / activate is the command to enter the environment. Simply type deactivate to exit.

Installation of libraries used for development (may not be necessary)

Write the library used for development in a file called requirements.txt. Here we use a package called requests.

requests ~= 2.23.0

To install the package described in requirements.txt, use the following command.

pip install -r requirements.txt 

This will install the required libraries in a valid virtual environment .venv. If you've already done a lot of pip install and forgot what you put in,

pip freeze > requirements.txt

You can create requirements.txt from the current environment like this.

Implement the package

This time, we will use the following directory structure.

packaging_tutorial/
  corona/
    __init__.py
    __main__.py
  tests/
  requirements.txt
  setup.py
  LICENSE
  README.md

Here is an example of corona / __ init__.py. I implemented the get () function to get information about the new corona that is popular these days. Also prepare main () so that it can be easily executed from the command line.

import requests
import sys

def get(country: str) -> str:
    url = f"https://corona-stats.online/{country}?minimal=true"
    response = requests.get(url, headers={'user-agent': 'curl'})
    return response.text

def main() -> None:
    country = sys.argv[1] if len(sys.argv) > 1 else ""
    print(get(country))

Write corona / __ main__.py to callmain ()with pythonm -m.

from . import main
main()

Try it out.

% python -m corona jp
Rank Country    Total Cases  New Cases ▲ Total Deaths New Deaths ▲ Recovered Active  Critical Cases / 1M pop
1    Japan (JP)        2,495                       62                    472   1,961       60             20
     World         1,015,466       523 ▲       53,190         24 ▲   212,229 750,047   37,696         130.29

Write setup.py to complete the package.

Create a file called setup.py and write the package information. Detailed specifications can be found at https://packaging.python.org/guides/distributing-packages-using-setuptools/. As a point

import setuptools

with open("README.md", "r") as fh:
    long_description = fh.read()

setuptools.setup(
    name="corona-propella", # Replace with your own username
    version="0.0.1",
    install_requires=[
        "requests",
    ],
    entry_points={
        'console_scripts': [
            'corona=corona:main',
        ],
    },
    author="Propella",
    author_email="[email protected]",
    description="A covoid-19 tracker",
    long_description=long_description,
    long_description_content_type="text/markdown",
    url="https://github.com/pypa/sampleproject",
    packages=setuptools.find_packages(),
    classifiers=[
        "Programming Language :: Python :: 3",
        "License :: OSI Approved :: MIT License",
        "Operating System :: OS Independent",
    ],
    python_requires='>=3.7',
)

Now that the package is complete, install it in this environment and run it.

pip install -e .
rehash
corona

This pip install -e command installs the package in development mode, which is useful as soon as you change the source code.

Make a handout

I will summarize the package I made so that I can distribute it. The standard format is wheel. Install the required commands and create a whl file in dist.

pip install --upgrade pip setuptools wheel
python setup.py bdist_wheel

Files like dist / corona_propella-0.0.1-py3-none-any.whl are distributions. You can install it with pip.

Testing the handout

Let's create another virtual environment and test the distribution.

deactivate
cd ..
mkdir packaging_test
cd packaging_test
python -m venv .venv
source .venv/bin/activate
pip install ../packaging_tutorial/dist/corona_propella-0.0.1-py3-none-any.whl
python -m corona jp

This will install the package you just created along with the dependent packages in your virtual environment. Smooth. .. ..

Creating an Egg

Instead of Wheel, you can create a format called Egg that seems to have been used in the past.

python setup.py bdist_egg

Use easy_install instead of pip to install Egg.

easy_install ../packaging_tutorial/dist/corona_propella-0.0.1-py3.7.egg

Various cleanup

Delete the file created by setup.py

python setup.py clean --all

Erase the virtual environment

rm -r .venv

Relationship between requirements.txt and setup.py

The method I've introduced is verbose because you end up writing the required packages in both requirements.txt and install_requires in setup.py. According to https://caremad.io/posts/2013/07/setup-vs-requirement/, there are the following differences in the manners.

When creating a library, pip install -e . will also install the dependent packages, so I don't think requirements.txt is needed.

reference

Recommended Posts

A standard way to develop and distribute packages in Python
Organize python modules and packages in a mess
Steps to develop a web application in Python
How to develop in Python
MIDI packages in Python midi and pretty_midi
Change the standard output destination to a file in Python
A simple way to avoid multiple for loops in Python
How to develop in a virtual environment of Python [Memo]
Introducing a good way to manage DB connections in Python
[Mac] A super-easy way to execute system commands in Python and output the results
Just try to receive a webhook in ngrok and python
Seeking a unified way to wait and get for state changes in Selenium for Python elements
An easy way to view the time taken in Python and a smarter way to improve it
How to display bytes in the same way in Java and Python
How to package and distribute Python scripts
Modules and packages in Python are "namespaces"
How to get a stacktrace in python
Easy way to use Wikipedia in Python
Manage python packages to install in containers
A way to understand Python duck typing
How to use is and == in Python
[Python] How to put any number of standard inputs in a list
How to put a half-width space before letters and numbers in Python.
Connect to postgreSQL from Python and use stored procedures in a loop.
I tried to develop a Formatter that outputs Python logs in JSON
What is the fastest way to create a reverse dictionary in python?
How to stop a program in python until a specific date and time
Try to calculate a statistical problem in Python
How to generate permutations in Python and C ++
To execute a Python enumerate function in JavaScript
How to embed a variable in a python string
I want to create a window in Python
Create a standard normal distribution graph in Python
How to create a JSON file in Python
I wrote a class in Python3 and Java
Send messages to Skype and Chatwork in Python
To add a module to python put in Julialang
How to notify a Discord channel in Python
[Python] How to draw a histogram in Matplotlib
How to output "Ketsumaimo" as standard output in Python
To represent date, time, time, and seconds in Python
How to plot autocorrelation and partial autocorrelation in python
Use libsixel to output Sixel in Python and output a Matplotlib graph to the terminal.
[ES Lab] I tried to develop a WEB application with Python and Flask ②
A complete guidebook to using pyenv, pip and python in an offline environment
I want to exe and distribute a program that resizes images Python3 + pyinstaller
Searching for an efficient way to write a Dockerfile in Python with poetry
Python packages and modules
Convert timezoned date and time to Unixtime in Python2.7
I tried to graph the packages installed in Python
Parse a JSON string written to a file in Python
How to convert / restore a string with [] in python
I want to embed a variable in a Python string
I want to easily implement a timeout in python
Calculation of standard deviation and correlation coefficient in Python
(Python) Try to develop a web application using Django
I want to write in Python! (2) Let's write a test
[Python] How to expand variables in a character string
I tried to implement a pseudo pachislot in Python
Create a plugin to run Python Doctest in Vim (1)
A memorandum to run a python script in a bat file