一、setuptools介紹
Setuptools是Python Distutils的加強版,使開發者構建和發布Python包更加容易,特別是當包依賴於其他包時。用setuptools構建和發布的包與用Distutils發布的包是類似的。包的使用者無需安裝setuptools就可以使用該包。如果用戶是從源碼包開始構建,並且沒有安裝過setuptools的話,則只要在你的setup腳本中包含一個bootstrap模塊(ez_setup),用戶構建時就會自動下載並安裝setuptools了。
功能亮點:
- 利用EasyInstall自動查找、下載、安裝、升級依賴包
- 創建Python Eggs
- 包含包目錄內的數據文件
- 自動包含包目錄內的所有的包,而不用在setup.py中列舉
- 自動包含包內和發布有關的所有相關文件,而不用創建一個MANIFEST.in文件
- 自動生成經過包裝的腳本或Windows執行文件
- 支持Pyrex,即在可以setup.py中列出.pyx文件,而最終用戶無須安裝Pyrex
- 支持上傳到PyPI
- 可以部署開發模式,使項目在sys.path中
- 用新命令或setup()參數擴展distutils,為多個項目發布/重用擴展
- 在項目setup()中簡單聲明entry points,創建可以自動發現擴展的應用和框架
二、簡單的例子
python中安裝包的方式有很多種:
- 源碼包:python setup.py install
- 在線安裝:pip install 包名 / easy_install 包名
pip install的東西從哪里來的?
從PyPI (Python Package Index)來的,官網是: https://pypi.python.org/pypi
執行pip install terminaltranslator命令的時候,它就會去從官方網站搜terminaltranslator,搜到了就下載壓縮包並解壓安裝,如果沒有搜索到就會報錯。
1、源碼包安裝
源碼包安裝就是你在本地編寫好了一個模塊,自己安裝在本地使用,別人(即使是你自己)都不能 pip install xxx 下載你的模塊
1.准備工作
# 1.首先創建我們需要的目錄結構和文件(自行創建)
# 當前測試的目錄是: /tmp/demo
`-- demo |-- helloapp | |-- hello.py | `-- __init__.py |-- __init__.py |-- myapp | |-- __init__.py | `-- myapp.py `-- setup.py # 2.編輯 setup.py from setuptools import setup, find_packages setup( name="demo", version="1.0", author="zbj", author_email="22@qq.com", packages=find_packages(), ) # 3.編輯 hello.py def hello_func(): print("HelloWorld") # 4.編輯 myapp.py def myapp_func(): print("嘿嘿嘿")
2.源碼安裝
# 進入setup.py所在的那層目錄 cd /tmp/demo # 檢查setup.py 是否有錯誤(warning不是錯誤) python setup.py check # 安裝 python setup.py install
3.結果
打包之后多出兩個文件夾,分別是demo.egg-info和dist。demo.egg-info是必要的安裝信息,
而dist中的壓縮包就是安裝包,此時默認的egg包,egg包就是zip包,如果需要使用egg包,name將egg后綴改成zip解壓即可
4.測試
測試的時候需要注意導包路徑和當前所在路徑
目前所在路徑是: /tmp/demo
直接進入python解釋器: python3(我自己安裝的python3版本)
5.setuptools更多參數用法
https://setuptools.readthedocs.io/en/latest/setuptools.html
2、打包上傳到pypi
2-1、配置文件和打包
1.創建文件的目錄結構
hello/ |-- hello | |-- hello.py | `-- __init__.py |-- LICENSE |-- README.md `-- setup.py
2. setup.py
from setuptools import setup, find_packages setup( name="hello", version='1.0', description="Test Hello", url="None", author="zbj", author_email="22@qq.com", license="MIT", packages=find_packages() )
3. LICENSE
LICENSE代表許可證
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.
4. setuptools 和wheel
首先需要保證你有最新版的setuptools
和wheel
python -m pip install --user --upgrade setuptools wheel
Tip:如果出現問題了可以查看官網的解決方案:https://packaging.python.org/tutorials/installing-packages/
5. 打包模塊
# 進入到setup.py同級的目錄下 python setup.py sdist bdist_wheel
打包之后多出兩個文件夾,分別是hello.egg-info和dist。hello.egg-info是必要的安裝信息,而dist中的壓縮包就是安裝包
dist中包含兩個文件:
dist/
|-- hello-1.0-py3-none-any.whl
`-- hello-1.0.tar.gz
6.打包方式介紹
有了上面的 setup.py 文件,我們就可以打出各種安裝包,主要分為兩類:sdist 和 bdist。
Source distribution
使用 sdist 可以打包成 source distribution,支持的壓縮格式有:
Format | Description | Notes |
---|---|---|
zip | zip file (.zip) | Windows 默認 |
gztar | gzip’ed tar file (.tar.gz) | Unix 默認 |
bztar | bzip2’ed tar file (.tar.bz2) | |
xztar | xz’ed tar file (.tar.xz) | |
ztar | compressed tar file (.tar.Z) | |
tar | tar file (.tar) |
使用方式為:
$ python setup.py sdist --formats=gztar,zip
現在目錄下多出 dist 和 *.egg-info 目錄,dist 內保存了我們打好的包,上面命令使用 --formats
指定了打出 .tar.gz
和 .zip
包,如果不指定則如上表根據具體平台默認格式打包。
包的名稱為 setup.py
中定義的 name
, version
以及指定的包格式,格式如:firstApp-0.0.1.tar.gz。
Built distribution
使用 bdist 可以打出 built distribution,和源碼包相比,由於預先構建好,所以安裝更快:
Format | Description | Notes |
---|---|---|
gztar | gzipped tar file (.tar.gz) | Unix 默認 |
bztar | bzipped tar file (.tar.bz2) | |
xztar | xzipped tar file (.tar.xz) | |
ztar | compressed tar file (.tar.Z) | |
tar | tar file (.tar) | |
zip | zip file (.zip) | Windows 默認 |
rpm | RPM | |
pkgtool | Solaris pkgtool | |
sdux | HP-UX swinstall | |
wininst | self-extracting ZIP file for Windows | |
msi | Microsoft Installer. |
使用上,和 sdist 一樣,可以使用 --formats
指定包格式。如:
$ python setup.py bdist --formats=rpm
同時為了簡化操作,setuptools 提供了如下命令:
Command | Formats | Notes |
---|---|---|
bdist_dumb | tar, gztar, bztar, xztar, ztar, zip | Windows 默認 zip, Unix 默認 gztar |
bdist_rpm | rpm, srpm | |
bdist_wininst | wininst | |
bdist_msi | msi |
所以上面打 rpm 包可以使用:
$ python setup.py bdist_rpm
2-2、上傳到Pypi
此時前置打包的步驟已經完成,可以開始進行上傳。
1.利用twine
將包上傳上去,首先安裝twine
pip install twine
2.注冊 PyPI 賬號
登錄 https://pypi.python.org/pypi,注冊賬號
3.上傳
# 使用 upload $ twine upload dist/* 輸入 username 和 password 即上傳至 PyPI。 # 如果不想每次輸入賬號密碼,可以在家目錄下創建 .pypirc 文件,內容如下: [distutils] index-servers = pypi pypitest [pypi] username: password: [pypitest] repository: https://test.pypi.org/legacy/ username: password:
4. 檢驗
這時候就可以,下載包,然后運行里面方法了
pip install hello

在本地測試的時候可以直接安裝打包好的dist下的包:
pip install xxx.tag.gz
測試功能正常后再上傳到pypi
5. 更新版本
更新版本也很簡單,只需要修改setup.py下的version
然后重新生成檔案,上傳
python setup.py sdist bdist_wheel
twine upload dist/hello-0.0.2*
6.更新本地moudle版本
pip install --upgrade hello 或者是先卸載,再安裝 # 卸載hello pip uninstall hello # 安裝hello pip install hello
三、setuptools的進階使用
上面使用setuptools時只是簡單的用一個配置文件setup.py就完成了打包信息填寫。在真實的開發環境中,往往是多個文件配合。以openstack的打包為例。openstack中引入了Pbr的管理工具。
pbr是setuptools的輔助工具,最初為openstack開發,基於d2to1。Pbr會讀取和過濾setup.cfg中的內容,然后將解析后的數據提供給setup.py作為參數。 setup.cfg提供setup.py的默認參數,同時易於修改。Setup.py先解析setup.cfg文件,然后執行相關命令。包括以下功能: 1、從git中獲取Version,AUTHORS和ChangeLog信息 2、SphinxAutodoc。pbr會掃描project,找到所有模塊,生成stubfiles 3、Requirements。讀取requirements.txt文件,生成setup函數需要依賴包 4、long_description。從README.rst、README.txt或者READMEfile中生成long_description參數
Pbr的文件很簡單,如下。配置之后會自動尋找目錄下的setup.cfg文件,解析文件參數給setup.py使用。
https://docs.openstack.org/pbr/latest/user/using.html
setup.py
from setuptools import setup setuptools.setup( setup_requires=['pbr'], pbr=True)
setup.cfg
[metadata] name = my_package version = attr: src.VERSION description = My package description long_description = file: README.rst, CHANGELOG.rst, LICENSE.rst keywords = one, two license = BSD 3-Clause License classifiers = Framework :: Django License :: OSI Approved :: BSD License Programming Language :: Python :: 3 Programming Language :: Python :: 3.5 [files] packages = project_name data_files = etc/pbr = etc/pbr/* [global] setup-hooks = pbr.hooks.setup_hook [entry_points] console_scripts = project_name = project.cmd.mycmd:main [options] zip_safe = False include_package_data = True packages = find: scripts = bin/first.py bin/second.py install_requires = requests importlib; python_version == "2.7" [options.package_data] * = *.txt, *.rst hello = *.msg [options.extras_require] pdf = ReportLab>=1.2; RXP rest = docutils>=0.3; pack ==1.1, ==1.3 [options.packages.find] exclude = src.subpackage1 src.subpackage2 [options.data_files] /etc/my_package = site.d/00_default.conf host.d/00_default.conf data = data/img/logo.png, data/svg/icon.svg