製作 Python 第三方套件

Author Avatar

SiriusKoan

  ·  2 min read

Setup #

首先,必須安裝一些必要的套件。

第一個 twine 是最終上傳至 PyPI 時所需的工具,而第二個 setuptools 則是在撰寫 setup.py 時所需的套件,能夠使撰寫 setup.py 的過程更加簡便。

setup.py #

首先,必須先撰寫 setup.py,其中包含整個套件所需的資訊。以下為一個簡單範例。

雖然有許多欄位,但並非全部皆為必填,僅是若未填寫則在建置後可能會出現 UNKNOWN 等預設名稱,因此一般而言仍建議完整填寫。

基本上,nameversionpackages 為較為重要的欄位,其餘欄位則可視需求選擇性填寫,以下分項說明。

  • name 指的是此套件的名稱,亦即他人安裝套件時所需輸入的名稱。
  • version 顧名思義即為版本號,可參考 PEP 440 – Version Identification and Dependency Specification 的規範,此處直接以 x.x 命名。
  • packages 為此套件中所包含的 package,在上述範例中使用 setuptools 提供的 find_packages 以自動尋找,亦可加入 exclude 選項以排除不應納入的 package,例如 testsdocs 等,或直接指定,如 packages=["mypackage"]
  • description 為此套件的簡短描述,將於 PyPI 顯示;而 long_description 則會出現在 PyPI 網站的 Project description 部分,通常可直接引用 GitHub 上的 README.md。由於直接引用,需記得設定 long_description_content_type,否則將以純文字顯示。
  • authorauthor_email 為作者資訊,url 為專案網址,此處選擇放置 GitHub repo,亦因如此 PyPI 會顯示 GitHub statistics。license 可依個人偏好選擇。上述幾項皆會於 PyPI 網站顯示。
  • install_requires 包含此套件所需的其他第三方套件,如 requestsnumpy 等。如需指定版本,請使用 extras_require,可參考 GitHub pyTelegramBotAPI/setup.py。若對 python 版本有需求,則可使用 python_requires
  • classifiers 為一系列資訊,官方稱之為 “A list of strings describing the categories for the package”,亦會顯示於 PyPI 頁面。此處放置了一些 python 版本相關資訊。

若需更詳細的說明或瞭解更多欄位用途,可參考官方文件 Keywords。此外,這些資料除了可直接撰寫於 setup.py,亦可寫於 setup.cfg,但本文不再贅述此方式,有需求者可參考 setuptools: Quickstart 進行轉換。

寫套件 #

完成 setup.py 後,即可開始撰寫套件內容。

首先,需建立一個與套件名稱相同的目錄,此處以 mypackage 為例。接著於該目錄中建立 __init__.py,以標示其為一個 package。隨後即可開始撰寫套件內容,需注意在建立 class 或 function 後,應將其全部 import 至 __init__.py

撰寫完成後,即可開始使用此套件。可嘗試執行 pip install .,理論上會顯示安裝成功的訊息,並完成 mypackage 套件的安裝。此時開啟 python interpreter,嘗試 import mypackage,應可順利載入,並開始使用自製套件。

上傳至 PyPI #

在自行測試無誤後,即可將套件發佈至 PyPI,供全球使用者下載,此時便需使用先前安裝的 twine 工具。

但在上傳之前,必須先產生套件的壓縮檔,需透過 python 進行相關處理。

在上傳之前,還需擁有一個 PyPI 帳號,可透過 twine 建立,亦可選擇於官方網站註冊。基本上並無特殊要求,但建議 Username 與 setup.py 中的 author 保持一致,以避免後續可能產生的問題。註冊完成後,即可進行最後步驟。

執行上述指令後,系統會要求登入,隨後開始上傳。完成後即可回到註冊頁面,理論上可見套件已成功發佈於 PyPI,供所有人下載。

日後若需更新套件,只需重複上述三個指令即可,但可能會遇到 HTTPError: 400 Client Error: File already exists.,此為 PyPI 不允許重複檔名所致,通常是因為未更新版本號。若已更新版本號仍無法解決,可嘗試先刪除 dist 目錄後再重新執行指令。

此外,PyPI 亦提供多種 badge 可嵌入於 README 中,以下為常見範例,建議善加利用以提升 README 的豐富度。

使用 GitHub Actions 自動化 #

前述步驟為手動將套件上傳至 PyPI,本章則介紹如何透過 GitHub Actions 自動化此流程。首先需前往 repo 下方的 Actions 頁面,應可見如下圖所示介面。

選擇第一個 Publish Python Package,隨後進入編輯設定檔頁面,檔名不限,系統會自動偵測。基本上,此設定檔即指示 GitHub Actions 將套件上傳至 PyPI,但仍可進行部分微調。在開始之前,先簡要說明其組成元件。

  • workflow 為流程,基本上目前編輯的設定檔即為一個 workflow。
  • job 為主要步驟,由多個 step 組成,若需處理相依性(如必須先通過測試才能部署),需於此層設定,否則系統將自動平行執行。
  • step 為執行步驟,由 job 依序執行。
  • action 為 GitHub Actions 中最小單位,一個 step 可包含多個 action

此外,最上方尚有 nameon,前者用於命名 workflow,後者則指定觸發時機,此處選擇於每次 push 時觸發,如此每次 push 系統即會自動更新 PyPI 上的套件。更改完成後,設定檔內容應類似 RandomUsers GitHub Actions

最後,需於 repo 的設定中 secrets 加入 PYPI_API_TOKEN,如此 GitHub Actions 方能通過身份驗證。此 API token 可於 PyPI 的 Account Setting 產生。

完成上述步驟後,即可將新版本 push 至 GitHub,並確認是否成功觸發 GitHub Actions 並更新至 PyPI。過程中可能會遇到語法錯誤,畢竟各 CI/CD 工具的設定檔皆有其專屬語法。

References #