Publish your own Python Library

These two days, for convenience, I tossed about a tool I wrote, and studied how to publish my Python library. Recorded here, I mainly introduced the following contents.

  • The complete process of publishing Python Libraries
  • The Method of Publishing Your Command Line Tools through Python Library

Check directory organization

To publish Python libraries, you first need to check whether your directory organization meets the requirements of the compiler to use my library. MarkTex For example, the directory tree structure is as follows:

.
├── MANIFEST.in
├── marktex
│   ├── config.py
│   ├── example
│   │   └── ...
│   ├── __init__.py
│   ├── markast
│   │   ├── document.py
│   │   ├── environment.py
│   │   ├── __init__.py
│   │   ├── line.py
│   │   ├── parser.py
│   │   ├── token.py
│   │   ├── utils.py
│   │   └── xmls.py
│   ├── marktex.py
│   └── texrender
│       └── ...
└── setup.py

You can see a subdirectory in the project root directory. / marktex is where the project code is located. In the project root directory, besides the project code, the necessary file is setup.py.

Check references in packages

If the reference is incorrect, even if the project does not report errors because of IDE, it will also report errors when compiled and packaged.

The first is to assume that our package has been compiled successfully. Then we need to introduce the relevant content in the package. We can write absolute paths. For example, I want to introduce a class in. / marktex/markast/line.py.

# environment.py
from marktex.markast.line import NewLine

This absolute path approach can introduce classes of other folders under the project:

# environment.py
from marktex.texrender.toTex import MarkTex

The other is the relative path, which deletes all the directories under the absolute path, including the directories where the files are located, leaving only a few points.

# environment.py
from .line import NewLine

Note that this method can only refer to each other in the directory where it is located. There is no such grammar in Python as.. / So you can go to the previous layer to find the package.

Specifically, you can not check so carefully. After compiling, you can try to import packages in other directories, see the wrong code and then change it.

Installation file setup.py

We use the setuptools library to compile the Python library. Before compiling, we need to explain our project, so we have the setup.py file. The template of this file is as follows, which can be directly applied:

from setuptools import setup,find_packages

long_description = "" #Here you can import external README.md

setup(
    name='TODO', # Project name
    version='TODO', # For example, 0.0.1/0.0.1.dev1
    description='TODO', 
    long_description = long_description, 
    url='TODO', # If there are links like github
    author='TODO', # author
    author_email='TODO', # mailbox
    license='MIT',
    classifiers=[
        'Development Status :: 3 - Alpha',
        'Intended Audience :: Developers',
        'Topic :: Software Development :: Build Tools',
        'License :: OSI Approved :: MIT License',
        'Programming Language :: Python :: 3',
        'Programming Language :: Python :: 3.3',
        'Programming Language :: Python :: 3.4',
        'Programming Language :: Python :: 3.5',
    ],
    keywords='TODO', # Spaces between keywords are generally spaced
    install_requires = [
      "TODO",
    ],
    packages=find_packages(),
    include_package_data = True, #
    entry_points={ #If the published library includes command line tools
        'console_scripts':[
            'cmdname = cmdtoolfilepath:methodname' #
        ]
      },
)

Most of them are easy to understand. There are two parameters to note. One is include_package_data. When compiling, if there is a non.py file in the project, it will not be compiled by default. If the project uses some related files, you can set the parameter to True, and generate one beside the setup.py file. The MANIFEST.in file declares which files are included. The format of the file is as follows:

include example/*.md
include README.rst

Note that the path is relative to the real project. For example, my project is marktex. To add all md files in the project example directory, write from example / instead of marktex.

Another parameter is entry_points, which is used to generate scripting tools. The format is as shown in the template. For example, in my project, I will use marktex.marktex.py as the last tool to call. Then the content should be written as follows:

'console_scripts':[
	'marktex = marktex.marktex:main'
]

The left side is the noun of the command used in the final command line, and the right side is the path specific to the method. If there is no specific method, you can write main to represent the file. How to write the file concretely can you refer to my project file? marktex.py

When the compilation is successful, I can do the following:

marktex a.md -o "./"

Compiling and Publishing

The last two steps are compiling and publishing. Compiling commands is simple:

python setup.py sdist bdist_wheel

After compiling, if you want to install the test locally, find the compiled file under the dist file and run it:

pip install path/to/whl/xxx.whl

If there is no update version number, the installation will not be able to continue, you can force the installation by adding parameters:

pip install --force-reinstall path/to/whl/xxx.whl

After the test is completed, it's time for the final release. First you need to https://pypi.org/ Register an account and then run it. Enter the password according to the prompt:

twine upload --skip-existing dist/*

PS: Of course, for the first time you may need to install the twine package

PSS: If you configure the file well, you don't need to enter your account password in the future. How to configure it, please ask Google.

So far, the whole process has been completed.

appendix

To facilitate the operation, I wrote two scripts to help me compile, install and upload tasks, attached here:

build.cmd is used for compilation, and the final generated file is found in the directory for compilation.

python setup.py sdist bdist_wheel
SET CountI=0
SET BakDir="./dist/"
for /f   %%a in ('dir %BakDir% /a:-d /B /o:-D') do (
rem echo %%a
SET FileName=%%a
SET CountI=CountI+1
rem echo %CountI%
if %CountI% == 0 goto bakup2
 
)
:bakup2
rem pip install --force-reinstall %BakDir%%FileName%
pip install %BakDir%%FileName%

Push.cmd for release

twine upload --skip-existing dist/*

Keywords: Python Programming pip github

Added by dvd420 on Thu, 01 Aug 2019 09:33:21 +0300