上传py模块到pypi

1. 在pypi官网(https://pypi.org)注册并完成账号认证。

2. 在本地创建Python项目。

项目组成包括:

tests文件夹,里面是空的就可以

kcodepen.py 准备上传的模块文件。我在kcodepen中定义了四个函数,分别用来绘制方形、圆形、三角形和五角星:

 

LICENSE 证书文件。文件的内容在pypi的官方指导文档有说明,直接复制粘贴即可:

Copyright (c) 2018 The Python Packaging Authority

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.

 READMD.md 对要上传模块的说明,这些说明到时候会显示在pypi官网上供下载时对模块内容进行了解。文件的内容在pypi的官方指导文档有说明,直接复制粘贴即可:

# Example Package

This is a simple example package. You can use
[Github-flavored Markdown](https://guides.github.com/features/mastering-markdown/)
to write your content.

setup.py 对要上传的模块进行编译处理。setup.py的总体内容在pypi的官方指导文档有说明,在此基础上我做了一些更改:

import setuptools

with open("README.md", "r") as fh:
    long_description = fh.read()  # 读取README.MD中的说明

setuptools.setup(name="pykcode", # 这个是显示在PYPI中的名称,使用pip安装时也是这个名称
                 version="0.0.5",# 版本号,做pip install --upgrade的时候有用
                 author="piglite", # 作者
                 author_email="xxx@xxx.com", 
                 description="test package",
                 long_description=long_description, #传入README.MD中的说明内容
                 long_description_content_type="text/markdown",
                 url="https://github.com/piglite",
                 packages=setuptools.find_packages(),
                 classifiers=[
                     "Programming Language :: Python :: 3",
                     "License :: OSI Approved :: MIT License",
                     "Operating System :: OS Independent",
                 ],
                 python_requires='>=3.6',
                 py_modules=['kcodepen'] #要上传的模块,也就是项目中的kcodepen.py
) 

setup 函数常用的参数如下:

参数说明
name包名称
version包版本
author程序的作者
author_email程序的作者的邮箱地址
maintainer维护者
maintainer_email维护者的邮箱地址
url程序的官网地址
license程序的授权信息
description程序的简单描述
long_description程序的详细描述
platforms程序适用的软件平台列表
classifiers程序的所属分类列表
keywords程序的关键字列表
packages需要处理的包目录(通常为包含 __init__.py 的文件夹)
py_modules需要打包的 Python 单文件列表
download_url程序的下载地址
cmdclass添加自定义命令
package_data指定包内需要包含的数据文件
include_package_data自动包含包内所有受版本控制(cvs/svn/git)的数据文件
exclude_package_data当 include_package_data 为 True 时该选项用于排除部分文件
data_files打包时需要打包的数据文件,如图片,配置文件等
ext_modules指定扩展模块
scripts指定可执行脚本,安装时脚本会被安装到系统 PATH 路径下
package_dir指定哪些目录下的文件被映射到哪个源码包
requires指定依赖的其他包
provides指定可以为哪些模块提供依赖
install_requires安装时需要安装的依赖包
entry_points动态发现服务和插件,下面详细讲
setup_requires指定运行 setup.py 文件本身所依赖的包
dependency_links指定依赖包的下载地址
extras_require当前包的高级/额外特性需要依赖的分发包
zip_safe不压缩包,而是以目录的形式安装

更多参数可见:https://setuptools.readthedocs.io/en/latest/setuptools.html

find_packages函数

对于简单工程来说,手动增加 packages 参数是容易。而对于复杂的工程来说,可能添加很多的包,这是手动添加就变得麻烦。Setuptools 模块提供了一个 find_packages 函数,它默认在与 setup.py 文件同一目录下搜索各个含有 __init__.py 的目录做为要添加的包。

find_packages(where='.', exclude=(), include=('*',))

find_packages 函数的第一个参数用于指定在哪个目录下搜索包,参数 exclude 用于指定排除哪些包,参数 include 指出要包含的包。

默认情况下 setup.py 文件只在其所在的目录下搜索包。如果不用 find_packages,想要找到其他目录下的包,也可以设置 package_dir 参数,其指定哪些目录下的文件被映射到哪个源码包,如: package_dir={'': 'src'} 表示 “root package” 中的模块都在 src 目录中。

包含数据文件

  • package_data:

该参数是一个从包名称到 glob 模式列表的字典。如果数据文件包含在包的子目录中,则 glob 可以包括子目录名称。其格式一般为 {'package_name': ['files']},比如:package_data={'mypkg': ['data/*.dat'],}

  • include_package_data:

该参数被设置为 True 时自动添加包中受版本控制的数据文件,可替代 package_data,同时,exclude_package_data 可以排除某些文件。注意当需要加入没有被版本控制的文件时,还是仍然需要使用 package_data 参数才行。

  • data_files:

该参数通常用于包含不在包内的数据文件,即包的外部文件,如:配置文件,消息目录,数据文件。其指定了一系列二元组,即(目的安装目录,源文件) ,表示哪些文件被安装到哪些目录中。如果目录名是相对路径,则相对于安装前缀进行解释。

  • manifest template:

manifest template 即编写 MANIFEST.in 文件,文件内容就是需要包含在分发包中的文件。一个 MANIFEST.in 文件如下:

include *.txt
recursive-include examples *.txt *.py
prune examples/sample?/build

MANIFEST.in 文件的编写规则可参考:https://docs.python.org/3.6/distutils/sourcedist.html

生成脚本

有两个参数 scripts 参数或 console_scripts 可用于生成脚本。

entry_points 参数用来支持自动生成脚本,其值应该为是一个字典,从 entry_point 组名映射到一个表示 entry_point 的字符串或字符串列表,如:

setup(
    # other arguments here...
    entry_points={
        'console_scripts': [
            'foo=foo.entry:main',
            'bar=foo.entry:main',
        ],    
    }
)

scripts 参数是一个 list,安装包时在该参数中列出的文件会被安装到系统 PATH 路径下。如:

scripts=['bin/foo.sh', 'bar.py']

用如下方法可以将脚本重命名,例如去掉脚本文件的扩展名(.py、.sh):

from setuptools.command.install_scripts import install_scripts

class InstallScripts(install_scripts):

    def run(self):
        setuptools.command.install_scripts.install_scripts.run(self)

        # Rename some script files
        for script in self.get_outputs():
            if basename.endswith(".py") or basename.endswith(".sh"):
                dest = script[:-3]
            else:
                continue
            print("moving %s to %s" % (script, dest))
            shutil.move(script, dest)

setup(
    # other arguments here...
    cmdclass={
        "install_scripts": InstallScripts
    }
)

其中,cmdclass 参数表示自定制命令,后文详述。

ext_modules

ext_modules 参数用于构建 C 和 C++ 扩展扩展包。其是 Extension 实例的列表,每一个 Extension 实例描述了一个独立的扩展模块,扩展模块可以设置扩展包名,头文件、源文件、链接库及其路径、宏定义和编辑参数等。如:

setup(
    # other arguments here...
    ext_modules=[
        Extension('foo',
                  glob(path.join(here, 'src', '*.c')),
                  libraries = [ 'rt' ],
                  include_dirs=[numpy.get_include()])
    ]
)

详细了解可参考:https://docs.python.org/3.6/distutils/setupscript.html#preprocessor-options

zip_safe

zip_safe 参数决定包是否作为一个 zip 压缩后的 egg 文件安装,还是作为一个以 .egg 结尾的目录安装。因为有些工具不支持 zip 压缩文件,而且压缩后的包也不方便调试,所以建议将其设为 False,即 zip_safe=False

自定义命令

Setup.py 文件有很多内置的的命令,可以使用 python setup.py --help-commands 查看。如果想要定制自己需要的命令,可以添加 cmdclass 参数,其值为一个 dict。实现自定义命名需要继承 setuptools.Command 或者 distutils.core.Command 并重写 run 方法。

from setuptools import setup, Command

class InstallCommand(Command):
    description = "Installs the foo."
    user_options = [
        ('foo=', None, 'Specify the foo to bar.'),
    ]
    def initialize_options(self):
        self.foo = None
    def finalize_options(self):
        assert self.foo in (None, 'myFoo', 'myFoo2'), 'Invalid foo!'
    def run(self):
        install_all_the_things()

setup(
    ...,
    cmdclass={
        'install': InstallCommand,
    }
)

依赖关系

如果包依赖其他的包,可以指定 install_requires 参数,其值为一个 list,如:

install_requires=[
    'requests>=1.0',
    'flask>=1.0'
]

指定该参数后,在安装包时会自定从 pypi 仓库中下载指定的依赖包安装。

此外,还支持从指定链接下载依赖,即指定 dependency_links 参数,如:

dependency_links = [
    "http://packages.example.com/snapshots/foo-1.0.tar.gz",
    "http://example2.com/p/bar-1.0.tar.gz",
]

分类信息

classifiers 参数说明包的分类信息。所有支持的分类列表见:https://pypi.org/pypi?%3Aaction=list_classifiers

示例:

classifiers = [
    # 发展时期,常见的如下
    #   3 - Alpha
    #   4 - Beta
    #   5 - Production/Stable
    'Development Status :: 3 - Alpha',

    # 开发的目标用户
    'Intended Audience :: Developers',

    # 属于什么类型
    'Topic :: Software Development :: Build Tools',

    # 许可证信息
    'License :: OSI Approved :: MIT License',

    # 目标 Python 版本
    'Programming Language :: Python :: 2',
    'Programming Language :: Python :: 2.7',
    'Programming Language :: Python :: 3',
    'Programming Language :: Python :: 3.3',
    'Programming Language :: Python :: 3.4',
    'Programming Language :: Python :: 3.5',
]

 

3. 利用setup.py构建和编译项目:

 

setup.py 文件有很多内置命令可供使用,查看所有支持的命令:

python setup.py --help-commands

此处列举一些常用命令:

  • build:

构建安装时所需的所有内容

  • sdist:

构建源码分发包,在 Windows 下为 zip 格式,Linux 下为 tag.gz 格式 。执行 sdist 命令时,默认会被打包的文件:

所有 py_modules 或 packages 指定的源码文件
所有 ext_modules 指定的文件
所有 package_data 或 data_files 指定的文件
所有 scripts 指定的脚本文件
README、README.txt、setup.py 和 setup.cfg文件

该命令构建的包主要用于发布,例如上传到 pypi 上。

  • bdist:

本例中,显示你用build构建项目:

python setup.py build

注意,终端输入命令时,目录保持在setup.py所在文件夹

编译项目:

python setup.py sdist

如果除了提供压缩文件还想提供.whl文件的话,可以用如下指令:

python setup.py sdist bdist_wheel

此时,被编译好的文件在项目文件夹的dist文件夹下:

 

4. 在本地创建PYPI的账号信息文件。信息文件保存在登录用户文件夹下(例如:users/Adiministrator),文件名称是 .pypirc

编辑 .pypirc

[distutils]
index-servers = pypi

[pypi]
username: pypi注册时的用户名
password: pypi注册时的密码

5. 上传到PYPI

利用pip安装或更新上传工具twine

pip install --upgrade twine

利用twine上传项目文件夹中dist下的内容:

twine upload dist/*

注意,在终端输入twine upload dist/* 指令时,也应该在setup.py所在文件夹中。

6. 上传成功后,在PYPI.org搜索就可以看到自己刚刚上传的内容。上传时我使用的名称(name)是pykcode

7. 可以使用pip install进行安装或更新:

pip install --upgrade pykcode

8. 在项目中使用,导入时要使用写在setup.py中py_modules里面的内容: 

import kcodepen
import turtle

t = turtle.Turtle()
kcodepen.star(t, 100)

turtle.done()

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值