封装我们自己写好的python包然后分享到网络提供给大家使用, 这本来是一个基本操作. 但是之前个人没有主动上传过自己封装的库到pypi, 正好趁这次自己封装简单包提供给大家用的机会, 来尽可能完整的实践了这一过程, 并在过程中踩了一些坑, 这里记录一下踩坑的过程.
django-jaeger-middleware/
├── django_jaeger_middleware # 这个包是我们核心代码区, 是我们安装包的主体文件,需要我们首先准备好
│ ├── __init__.py
│ ├── metadata.py
│ └── middleware.py
├── LICENSE # LICENSE, README.md, setup.py 这些是我们要打包发布的辅助文件
├── README.md
└── setup.py
1 directory, 6 files
setup.py 的文件
from setuptools import setup, find_packages
# 这下面几行是做了小小的封装, 可以先跳过直接看 `setup()` 函数部分
MIDDLEWARE_BASE_DIR = os.path.abspath(os.path.dirname(__file__))
meta_file = open(os.path.join(MIDDLEWARE_BASE_DIR, "django_jaeger_middleware", "metadata.py")).read()
md = dict(re.findall(r"__([a-z]+)__\s*=\s*'([^']+)'", meta_file)) # 读取 metadata.py 文件
with open(os.path.join(MIDDLEWARE_BASE_DIR, 'README.md')) as f:
long_description = f.read()
setup(
name='django-jaeger-middleware',
license='MIT',
version=md['version'],
description='在这里写对封装的这个包的简单描述',
long_description=long_description, # 详细描述,习惯上内容取自`README.md`文件
long_description_content_type="text/markdown",
author=md['author'],
author_email=md['authoremail'],
url="https://github.com/GalphaXie/django-jaeger-middleware", # 主页
download_url='https://github.com/GalphaXie/django-jaeger-middleware',
packages=find_packages(),
install_requires=[
"jaeger_client", # 封装的包所依赖的基础三方库
],
keywords=['django', 'jaeger', 'jaegertracing'],
classifiers=[
"Framework :: Django",
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
],
python_requires='>=3.6',
zip_safe=False
)
有关字典参数的详细信息,可以参阅官方网站:
1.pypi官方网站对应描述
2.python官方网站对应描述
还有更方便的方式, 就是参考一些成熟的模块的写法进行模仿; 当然,你也可以看看我的这个模块主页
setup.py
模块是否语法正确执行 $ python3 setup.py check
后, 查看控制台, 当出现:
running check
表示正确. 可以继续进行下一步:
README.md
和 LICENSE
内容提示: 参考其他人的优秀写法, LICENSE 基本找一个官方的三方库复制过来即可
xxx.tar.gz
传递, 不能使用 pip 安装# 构建模块
python3 setup.py build # 会多出一个 build 的目录
# 生成发布压缩包
python3 setup.py sdist # 会多出一个 dist 目录 和 一个 django_jaeger_middleware.egg-info 目录
注意:要制作哪个版本的模块,就使用哪个版本的解释器执行!
当前的目录结构:
├── build
│ └── lib
│ └── django_jaeger_middleware
│ ├── __init__.py
│ ├── metadata.py
│ └── middleware.py
├── dist
│ └── django-jaeger-middleware-1.0.0.tar.gz
├── django_jaeger_middleware # 原始目录
│ ├── __init__.py
│ ├── metadata.py
│ └── middleware.py
├── django_jaeger_middleware.egg-info
│ ├── dependency_links.txt
│ ├── not-zip-safe
│ ├── PKG-INFO
│ ├── requires.txt
│ ├── SOURCES.txt
│ └── top_level.txt
├── LICENSE
├── README.md
└── setup.py
6 directories, 16 files
安装模块
tar -zxvf 模块名 -C 要解压到的目录
例如: tar -zxvf django-jaeger-middleware-1.0.0.tar.gz 解压到当前目录. 可能你需要类似`site-packages` 这样的目录
python3 setup.py install
卸载模块
rm -r xxx
即可.安装setuptools
和wheel
模块, 如果之前已经安装可以更新到最新, 统一执行官网的
python3 -m pip install --user --upgrade setuptools wheel
python3
或 python
或 python2
, 选择的是那个版本的解释器, 后面编译出来的就是对应的OS + python
的版本.python
解释器版本的问题, 请根据需要调整解释器版本.python3 setup.py sdist bdist_wheel
正确执行后的目录结构是:
.
├── build
│ ├── bdist.linux-x86_64
│ └── lib
│ └── django_jaeger_middleware
│ ├── __init__.py
│ ├── metadata.py
│ └── middleware.py
├── dist
│ ├── django_jaeger_middleware-1.0.0-py3-none-any.whl
│ └── django-jaeger-middleware-1.0.0.tar.gz
├── django_jaeger_middleware
│ ├── __init__.py
│ ├── metadata.py
│ └── middleware.py
├── django_jaeger_middleware.egg-info
│ ├── dependency_links.txt
│ ├── not-zip-safe
│ ├── PKG-INFO
│ ├── requires.txt
│ ├── SOURCES.txt
│ └── top_level.txt
├── LICENSE
├── README.md
└── setup.py
7 directories, 17 files
twine
, 执行python3 -m pip install --user --upgrade twine
pypi测试账号
, 如果没有需要先去官网注册 注意: 这是测试官网python3 -m twine upload --repository-url https://test.pypi.org/legacy/ dist/*
填坑实录
: 当然, 我在这里踩了一个坑, 然后给 pypi
提了一个 issue, 可点击这里查看.下面是具体的过程我在执行改命令行的时候出现报错:
ModuleNotFoundError: No module named 'keyring.util.escape'
, 我详细看了整个报错.
0.先介绍一下我出错的环境: Ubuntu18.04的系统, python 3.6.9, pip 19.0.1的版本.
1.尝试读一下keyring
源码, 简单阅读之后没有发现更好的线索.
2.瞎折腾, 没有结果.
3.看到发布工具是twine
胡乱想到 在 ubuntu 系统下安装有些 win的工具时候是需要, 安装wine
工具的, 所以我就怀疑是不是这个发布只能在 win 下面操作, 而不能在 ubuntu下. 虽然这个看起来不那么合理, 但是也只能在 win系统下尝试一下, 死马当做活马医好了. 当然, 这个过程耗费了大量的时间和心情.
4.在win下测试, 我想起来要仔细的查看之前每一个命令的执行过程, 确实没有发现什么问题. 还把过执行过程中的几个warnning
给依次的处理掉了, 果然这一遍就比较顺利, 执行预发布的过程的时候就顺利进入到输入 pypi 账号密码的环节了. (具体处理的winning
有 pip 的升级问题; 某个脚本的环境变量问题,尤其是这个环境变量问题.
5.上面的环境变量问题给了我启示, 我想确认是否是在ubuntu下是我忽略了某些python三方库的脚本没有在全局的python解释器环境中. 遂 重复上面的详细的步骤, 然后观察每一步输出到控制台的结果. 但是, 我并没有发现什么蛛丝马迹.
6.报错bug依然出现. 所以我不得已认真去看谷歌中, 昨天没有认真看的一篇帖子(帖子地址), 在一番迫不得已的耐心寻找下我终于找到了蛛丝马迹. 让我对我安装的keyrings
库的版本问题产生了合理怀疑, 结合pip3 install --upgrade keyrings.alt
命令, 我做了尝试.
1.python3 -m pip install keyring
# 安装
2.正确安装后, 进入python3解释器, 试图导入 import keyring
报相同的错误
3.然后执行:
python3 -m pip install --upgrade keyrings.alt
4.正确执行后, 进入python3解释器, 试图导入 import keyring
, 控制台终于没有再报错;我继续执行 import keyring.util.escape
, 又继续报错.
5.然后我就根据上面的操作合理推测, 是不是要单独安装keyring.util
和 keyring.util.escape
这两个包. 但是, 安装的时候发现并没有这两个包单独存在于 pypi
仓库. 同时, 我还使用 dir(keyring)
和dir(keyring.util)
来注意观察 keyring
这个包是否有 对应的属性和方法. 发现是: keyring.util
这个属性是存在的.
6.当我再视图查看 是否有keyring.util.escape
的时候, dir
出现了一堆结果, 我就不看了. 继续从原始的上传命令着手 python3 -m twine upload --repository-url https://test.pypi.org/legacy/ dist/*
, 终于这行命令也不在报错了.
pypi测试官网
之后, 我们可以进行下载安装,看看是否正确,执行: python3 -m pip install --index-url https://test.pypi.org/simple/ --no-deps example-pkg
--no-deps
是说忽略掉 你要安装的包所需要的其他依赖包. (解释一下这个"坑": 我们自己包目前是分享到pypi的测试服
, 而如果我们自己包中依赖了其它的三方库, 这些三方的库不一定在 pypi测试服
上面有对应的安装包, 我们就需要忽略这些报错. 如果不加该参数那么会报找不到依赖包
的错误.)successful
的时候, 我们可以进入python解释器执行import example
, 当导入example-pkg
不报No module
即可, 因为有可能报 xxx包 no module
的错误, 忽略即可.twine upload dist/*
上传即可, 不需要再指定 url.gitignore
的写法, 可以参考这里pip install -e git+https://{deploy token}@git.ucloudadmin.com/securityhouse/pyservice/django-jaeger-middleware.git#egg=1.0.0
{deploy token}
对应的是 name:password
, 注意去掉 {}
egg=tag名
,tag需要由最新的master分支创建; 也可对应setup.py中的包名, 我的示例中是 1.0.0
#egg=1.0.0
部分替换成@你的分支名#egg=包名
. 不易不要漏掉对应的各个符号.deploy token
否则报错参考资料:
本文例子的URL: