知乎专栏 | 多维度架构 |
The Python Package Index (PyPI) is a repository of software for the Python programming language.
PyPI helps you find and install software developed and shared by the Python community.
Package authors use PyPI to distribute their software.
PyPI 是一个 Python 语言软件仓库,开发包的作者通过Python社区共享他们的作品。软件开发者可以在平台上搜索、安装和使用这些共享资源。
发布 Python 包到 PyPI(Python Package Index) 的步骤
下面开始介绍如何将自己的 Python 包发布到Python Package Index。
准备一个 Python 项目,目录结构如下
neo@MacBook-Pro-Neo ~/workspace % mkdir netkiller-project neo@MacBook-Pro-Neo ~/workspace % cd netkiller-project
上传到 Python Package Index 的包必须包含该文件,外国法律是很严的,License 文件是告诉用户该软件包的授权条款。你可以在下面网站找到 License 复制粘贴到 LICENSE文件中。
Choose an open source license 我使用的是MIT License
neo@MacBook-Pro-Neo ~/workspace/netkiller-project % curl -s https://mit-license.org | sed 's/<[^>]*>//g ; /^$/d' > LICENSE
neo@MacBook-Pro-Neo ~/workspace/netkiller-project % vim README.md neo@MacBook-Pro-Neo ~/workspace/netkiller-project % cat README.md = Netkiller-Project 演示如何上传包到PyPI
neo@MacBook-Pro-Neo ~/workspace/netkiller-project % mkdir netkiller neo@MacBook-Pro-Neo ~/workspace/netkiller-project % vim netkiller/__init__.py neo@MacBook-Pro-Neo ~/workspace/netkiller-project % cat netkiller/__init__.py name = "netkiller" __version__ = "0.0.1"
setup.py 文件是 setuptools 打包工具的构建脚本,主要用来描述项目名称,版本,作者邮箱,项目描述信息,网址,运行环境,依赖哪些库,支持哪些操作系统,等等。
neo@MacBook-Pro-Neo ~/workspace/netkiller-project % vim setup.py neo@MacBook-Pro-Neo ~/workspace/netkiller-project % cat setup.py import setuptools with open("README.md", "r") as fh: long_description = fh.read() setuptools.setup( name="netkiller-project", version="0.0.1", author="Neo Chen", author_email="netkiller@msn.com", description="Netkiller Python Package", long_description=long_description, long_description_content_type="text/markdown", url="https://github.com/netkiller/netkiller.netkiller.io", packages=setuptools.find_packages(), classifiers=[ "Programming Language :: Python :: 3", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", ], )
使用命令 python3 setup.py sdist bdist_wheel 打包
neo@MacBook-Pro-Neo ~/workspace/netkiller-project % python3 setup.py sdist bdist_wheel running sdist running egg_info creating netkiller_project.egg-info writing netkiller_project.egg-info/PKG-INFO writing dependency_links to netkiller_project.egg-info/dependency_links.txt writing top-level names to netkiller_project.egg-info/top_level.txt writing manifest file 'netkiller_project.egg-info/SOURCES.txt' reading manifest file 'netkiller_project.egg-info/SOURCES.txt' writing manifest file 'netkiller_project.egg-info/SOURCES.txt' running check creating netkiller-project-0.0.1 creating netkiller-project-0.0.1/netkiller_project.egg-info copying files to netkiller-project-0.0.1... copying README.md -> netkiller-project-0.0.1 copying setup.py -> netkiller-project-0.0.1 copying netkiller_project.egg-info/PKG-INFO -> netkiller-project-0.0.1/netkiller_project.egg-info copying netkiller_project.egg-info/SOURCES.txt -> netkiller-project-0.0.1/netkiller_project.egg-info copying netkiller_project.egg-info/dependency_links.txt -> netkiller-project-0.0.1/netkiller_project.egg-info copying netkiller_project.egg-info/top_level.txt -> netkiller-project-0.0.1/netkiller_project.egg-info Writing netkiller-project-0.0.1/setup.cfg creating dist Creating tar archive removing 'netkiller-project-0.0.1' (and everything under it) running bdist_wheel running build installing to build/bdist.macosx-11-x86_64/wheel running install running install_egg_info Copying netkiller_project.egg-info to build/bdist.macosx-11-x86_64/wheel/netkiller_project-0.0.1-py3.9.egg-info running install_scripts adding license file "LICENSE" (matched pattern "LICEN[CS]E*") creating build/bdist.macosx-11-x86_64/wheel/netkiller_project-0.0.1.dist-info/WHEEL creating 'dist/netkiller_project-0.0.1-py3-none-any.whl' and adding 'build/bdist.macosx-11-x86_64/wheel' to it adding 'netkiller_project-0.0.1.dist-info/LICENSE' adding 'netkiller_project-0.0.1.dist-info/METADATA' adding 'netkiller_project-0.0.1.dist-info/WHEEL' adding 'netkiller_project-0.0.1.dist-info/top_level.txt' adding 'netkiller_project-0.0.1.dist-info/RECORD' removing build/bdist.macosx-11-x86_64/wheel
neo@MacBook-Pro-Neo ~/workspace/netkiller-project % ls dist netkiller-project-0.0.1.tar.gz netkiller_project-0.0.1-py3-none-any.whl
neo@MacBook-Pro-Neo ~/workspace/netkiller-project % twine upload dist/* Uploading distributions to https://upload.pypi.org/legacy/ Enter your username: netkiller Enter your password: Uploading netkiller_project-0.0.1-py3-none-any.whl 100%|██████████████████████████████████████████████████████████| 5.81k/5.81k [00:02<00:00, 2.28kB/s] Uploading netkiller-project-0.0.1.tar.gz 100%|██████████████████████████████████████████████████████████| 4.24k/4.24k [00:01<00:00, 3.54kB/s] View at: https://pypi.org/project/netkiller-project/0.0.1/
neo@MacBook-Pro-Neo ~/workspace/netkiller-project % pip3 install netkiller-project Collecting netkiller-project Downloading netkiller_project-0.0.1-py3-none-any.whl (2.8 kB) Installing collected packages: netkiller-project Successfully installed netkiller-project-0.0.1
neo@MacBook-Pro-Neo ~/workspace/netkiller-project % pip3 uninstall netkiller-project Found existing installation: netkiller-project 0.0.3 Uninstalling netkiller-project-0.0.3: Would remove: /usr/local/lib/python3.9/site-packages/netkiller/* /usr/local/lib/python3.9/site-packages/netkiller_project-0.0.3.dist-info/* Proceed (y/n)? y Successfully uninstalled netkiller-project-0.0.3
Format Description Notes gztar gzipped tar file (.tar.gz) Unix 默认 bztar bzipped tar file (.tar.bz2) xztar xzipped tar file (.tar.xz) ztar compressed tar file (.tar.Z) tar tar file (.tar) zip zip file (.zip) Windows 默认 rpm RPM pkgtool Solaris pkgtool sdux HP-UX swinstall wininst self-extracting ZIP file for Windows msi Microsoft Installer. $ python setup.py bdist --formats=rpm setuptools 提供了如下简化命令: Command Formats Notes bdist_dumb tar, gztar, bztar, xztar, ztar, zip Windows 默认 zip, Unix 默认 gztar bdist_rpm rpm, srpm bdist_wininst wininst bdist_msi msi 打 rpm 包可以使用: $ python setup.py bdist_rpm
创建 ~/.pypirc 文件
neo@MacBook-Pro-Neo ~/git/kindle % cat ~/.pypirc [pypi] username:netkiller password:******
****** 改为你的密码
http://docs.python.org/3/install/index.html
http://docs.python.org/3/distutils/index.html
创建 setup.py 如下:
# cat setup.py from distutils.core import setup setup ( name = 'firewall', version = '1.0.0', py_modules = ['firewall'], author = 'neo.chen', author_email = 'netkiller@msn.com', description = 'Module firewall', url='http://netkiller.github.io/', )
注意:name和py_modules这两个参数一定要与firewall.py文件名相同,否则发布安装时会发出模块文件找不到的错误.
打包操作
# python setup.py sdist running sdist warning: sdist: missing required meta-data: url warning: sdist: manifest template 'MANIFEST.in' does not exist (using default file list) warning: sdist: standard file not found: should have one of README, README.txt writing manifest file 'MANIFEST' creating firewall-1.0.0 making hard links in firewall-1.0.0... hard linking firewall.py -> firewall-1.0.0 hard linking setup.py -> firewall-1.0.0 creating dist tar -cf dist/firewall-1.0.0.tar firewall-1.0.0 gzip -f9 dist/firewall-1.0.0.tar tar -cf dist/firewall-1.0.0.tar firewall-1.0.0 gzip -f9 dist/firewall-1.0.0.tar removing 'firewall-1.0.0' (and everything under it)
sdist 生成的文件
# ll dist/ total 4 -rw-r--r--. 1 root root 2123 Aug 9 12:41 firewall-1.0.0.tar.gz
安装包
# python setup.py install running install running build running build_py creating build creating build/lib copying firewall.py -> build/lib running install_lib copying build/lib/firewall.py -> /usr/lib/python2.6/site-packages byte-compiling /usr/lib/python2.6/site-packages/firewall.py to firewall.pyc running install_egg_info Writing /usr/lib/python2.6/site-packages/firewall-1.0.0-py2.6.egg-info
安装后
# ll /usr/lib/python2.6/site-packages/firewall* -rw-r--r--. 1 root root 201 Aug 9 12:42 /usr/lib/python2.6/site-packages/firewall-1.0.0-py2.6.egg-info -rw-r--r--. 1 root root 6145 Aug 9 11:28 /usr/lib/python2.6/site-packages/firewall.py -rw-r--r--. 1 root root 11858 Aug 9 12:42 /usr/lib/python2.6/site-packages/firewall.pyc
https://pip.readthedocs.io/en/stable/installing/
自从Python 3.4版本开始,pip已经被内置在Python中,所以无需再次安装。如果你的系统中没有pip/pip3命令,或者不小心卸载了,可以使用下面方式安装。
neo@MacBook-Pro-Neo ~ % pip --version pip 21.1 from /usr/local/lib/python3.9/site-packages/pip (python 3.9) neo@MacBook-Pro-Neo ~ % pip3 --version pip 21.1 from /usr/local/lib/python3.9/site-packages/pip (python 3.9)
安装包
$ pip install Markdown
安装特定版本的包, 通过使用 ==, >=, <=, >, < 来指定一个版本号。
比如说我要安装3.4.1版本的matplotlib
pip install matplotlib==3.4.1
$ pip install 'Markdown<2.0' $ pip install 'Markdown>2.0,<2.0.3'
用户级包管理,默认root是全局安装
pip3 install --user netkiller-firewall
pip install dist/netkiller_firewall-0.0.1-py3-none-any.whl
操作演示
neo@MacBook-Pro-Neo ~ % cd workspace/firewall neo@MacBook-Pro-Neo ~/workspace/firewall % ls dist netkiller-firewall-0.0.1.tar.gz netkiller_firewall-0.0.1-py3.9.egg netkiller_firewall-0.0.1-py3-none-any.whl neo@MacBook-Pro-Neo ~/workspace/firewall % pip install dist/netkiller_firewall-0.0.1-py3-none-any.whl Processing ./dist/netkiller_firewall-0.0.1-py3-none-any.whl Installing collected packages: netkiller-firewall Successfully installed netkiller-firewall-0.0.1
升级包到当前最新的版本,可以使用-U 或者 --upgrade
# pip install distribute --upgrade $ pip install -U Markdown
neo@MacBook-Pro-Neo ~ % pip show netkiller-logging Name: netkiller-logging Version: 0.0.5 Summary: log send to remote Home-page: http://netkiller.github.io Author: None Author-email: netkiller@msn.com License: BSD Location: /usr/local/lib/python3.9/site-packages Requires: Required-by:
neo@MacBook-Pro-Neo ~ % pip list Package Version ------------------------------------------------- --------- autopep8 1.5.6 bleach 3.3.0 certifi 2020.12.5 chardet 4.0.0 click 7.1.2 colorama 0.4.4 cv 1.0.0 cycler 0.10.0 decorator 4.4.2 dlib 19.22.0 docutils 0.17
查看需要升级的包
neo@MacBook-Pro-Neo ~ % pip list -o
目前已经安装的库中,看哪些需要版本升级
neo@MacBook-Pro-Neo ~ % pip list -o Package Version Latest Type ------------------------------------------------- --------- -------- ----- autopep8 1.5.6 1.5.7 wheel decorator 4.4.2 5.0.7 wheel docutils 0.17 0.17.1 wheel easyocr 1.3.0.1 1.3.1 wheel et-xmlfile 1.0.1 1.1.0 wheel idna 2.10 3.1 wheel importlib-metadata 3.10.0 4.0.1 wheel Pygments 2.8.1 2.9.0 wheel pyobjc 7.1 7.2 wheel
如果一个项目需要安装很多库,可以将他们放入一个文件 requirements.txt,例如那可以批量安装:
pip install -r requirements.txt
requirements.txt 文件内容格式如下:
netkiller-logging==0.0.4 netkiller-firewall
操作演示
neo@MacBook-Pro-Neo ~ % vim requirements.txt neo@MacBook-Pro-Neo ~ % cat requirements.txt netkiller-logging netkiller-firewall neo@MacBook-Pro-Neo ~ % pip install -r requirements.txt Collecting netkiller-logging Downloading netkiller_logging-0.0.5-py3-none-any.whl (14 kB) Collecting netkiller-firewall Downloading netkiller_firewall-0.0.1-py3-none-any.whl (5.4 kB) Installing collected packages: netkiller-logging, netkiller-firewall
列出安装包的描述信息
$ pip freeze
操作演示
neo@MacBook-Pro-Neo ~ % pip freeze autopep8==1.5.6 bleach==3.3.0 certifi==2020.12.5 chardet==4.0.0 click==7.1.2 colorama==0.4.4 cv==1.0.0 cycler==0.10.0 decorator==4.4.2 dlib==19.22.0 docutils==0.17 easyocr==1.3.0.1 et-xmlfile==1.0.1 face-recognition==1.3.0 face-recognition-models==0.3.0 idna==2.10 imageio==2.9.0 imageio-ffmpeg==0.4.3 importlib-metadata==3.10.0 keyboard==0.13.5 keyring==23.0.1 kiwisolver==1.3.1 lxml==4.6.3 matplotlib==3.4.1 moviepy==1.0.3 netkiller-devops==0.0.1 netkiller-kindle==0.0.3 networkx==2.5.1 numpy==1.20.2 opencv-python==4.5.1.48 openpyxl==3.0.7 packaging==20.9 pandas==1.2.4 Pillow==8.2.0 pkginfo==1.7.0 proglog==0.1.9 progress==1.5 PyAudio==0.2.11 pycodestyle==2.7.0 Pygments==2.8.1 pyobjc==7.1 python-dateutil==2.8.1 python-docx==0.8.10 pytz==2021.1 PyWavelets==1.1.1 PyYAML==5.4.1 readme-renderer==29.0 requests==2.25.1 requests-toolbelt==0.9.1 rfc3986==1.4.0 scikit-image==0.18.1 scipy==1.6.2 six==1.15.0 SpeechRecognition==3.8.1 tabulate==0.8.9 tifffile==2021.3.31 toml==0.10.2 torch==1.8.1 torchvision==0.9.1 tqdm==4.59.0 twine==3.4.1 typing-extensions==3.7.4.3 urllib3==1.26.4 webencodings==0.5.1 xlrd==2.0.1 zipp==3.4.1
导出已经安装的包列表,并保存到到本地文件中:
pip freeze > requirements.txt
验证已安装的包是否有兼容依赖问题
pip check package-name
操作演示
neo@MacBook-Pro-Neo ~ % pip check netkiller-firewall No broken requirements found.
将库下载到本地指定目录
pip download package_name -d "要保存的文件路径"
操作演示
neo@MacBook-Pro-Neo ~ % pip download netkiller-logging -d /tmp/netkiller-logging Collecting netkiller-logging Using cached netkiller_logging-0.0.5-py3-none-any.whl (14 kB) Saved /private/tmp/netkiller-logging/netkiller_logging-0.0.5-py3-none-any.whl Successfully downloaded netkiller-logging neo@MacBook-Pro-Neo ~ % ls /tmp/netkiller-logging netkiller_logging-0.0.5-py3-none-any.whl
由于 pip 源服务器放在外国,所以我们安装包的时候速度非常慢。
国内一些企业和组织做了 pip 镜像,他们每个一定时间从外国服务器同步一次数据到国内服务器,我们将 pip 切换到国内服务器后,再下载包就不会去外国服务器,所以下载速度大大提高。
临时下载一个包
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple matplotlib
永久性切换
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
设为默认后,以后安装库都将从清华镜像源下载
下面是国内常用镜像服务器地址:
清华镜像 https://pypi.tuna.tsinghua.edu.cn/simple
阿里云镜像 https://mirrors.aliyun.com/pypi/simple/