likes
comments
collection
share

打包发布自己的第一个 Python 项目(包)

作者站长头像
站长
· 阅读数 10

如何用 pip 安装自己写的包

昨天突发奇想,想让自己写的包也可以像我们常用的 numpy、flask、tensorflow 那样直接一个 pip install XXX 命令就安装上。

要实现这个,首先,我们需要了解 pip 和 Pypi。

(如果你懂一点点英语,请直接看这篇文档:Packaging and distributing projects

(如果你用 Windows,我不保证你可以顺利完成所有操作,自求多福 [告辞])

Pypi

打包发布自己的第一个 Python 项目(包)

The Python Package Index (PyPI) is a repository of software for the Python programming language.

这是 Pypi 的官网上对自己的描述,大概翻译一下:

Python Package Index (PyPI) 是 Python 编程语言的软件库。

其实,我们平时使用 pip 时,就是在 Pypi 里拉取这些包的,例如:

如何用 pip 安装包可以参考:文档 - Installing Packages,这不是本文的重点。

我们接下来参考 文档 - Packaging Python Projects,讨论如何打包、发布自己的项目,然后用 pip 安装自己写的包。

项目结构

大家都知道(不然这篇文章还不适合现在的你,不用看了),我们写一个 Python 项目时,最基本的目录结构如下:

packaging_tutorial/
  example_pkg/
    __init__.py

当我们要开源或者以其他形式发布一个项目时,比如放到 Github 之前,还会加一些测试、LICENSE、README,目录就变成了这样:

packaging_tutorial/
  example_pkg/
    __init__.py
  tests/
  LICENSE
  README.md

现在我们要打包发布这个项目,还需要再加一个 setup.py

packaging_tutorial/
  example_pkg/
    __init__.py
  tests/
  setup.py
  LICENSE
  README.md

setup.py

setup.py 描述了你的项目,告诉别人你项目的名称、版本、描述、依赖......类似于写 node.js 同学的 package.json

说的官方一点就是:setup.py 是 setuptools 的构建脚本。它告诉 setuptools 关于你的软件包(如名称和版本)以及要包含哪些代码文件。

一个基本的 setup.py 长这样:

from setuptools import setup

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

setup(
    name='packaging_tutorial',
    version='0.0.1',
    packages=setuptools.find_packages(),
    url='https://github.com/pypa/sampleproject',
    license='MIT',
    author='Example Author',
    author_email='author@example.com',
    description='A small example package',
    long_description=long_description,
    long_description_content_type="text/markdown",
    install_requires=['numpy'],
    classifiers=[
        "Programming Language :: Python :: 3",
        "License :: OSI Approved :: MIT License",
        "Operating System :: OS Independent",
    ],
    python_requires='>=3.6',
)

其实基本看名字就知道是些什么了,我们只说明几个特别的:

  • packages,这里可以写一个list,比如 packages=['example_pkg1', 'example_pkg2', ...],即你的目录里的 Python 包(带__init__.py的那种目录),也可以如官网建议的直接让 setuptools 给你去找。

  • long_description,我们从 README.md 里直接读取的 markdown 文档,所以把long_description_content_type 对于设置了 markdown。

  • install_requires,是你这个项目依赖的包,可以让 pip 安装你的包的时候检查依赖,如果依赖没有安装或版本不对,就把正确的依赖也一起装上。注意,这里的依赖必须是 pypi 里有的(即你可以用 pip install xxx 安装的)。要了解更多请看:install_requires vs requirements files

  • classifiers,就是给你的项目贴些标签,方便别人检索啦,可选的在这个目录里:pypi.org/classifiers…

setup.py 里还可以指定很多其他东西的,具体看文档:packaging.python.org/guides/dist…


写完 setup.py 其实我们就可以在自己的电脑上 pip 安装这个包了!

$ cd packaging_tutorial
$ pip3 install .
$ cd ~
$ python3
>>> import example_pkg    # 注意这里import的不是setup里的name,而是packages列表里的包名

如果本地安装没问题(我没遇到问题,不清楚有没有坑),接下来,我们把包就要上传到 Pypi 了。

注册 Pypi 账号

和 GitHub 一样哈,你得先注册一个号才能上传到 Pypi。

直接点这个链接注册:pypi.org/account/reg…

注册好之后,生成一个 token:pypi.org/manage/acco… scope 到特定的项目。

⚠️注意:token 生成出来以后不要马上关掉页面,不然就没了!!!把 token 复制粘贴保存到个本地的文件里(你要手抄我不反对,一百多位,别抄错就行 [狗头])。

然后,创建一个纯文本文件 $HOME/.pypirc (Windows 咋搞自行解决,我不用Windows),在里面写:

[pypi]
username = __token__
password = <换成你刚刚复制下来的 token, 包括 `pypi-` 前缀>

注意,不要把username改成你的用户名,就是写 username = __token__,固定der!因为我们是要用 token 嘛,所以用户是 __token__password = token 把 token 换成你的 token,注意不要换行,也不要加其他乱七八糟的空白字符(如果你要Windows的记事本,请小心BOM)。

例如:

[pypi]
username = __token__
password = pypi-BCqRT66666666kLTI1NjQzZGUJXsgElwaS576OnvGVIshizhegedeshisabiJzaW9uIjogMXC05ZzcIWlOs2lyTZCOCCCCU1NwACvbnL9IsWyPMiOiAidXiJBBBcmcicN0AAAYgCB82jrAI9RDJl5BJfK2333333

打包、上传

打包很简单:

$ cd packaging_tutorial
$ python setup.py sdist
$ tree .
.
├── LICENSE
├── README.md
├── packaging_tutorial.egg-info
│   ├── PKG-INFO
│   ├── SOURCES.txt
│   ├── dependency_links.txt
│   ├── requires.txt
│   └── top_level.txt
├── dist
│   └── packaging_tutorial-0.0.1.tar.gz
├── setup.py
└── example_pkg
    ├── __init__.py
    └── src.py

你会看见出来些 packaging_tutorial.egg-infodist 啦。如果你没兴趣,就不用管它们,把他们看成“编译”出来的二进制文件就好。这些也不用加版本管理里,你随时可以生成的。

然后就是上传了,这一步需要我们先安装一个 twine:

$ pip install twine

好了之后,用 twine 就可以把包上传到 pypi 了:

$ twine upload dist/*

当然,你可以只上传某个特定版本: twine upload dist/packaging_tutorial-0.0.1.tar.gz

如果失败,请检查你的网络,确保你可以上 pypi官网 (搞这些最好科学上网,不然我不知道能不能成);还有检查你的 $HOME/.pypirc,token 有没有写错。

上传完它就会输出一个 URL:https://pypi.org/project/<sampleproject>,打开就可以在 pypi 里看到你的项目了!

用 Pip 安装自己写的包

最后,换台计算机(我们自己的电脑上已经安装过了嘛,痛失贞洁了,不好玩了)。

在另一台机器上(安装了 python、pip的):

$ pip install packaging_tutorial

你可以看到下载、依赖处理、安装的过程。好了之后你就可以用自己写的包了:

$ python
>>> import example_pkg

最后

这篇文章只是对整个流程简要的记录和介绍,官方的这篇文章写了更完整的介绍:Packaging and distributing projects