上传自己的模块到pypi,可以用pip安装,方便自己和其他人使用

打包结构如下图所示

├── project_name  # 工程文件夹,所有代码文件存放目录
│   ├── a.py
│   ├── b.py
│   ├── __init__.py  # 这个文件不能少
│   ├── dir
│   │   ├── d.py
│   │   ├── e.py
│   │   ├── f.zip
│   │   └── __init__.py
│   ├── README.md
│   └── requirements.txt
└── setup.py  # 用于打包配置的代码,与project_name文件夹同级目录

注意事项

  1. 项目内部采用工程名(模块名,包名)开头的方式导入模块,比如: from project_name.xxx import abc,不然外部安装成功后,使用也会报错
  2. 项目根目录下需要有 __init__.py 文件,且如果需要将指定目录打包,对应目录下也需要有此文件
  3. 尽量不要用相对路径方式导入,尽量使用 项目名.模块名 方式导入
  4. 如果要加载配置文件,代码里面使用绝对路径方式:使用 项目名__file__ 取路径 或者 项目名.__path__[0]来得到绝对路径
  5. 非py文件需要在 setup.py 的 data_files 参数里面配置,不然打包时所需的 配置文件、模型文件不会被打包

生成安装文件

先到pypi官网 https://pypi.org/搜索一下项目是否重名

setup.py

from setuptools import find_packages, setup

name = 'img_classifier'
requires_list = open(f'{name}/requirements.txt', 'r', encoding='utf8').readlines()
requires_list = [i.strip() for i in requires_list]

setup(
    name=name,  # 包名同工程名,这样导入包的时候更有对应性
    version='1.0.0',
    author="Jayson",
    author_email='jaysonteng@163.com',
    description="encapsulate logger",
    python_requires="==3.7.*",
    packages=find_packages(),
    package_data={"": ["*"]},  # 数据文件全部打包
    include_package_data=True,  # 自动包含受版本控制(svn/git)的数据文件
    zip_safe=False,
    # data_files=['img_classifier/config/conf.yaml',
    #             'img_classifier/models/flag.pt',
    #             'img_classifier/people_model/face.lib',
    #             'img_classifier/porn_model/porn_classifier_model.onnx'
    #             ]
    
    # 设置依赖包
    install_requires=requires_list
)

–name 包名称
–version (-V) 包版本
–author 程序的作者
–author_email 程序的作者的邮箱地址
–maintainer 维护者
–maintainer_email 维护者的邮箱地址
–url 程序的官网地址
–license 程序的授权信息
–description 程序的简单描述
–long_description 程序的详细描述
–platforms 程序适用的软件平台列表
–classifiers 程序的所属分类列表
–keywords 程序的关键字列表
–packages 需要处理的包目录(包含__init__.py的文件夹)
–py_modules 需要打包的python文件列表
–download_url 程序的下载地址
–cmdclass
–data_files 打包时需要打包的数据文件,如图片,配置文件等
–scripts 安装时需要执行的脚步列表
–package_dir 告诉setuptools哪些目录下的文件被映射到哪个源码包。一个例子:package_dir = {’’: ‘lib’},表示“root package”中的模块都在lib 目录中。
–requires 定义依赖哪些模块
–provides定义可以为哪些模块提供依赖
–find_packages() 对于简单工程来说,手动增加packages参数很容易,刚刚我们用到了这个函数,它默认在和setup.py同一目录下搜索各个含有 init.py的包。
其实我们可以将包统一放在一个src目录中,另外,这个包内可能还有aaa.txt文件和data数据文件夹。另外,也可以排除一些特定的包
find_packages(exclude=[".tests", ".tests.", "tests.", “tests”])
–install_requires = [“requests”] 需要安装的依赖包
–entry_points 动态发现服务和插件,下面详细讲

MANIFEST.in 文件

由于 data_files 参数即将被弃用,所以后续需要使用此方法
include_package_data = True  # setup中这个参数必须声明

MANIFEST.in文件与setup.py文件在同一层目录

# 然后在 MANIFEST.in 中代码格式如下,进行文件的操作
include *.txt  # 包含文件
recursive-include examples *.txt *.py  # 递归查找这三个类型文件,多个文件用空格隔开
prune examples/sample?/build  # 排除此文件

打包安装

python setup.py build   # build可以省略

python setup.py sdist   ## dist目录下生成了最终的压缩包(默认格式tar.gz),可以指定压缩包类型通过指定参数  --formats=zip,gztar...  参考链接:https://docs.python.org/3.7/distutils/sourcedist.html

cd dist

解压:tar -zxvf **.tar.gz   # 也可以不解压,通过easy_install 来直接安装,ps:通过easy_install安装的卸载相对麻烦些

python setup.py build   # build可以省略

python setup.py install # 安装模块

python setup.py develop # 调试模式,不会真正安装,生成一个软链接,这边更新以后,导入的包会随之更新,方便调试

这种方式安装较麻烦,并且包含的文件有重复的情况,在package/包/根目录下面有重复的data_files的文件

安装后,包名下划线会被转换为短横线,在pip list中可以看到

使用下面命令生成 egg 包:

python setup.py bdist_egg

或者生成 whl 包:

python setup.py bdist_wheel  # 在dist目录下生成 *.whl文件
python3 setup.py sdist bdist_wheel  # 可以wheel和源文件同时生成
pip install *whl

其他格式打包

python setup.py bdist_wininst  # 生成windows .exe 可执行文件
python setup.py bdist_rpm  # 实现linux rpm 包的构建

上传

典型的 .pypirc 文件

可以配置到$HOME/.pypirc文件中,就不用多次输入了。window: C:\Users\用户名\.pypirc

上传方式1,不推荐,用户密码容易被劫持

[distutils]
index-servers = pypi

[pypi]
repository = https://upload.pypi.org/legacy/
username:xxx
password:xxx

[pypitest]
repository: https://test.pypi.org/legacy/  # 测试平台
username: your_username
password: your_password
# 然后使用这条命令进行信息注册,完成后,你可以在 PyPi 上看到项目信息。
python setup.py register

# 注册完了后,你还要上传源码包,别人才使用下载安装
python setup.py upload  # 默认上传到正式平台
python setup.py upload -r pypi  # 正式平台
python setup.py upload -r pypitest  # 测试平台
python setup.py sdist upload -r pypi # 一步创建发布

上传方式2,推荐

或者也可以使用 twine 工具注册上传

pypi官网:https://pypi.org/

去官网注册个账号

使用 twine 上传自己的 python 包到 pypi

# 安装twine
pip install twine

# 打包检查
python setup.py check

# 打包
python3 setup.py sdist build

# 上传
twine upload dist/*

# .pypirc文件只需要下面内容
[pypi]
username:xxx
password:xxx

# 下载安装
pip install name  # name是setup里面name对应的名字

twine 提示输入 pypi 账号和密码,上传成功否就能在自己的pypi账号中看到了。

但是并不是马上就能使用 pip 安装了。需要等待一段时间。

如果要更新原版,除了pip uninstall外,还需要删除原来缓存的文件,不然不会下载新的。

如果更新了版本号,就不存在这种情况

windows路径:C:\Users(自己的用户名)\AppData\Roaming\Python\Python35\site-packages

linux路径:~/.cache/pip

报错

## 1
ValueError: pypitest not found in .pypirc
解决方法: 将其放到根目录

## 2
configparser.NoSectionError: No section: 'pypi pypitest'
解决方法: 需要配置
[distutils] 
index-servers = 
    pypi
    pypitest
注意需要用上面的格式,换行

## 3
Server response (410): Project pre-registration is no longer required or supported, upload your files instead.
解决方法:别使用python setup.py register、upload方法,使用twine方法上传

参考链接:https://www.cnblogs.com/leffss/p/12029963.html

posted on 2021-09-03 10:02  jaysonteng  阅读(1393)  评论(0编辑  收藏  举报