如何建立 Python 包然後上傳到 server 讓你達成 DRY 原則

程式寫久了都會遇到在多個專案中重複寫一樣的東西,例如工具類程式、常用的介面程式、基礎算法程式等等,重複的東西就會違背 DRY (Don’t Repeat Yourself) 原則,今天這篇文就來示範一下如何自己建立自己的 Python 包,然後上傳到公有或私有 server,最後能透過 pip install 來安裝已打包好的程式,文章會分為 2 個部份,第 1 部份是如何打包,第 2 部份是把我們打包好的程式上傳到公開的庫 PyPI (Python package index) 或者私有的庫 pypiserver

打包你的 Python 程式

首先我們要有想打包的程式,資料夾結構會長的跟下面一樣,

└── tshine73-utils    <--- 這個是 "project name",也就是之後會用 pip install 時用的名字
    └── tshine73_utils   <--- 這個是 "package name",也就是未來在程式中 import 時用的名字
        ├── __init__.py
        └── aws
            └── code1.py
                └── __init__.py
        ├── code1.py
        └── code2.py
    ├── README.md
        ├── requirements.txt
    └── setup.py

這裡可以留意一下 project name 和 package name 的差別,準備好程式後,就可以照著以下的步驟進行打包啦!

若懶得整理你自己程式可用 我的程式 來練習打包。

1. 安裝 twine

因為我們是用 twine 來上傳 Python 包,所以要裝。

pip install twine==6.1.0

2. 準備好 setup.py

這個檔案是用來定義 Python 包的 metadata,要留意一下 install_requires 這個參數,需要把你的程式中有用到的 Python 依賴包都放入。

from setuptools import setup, find_packages

setup(
    name="tshine73-utils",
    version="0.2",
    author="tshine73",
    author_email="fan.steven.chiang@gmail.com",
    description="tshine73 utils",
    packages=find_packages(),
    classifiers=[
        'Programming Language :: Python :: 3',
        'License :: OSI Approved :: MIT License',
        'Operating System :: OS Independent',
    ],
    python_requires='>=3.12',
    include_package_data=True,
    install_requires=[
        "psycopg2-binary==2.9.9", 'boto3==1.36.3', 'requests==2.32.3'
    ]
)

3. 打包

執行下述指令,

python setup.py sdist

然後你會看到多了 2 個資料夾 distxxxx-info,如下圖紅字。

4. 使用 pip 安裝一下剛剛打包的 Python 包,然後寫個程式測試一下

. 來安裝 dist 資料夾中的 Python 包,

pip install .

然後隨便寫個程式測試一下是不是真的可以在 import 你的 Python 包進來,

from datetime import datetime

from tshine73_utils.date_utils import format_datetime


def main():
    current_date_time = format_datetime(datetime.now())
    print(f"current date time is {current_date_time}")

if __name__ == "__main__":
    main()

看起來可以成功執行,

最後可以解除安裝,一會 上傳我們的 Python 包後可以再測試安裝一次。

pip uninstall tshine73-utils

上傳你的 Python 包到公有或私有環境

上傳 Python 包到公有環境 PyPI

PyPI 是 Python 的包索引,你在執行 pip install 時預設都會來這裡找相依的包,所以我們也可以把我們的包上傳到這裡,讓社群的大家都可以使用😃

1. 註冊 PyPI 會員

上傳前你需要先去註冊 PyPI 會員,完成 2 階段認證設定後,在 Account setting 中新增 API token,

2. 使用 twine 上傳 Python 包

使用以下指令後上傳,

twine upload dist/*

然後它會要你輸入上一步取得的 API Token,完成後會看到下圖。

3. 安裝測試

這次我們就來輸入 project name tshine73-utils 來測試一下安裝。

pip install tshine73-utils

成功安裝!

上傳 Python 包到私有環境 PyPI

PyPI 的 私有server 有很多,這裡就選擇一個較熱門的 pypiserver,它跟 PyPI 都實作一樣的介面,所以我們也可以用相同的 pip 和 twine 指令行安裝和上傳,它的方便也在於用 pip install pypiserver 後,就可以直接用它的指令啟動 server 起來了,為求環境獨立性,我這裡使用 docker 來啟動 pypiserver。

1. 使用 docker run 啟動 pypiserver

感謝網路上已經有相對應的 pypiserver docker image 可使用,使用以下指令啟動 pypiserver 可讓我們不透過認證就可以上傳 Python 包到 server 上。

docker run --rm -it --name pypiserver -p 8080:8080 -v ./packages:/data/packages pypiserver/pypiserver run -a . -P . -p 8080 --server gunicorn

啟動後,可透過 http://localhost:8080 連線看看,成功後會看到下圖。

2. 使用 twine 上傳 Python 包

因為是將 Python 包上傳到自己建立的 server,所以我們在用 twine 指令時需多指定 repository URL,

twine upload dist/* --repository-url http://localhost:8080

然後畫面會跳出要你輸入 username 和 password 的提示,直接按 enter 就好

3. 安裝測試

使用一樣的 pip 指令,但這次我們要給它自建 server 的 URL,

pip install tshine73-utils --index-url http://localhost:8080

感謝老天也是成功安裝。

結論

今天的文章介紹了如何打包自己的 Python 程式然後上傳到公有或私有 server 上,這樣就不會老是在多個專案中將程式複製來複製去的吧!

最重要的是我們遵守了 DRY (Don’t Repeat Yourself) 開發原則,很棒對吧😎

tshine73
tshine73
文章: 64

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *