本地 Python 代码上传到 Python 第三方库(Pypi)

程序员对于编程都有自己的“套路”,好的套路都会得到复用和 IT 界的传播。这时有一个疑问,怎样来实现呢?小编这里就准备介绍如何将自己写的 Python 包上传到 Python 官网的第三方库上,然后所有的人都可以使用 pip(/pip3) install package 下载。

在Python的世界里,有个叫Distutils的工具模块可以帮我们轻松的解决这个问题,既然这样,让我们开始打包之旅吧。

要打包代码,首先你的确保你的代码得是个包。这就需要你的文件夹下必须有一个init.py文件(如果使用 Pychram ,可以创建一个包,这个文件是自动生成的。)。剩余的就是将你这些代码放入到这个文件夹下面即可。整理成包的文件结构大概像下面这样:

package_zong
    |
    +-- LICENSE
    |
    +-- README.txt
    |
    +-- setup.py
    |
    +-- package1
    .       |
    .       +-- __init__.py
    .       |
    .       +-- myscripts1.py
    .       |
    .       +-- mysscripts2.py
    .       |
    .       +-- *************.py
    .       |
    .
    |
    +-- package2
    .       |
    .       +-- __init__.py
    .       |
    .       +-- myscripts1.py
    .       |
    .       +-- mysscripts2.py
    .       |
    .       +-- *************.py
    .       |
    .
    |
    +-- docs/
    |

哇,咋一看,这么多文件,其实不多,解释如下:

  • package_zong 这个文件夹就是存放下面很多文件和文件夹的,没有任何作用;
  • LICENSE 就是授权文件,里面是你关于这个包的授权,使用的是 MIT license 具体内容为:
MIT License

Copyright (c) 2018 lichanghong

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
  • README.txt,这个文件想必研发都应该清楚。如果有,尽量放些东西在这里了,后面如果可能我们会用到它的。需要注意的是,Windows的回车和Linux不一样,所以建议用Windows的好了;
  • setup.py,核心文件,这里面的内容马上我们会讲;
  • package1、package2 (可以有 n 个,就是有 n 个包)就是你包的名称,包里面myscripts*.py的各种文件就是你原有的各种代码模块(类似这样的 .py 文件可以有 n 个,也就是有 n 个模块)。 init.py文件(文件内容可以为空)就表明了当前文件夹是一个包;
  • docs/,这个文件夹你放你的documents吧,不过要用心写文档真是个难事。如果你只是做测试,这个文件夹可以不存在。

下面介绍核心文件 setup.py(上传到 Pypi 的主要文件):
具体内容如下:

import codecs
import os
import sys
try:
    from setuptools import setup
except:
    from distutils.core import setup

def read(fname):
    return codecs.open(os.path.join(os.path.dirname(__file__), fname)).read()

NAME = "wenyali_pypi_test"
PACKAGES = ['package1','package2']
DESCRIPTION = "this is a test for package by myself upload to pypi"
LONG_DESCRIPTION = "this is a test for package by myself upload to pypi"
KEYWORDS = "keyword"
AUTHOR = "wenyali"
AUTHOR_EMAIL = "2917073217@qq.com"
URL = "https://github.com/lichanghong/wenyali.git"
VERSION = "1.0.0"
LICENSE = "MIT"
setup(
    name =NAME,version = VERSION,
    description = DESCRIPTION,long_description =LONG_DESCRIPTION,
    classifiers =[
        'License :: OSI Approved :: MIT License',
        'Programming Language :: Python',
        'Intended Audience :: Developers',
        'Operating System :: OS Independent',
    ],
    keywords =KEYWORDS,author = AUTHOR,
    author_email = AUTHOR_EMAIL,url = URL, 
    packages = PACKAGES,include_package_data=True,zip_safe=True,
    entry_points={
      "console_scripts": [
                          "wenyali_console = package1.index:index",
                          ]
      },

)

setup.py 文件内容的解释:

  • setup 库 是打包的过程中必须引入的;
  • read 方法 我们一般是将README文件中的内容读取出来作为长描述:
    这个会在PyPI中你这个包的页面上展现出来;
    你也可以不用这个方法,自己手动写内容即可;
    PyPI上支持.rst格式的文件。暂不支持.md格式的文件,<BR>.rst文件PyPI会自动把它转为HTML形式显示在你包的信息页面上;
  • NAME :名字,一般放你包的名字即可,在遵循 pypi 的相关规则下,可以随意名名;
  • PACKAGES : 包含的包,可以多个,这是一个列表;
  • DESCRIPTION :关于这个包的描述;
  • LONG_DESCRIPTION:参见read方法说明;
  • KEYWORDS :关于当前包的一些关键字,方便PyPI进行分类;
  • AUTHOR :包作者的名字;
  • AUTHOR_EMAIL :作者的邮箱;
  • URL:你这个包的项目地址,如果有,给一个吧,没有你直接填写在PyPI你这个包的地址也是可以的;
  • VERSION:当前包的版本,这个按你自己需要的版本控制方式来;
  • LICENSE:授权方式,我喜欢的是MIT的方式,你可以换成其他方式:

你如果需要写一个 setup.py 文件,上面的复制一下,把信息改成你的就可以了。
需要注意的是:

  • 文中的 classifiers 的内容并不是随便填写的,你需要参照本文参考文档中的PyPI Classifiers来写。
  • entry_points 这个关键字是定义了控制台脚本,意思就是可以使用该工具,不需要在 python 环境下运行。里面涉及到很多的参数,具体的内容请自行查询资料。

运行文件到 Pypi

在命令行中,切换路径到 package_zong 文件夹下
下面是运行包上传的三行命令(本人使用的是 python 3 的软件环境):

 python3 setup.py check 

说明:输出一般是running check,如果有错误或者警告,就会在此之后显示,没有任何显示表示Distutils认可你这个setup.py文件。

python3 setup.py sdist

说明:命令执行后会输出打包的状态,你可以进行查看
如果有warning的话,你可以稍后返回修改对应的地方后,重新打包
如果正常的情况下,你应该可以在你的根目录下看到一个dist/的文件夹
文件夹里面包含了当前打包出来的一个.zip文件。或者.tar.gz文件。

twine upload dist/*

说明:将dist 下的所有文件上传到 Pypi,稍后你会输入用户名和密码。
这里有几个常出现问题:

  • 首先需要您去 https://pypi.org/ 官网注册一个账号,这个是必须的。
  • 不建议使用 python setup.py register sdist upload 这个是会报 ssl 错误。
  • setup.py 文件中 NAME 名字一定要符合规范,否则报 403 错误,这个时候需要删掉 dist 文件夹,然后需要重新打包,具体的规范可以查看 https://pypi.org/help/#project-name

下载上传的包到本地并运行测试

pip install wenyali_pypi_test(这个根据你自己设置的包名) 
# 进行 python3 环境下
from package1 import myscripts1,myscripts2
# 接着可以运行myscripts1 或者myscripts2里面的函数,例如运行main函数:
myscripts2.main()

如果你在 setup.py 文件中添加了entry_points ,那么你可以在不进入 python3 环境下,直接运行:

wenyali_console

这个结果具体是看您调用了哪些方法,我是调用了 package1 包下 index 模块下的 index 方法,具体参看为:

 entry_points={
      "console_scripts": [
                          "wenyali_console = package1.index:index",
                          ]
      },

点赞