如果您曾經使用setup.py腳本發布過一個Python包,那么您可能會發現編寫腳本來發布包比編寫包本身要困難。
Python 開發人員認識到了這一點,并且有一些工具采用了一種更現代的方法來構建包。Poetry 和 Flit 是構建Python 包的兩種流行工具。
(此處已添加圈子卡片,請到今日頭條客戶端查看)因為我使用了Poetry作為一個Python依賴性管理工具,所以我決定玩轉它的包管理功能。
為了獲得使用Poetry發布包的實踐經驗,我最近發布了Flake8 Markdown,一個用 Flake8 在Markdown文件中lint Python 代碼的工具。
本文將介紹我對Flake8 Markdown的pyproject.toml和codebase所做的更改,以使其可以在 PyPI(python包索引)上發布。
信息 已發布版本請查看Flake8 Markdown 倉庫。
創建一個包
用 Poetry 創建一個包, 如果 Poetry 已安裝,是會有幫助的。要做到這一點,請遵循 Poetry 安裝說明?,F在,用Poetry 創建一個包,我們將運行 poetry new,并提供包含該包的目錄的名稱:
我們收到郵件了! 不管怎樣,我們有一個包裹 (package,雙關語---譯者注)。讓我們打開它:
開箱即用,Poetry為我們提供了一個簡單的包結構和 pyproject.toml 文件:
- 0.1.0的包版本
- Python 的最小版本(在我的例子中是^3.7)
- pytest 支持和一個單元測試
信息關于 pyproject.toml的信息和背景,見 PEP 518。
如果我們將這個包按原樣發布在 Python包索引(PyPI)上,那么這個包看起來就不怎么樣,所以讓我們讓它看起來像值得安裝的東西。
自定義包
以下是初始 pyproject.toml文件:
以下是完成的 pyproject.toml:
信息有關自定義Poetry包的可用部分的完整列表,請參閱 Poetry's pyproject.toml 文檔。 讓我們從上到下逐步進行更改。
version
Version 描述了一個包的當前版本。我嘗試遵循語義版本控制,所以當更新向后不兼容時很明顯。
注一旦一個包的版本存在于pypi上,就不可能使用相同的版本號上傳不同的代碼。在發布Pypi上的版本之前,請確保使用 TestPyPI 進行測試更改。
description
這個簡短的描述出現在 pip search 和 PyPI搜索結果 中。
license
許可證出現在包的 PyPI 頁面的“Meta”部分。
我用 Github 的 choosealicense.com 找到了一個合適的許可證,并選定 MIT。Poetry 還列出了其他常見的許可證 和推薦的記號。
readme
Poetry創建了一個 README.rst 文件,但我更喜歡用 Markdown 編寫文檔。 README 的內容在 PyPI 上顯示為項目描述,因此很好地解釋為什么以及如何使用你的包。 我的 README 包括:
- 盾牌(因為它們看起來很漂亮)
- 引言
- 安裝
- 使用
- 行為準則
- 歷史記錄(大致遵循保留一個變更日志)
homepage and repository
這些出現在包的 PyPI 頁面的 Project 鏈接部分:
如果你的包有一個單獨的文檔網站,那么還有一個 documentation 屬性。
keywords
這些出現在 PyPI 頁面的 Meta 部分:
classifiers
“Trove分類器”作為 PyPI 包的類別,可以用來過濾 PyPI 上的包。它們出現在 PyPI 頁面的“分類器”部分:
完整列表見 PyPI 分類器頁面。
[tool.poetry.dependencies]
“依賴項”部分展示了Poetry的一個最佳特征。
當使用普通的 pip 或 Pipenv管理包時,通常在兩個位置指定包:dev和部署依賴項的requirements.txt或Pipfile,以及運行時/安裝依賴項的setup.py。
Poetry對所有依賴項使用pyproject.toml,這簡化了依賴項管理。
這部分包括兩個更改:
- 將最低的 Python 版本從3.7更新到3.6,以獲得更廣泛的兼容性
- 添加flake8作為依賴項
[tool.poetry.scripts]
Scripts 是“安裝包時將被安裝的腳本或可執行文件”。換句話說,開發人員可以在這里根據函數創建CLI命令。
腳本的形式為:
Flake8 markdown — 包含你的驚喜 — 有一個名為flake8 markdown的CLI命令:
在安裝 flake8-markdown 包之后, 運行 flake8-markdown 將從 flake8_markdown/__init__.py調用 main() 函數。
信息 要使包成為一個可運行模塊,比如python -m flake8-markdown,它需要一個 __main__.py模塊。在Flake8 Markdown中, __main__.py 文件導入并運行與上述腳本相同的 main() 函數。
發布包
TestPyPI
TestPyPI 是“一個獨立的Python包索引實例,它允許您在不影響實際索引的情況下嘗試分發工具和進程”。將包上傳到TestPyPI 并從那里安裝,可以幫助包維護人員避免發送損壞的包版本。
讓我們看看如何將包上載到TestPyPI。
注在將包上載到測試包索引之前,您需要注冊一個TestPyPI 帳戶。
首先,構建包:
接下來,將測試PyPI添加為備用包存儲庫:
現在,把包發布到TestPyPI:
最后,通過在 testpypi.pypi.org 上查看包并在獨立的虛擬環境中安裝測試版本,驗證包的外觀和工作是否符合預期:
PyPI
如果這個包在測試PyPI上看起來很好,并且正常啟動,那么發布到PyPI就非常簡單:
注在將包上傳到包索引之前,你需要注冊一個PyPI帳戶 。此帳戶與TestPyPI上的任何帳戶都是獨立的。
總結
PEP 517 打開了Poetry等工具的大門,提供了一種對開發人員友好的構建 Python 包的方式。因此,用Poetry創建和發布一個包是一種直接的、無需費力的體驗。構建一個包就像編寫代碼和向pyproject.toml文件中添加各部分一樣簡單。
很愉快,我決定寫一首關于它的詩:
浮動Python代碼 用Poetry集結 云端之旅
Poetry 詩歌。怎么樣?
英文原文:https://johnfraney.ca/posts/2019/05/28/create-publish-python-package-poetry/
譯者:青書