上傳自己的模塊到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文件夾同級目錄
注意事項
- 項目內部採用工程名(模塊名,包名)開頭的方式導入模塊,比如: from project_name.xxx import abc,不然外部安裝成功後,使用也會報錯
- 項目根目錄下需要有
__init__.py
文件,且如果需要將指定目錄打包,對應目錄下也需要有此文件 - 儘量不要用相對路徑方式導入,儘量使用
項目名.模塊名
方式導入 - 如果要加載配置文件,代碼裏面使用絕對路徑方式:使用
項目名__file__
取路徑 或者項目名.__path__[0]
來得到絕對路徑 - 非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='[email protected]',
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方法上傳