Membangun Paket Python: Panduan dari Pengembangan hingga PyPI

Masterkan pengemasan Python dari kode hingga pengiriman ke PyPI

Konten Halaman

Python packaging telah berkembang secara signifikan, dengan alat-alat modern dan standar yang membuat distribusi kode Anda menjadi lebih mudah daripada sebelumnya.

Panduan ini akan membawa Anda melalui proses membangun paket Python profesional dan menerbitkannya ke PyPI. Jika Anda baru dalam Python atau membutuhkan referensi cepat, lihat Python Cheatsheet kami untuk mempercepat pemahaman Anda tentang dasar-dasar Python.

Python Packages

Mengapa Mengemas Kode Python Anda?

Mengemas proyek Python Anda menawarkan berbagai manfaat:

  • Kemudahan Penggunaan Ulang: Bagikan kode di berbagai proyek tanpa menyalin-paste
  • Distribusi: Izinkan orang lain menginstal kode Anda hanya dengan pip install
  • Manajemen Ketergantungan: Tentukan dan kelola ketergantungan secara jelas
  • Versi: Lacak rilis dan pertahankan kompatibilitas mundur
  • Standar Profesional: Ikuti praktik terbaik komunitas Python
  • Dokumentasi: Struktur mendorong dokumentasi dan pengujian yang tepat

Struktur Paket Python Modern

Sebuah paket yang terorganisir dengan baik mengikuti struktur berikut:

my-package/
├── src/
│   └── mypackage/
│       ├── __init__.py
│       ├── core.py
│       └── utils.py
├── tests/
│   ├── __init__.py
│   └── test_core.py
├── docs/
│   └── index.md
├── .github/
│   └── workflows/
│       └── publish.yml
├── pyproject.toml
├── README.md
├── LICENSE
└── .gitignore

src-layout sekarang disarankan daripada tata letak datar karena:

  • Mencegah impor tidak sengaja dari kode yang belum terinstal selama pengembangan
  • Membuat pengujian lebih andal dengan memaksa instalasi
  • Memisahkan jelas kode sumber dari file proyek lainnya

Ketika mengatur struktur internal paket Anda, pertimbangkan untuk menerapkan prinsip-prinsip arsitektur bersih agar kode Anda lebih mudah dipelihara dan diuji. Panduan kami tentang Python Design Patterns for Clean Architecture membahas prinsip SOLID, injeksi ketergantungan, dan pola arsitektur bertingkat yang bekerja sangat baik dengan paket Python.

File pyproject.toml: Konfigurasi Modern

pyproject.toml (PEP 518, 621) adalah standar modern untuk konfigurasi proyek Python, menggantikan setup.py yang sudah usang:

[build-system]
requires = ["setuptools>=68.0", "wheel"]
build-backend = "setuptools.build_meta"

[project]
name = "mypackage"
version = "0.1.0"
description = "A fantastic Python package"
readme = "README.md"
requires-python = ">=3.8"
license = {text = "MIT"}
authors = [
    {name = "Your Name", email = "you@example.com"}
]
keywords = ["example", "tutorial", "package"]
classifiers = [
    "Development Status :: 4 - Beta",
    "Intended Audience :: Developers",
    "License :: OSI Approved :: MIT License",
    "Programming Language :: Python :: 3",
    "Programming Language :: Python :: 3.8",
    "Programming Language :: Python :: 3.9",
    "Programming Language :: Python :: 3.10",
    "Programming Language :: Python :: 3.11",
    "Programming Language :: Python :: 3.12",
]
dependencies = [
    "requests>=2.28.0",
    "click>=8.1.0",
]

[project.optional-dependencies]
dev = [
    "pytest>=7.4.0",
    "black>=23.0.0",
    "flake8>=6.0.0",
    "mypy>=1.5.0",
]
docs = [
    "sphinx>=7.0.0",
    "sphinx-rtd-theme>=1.3.0",
]

[project.urls]
Homepage = "https://github.com/yourusername/mypackage"
Documentation = "https://mypackage.readthedocs.io"
Repository = "https://github.com/yourusername/mypackage"
Issues = "https://github.com/yourusername/mypackage/issues"

[project.scripts]
mypackage-cli = "mypackage.cli:main"

[tool.setuptools.packages.find]
where = ["src"]

Bagian Konfigurasi Penting

  1. build-system: Menentukan backend pembuatan (setuptools, hatchling, poetry-core, flit-core)
  2. project: Metadata inti dan ketergantungan
  3. project.optional-dependencies: Ketergantungan fitur tambahan (dev, docs, pengujian)
  4. project.scripts: Titik masuk perintah baris
  5. tool.*: Konfigurasi khusus alat (black, pytest, mypy, dll.)

Memilih Backend Pembuatan

Setuptools (Pilihan Standar)

Opsi yang paling luas digunakan dan kompatibel:

[build-system]
requires = ["setuptools>=68.0", "wheel"]
build-backend = "setuptools.build_meta"

Kelebihan: Kompatibilitas universal, fitur yang luas, ekosistem yang besar Kekurangan: Konfigurasi yang lebih panjang, lebih lambat daripada alternatif modern

Hatchling (Modern & Cepat)

Backend modern yang ringan dan performa tinggi:

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

Kelebihan: Pembuatan cepat, konfigurasi sederhana, default yang baik Kekurangan: Plugin lebih sedikit dibandingkan setuptools

Poetry (All-in-One)

Manajemen ketergantungan dan lingkungan yang lengkap:

[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"

[tool.poetry]
name = "mypackage"
version = "0.1.0"
description = "A fantastic Python package"
authors = ["Your Name <you@example.com>"]

[tool.poetry.dependencies]
python = "^3.8"
requests = "^2.28.0"

Kelebihan: Resolusi ketergantungan, file kunci, alur kerja terintegrasi Kekurangan: Alur kerja berbeda, permukaan alat yang lebih besar

Flit (Minimalis)

Alat sederhana untuk paket sederhana:

[build-system]
requires = ["flit_core >=3.2,<4"]
build-backend = "flit_core.buildapi"

Kelebihan: Sangat sederhana, konfigurasi minimal Kekurangan: Fitur terbatas untuk paket kompleks

Membangun Paket Anda

Instalasi Alat Pembuatan

# Instal alat pembuatan modern
pip install build

# Atau untuk Poetry
pip install poetry

# Atau untuk Hatchling
pip install hatch

Membangun File Distribusi

Menggunakan paket build (berfungsi dengan backend apa pun):

# Bersihkan pembuatan sebelumnya
rm -rf dist/ build/ *.egg-info

# Bangun distribusi sumber dan wheel
python -m build

# Ini menciptakan:
# dist/mypackage-0.1.0.tar.gz    (distribusi sumber)
# dist/mypackage-0.1.0-py3-none-any.whl  (wheel)

Menggunakan Poetry:

poetry build

Menggunakan Hatch:

hatch build

Memahami Format Distribusi

Distribusi Sumber (sdist) - .tar.gz

  • Mengandung kode sumber dan instruksi pembuatan
  • Pip pengguna membangunnya selama instalasi
  • Termasuk pengujian, dokumen, dan file pengembangan lainnya

Wheel - .whl

  • Distribusi biner yang telah dibangun sebelumnya
  • Instalasi cepat (tidak ada langkah pembuatan)
  • Platform spesifik atau Python murni
  • Format yang disarankan untuk distribusi

Menerbitkan ke PyPI

Metode 1: Unggah Manual dengan Twine (Tradisional)

# Instal twine
pip install twine

# Periksa paket sebelum mengunggah
twine check dist/*

# Unggah ke TestPyPI terlebih dahulu (disarankan)
twine upload --repository testpypi dist/*

# Uji instalasi dari TestPyPI
pip install --index-url https://test.pypi.org/simple/ mypackage

# Unggah ke PyPI produksi
twine upload dist/*

Konfigurasikan kredensial di ~/.pypirc:

[distutils]
index-servers =
    pypi
    testpypi

[pypi]
username = __token__
password = pypi-AgEIcHlwaS5vcmc...

[testpypi]
repository = https://test.pypi.org/legacy/
username = __token__
password = pypi-AgENdGVzdC5weXBpLm9yZw...

Metode 2: Penerbitan Terpercaya (Disarankan untuk CI/CD)

Penerbitan Terpercaya menggunakan OpenID Connect (OIDC) untuk mengautentikasi dari platform CI/CD tanpa menyimpan token.

Konfigurasi di PyPI:

  1. Buka pengaturan proyek PyPI Anda
  2. Navigasi ke bagian “Publishing”
  3. Tambahkan “pending publisher” baru
  4. Konfigurasi:
    • Pemilik: Username GitHub Anda/organisasi
    • Repository: Nama repository
    • Workflow: publish.yml
    • Lingkungan: release (opsional tetapi disarankan)

Workflow GitHub Actions (.github/workflows/publish.yml):

name: Publish to PyPI

on:
  release:
    types: [published]

permissions:
  contents: read

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: '3.11'
      
      - name: Install build dependencies
        run: |
          python -m pip install --upgrade pip
          pip install build          
      
      - name: Build package
        run: python -m build
      
      - name: Store distribution packages
        uses: actions/upload-artifact@v3
        with:
          name: python-package-distributions
          path: dist/

  publish:
    needs: build
    runs-on: ubuntu-latest
    environment: release
    permissions:
      id-token: write
    
    steps:
      - name: Download distributions
        uses: actions/download-artifact@v3
        with:
          name: python-package-distributions
          path: dist/
      
      - name: Publish to PyPI
        uses: pypa/gh-action-pypi-publish@release/v1

Keuntungan:

  • Tidak ada token API yang harus dikelola atau diaman
  • Otentikasi otomatis melalui OIDC
  • Keamanan meningkat melalui aturan perlindungan lingkungan
  • Riwayat audit dari semua penerbitan

Praktik Terbaik

1. Manajemen Versi

Gunakan versi semantik (SemVer): MAJOR.MINOR.PATCH

# Instal alat peningkatan versi
pip install bump2version

# Tingkatkan versi
bump2version patch  # 0.1.0 -> 0.1.1
bump2version minor  # 0.1.1 -> 0.2.0
bump2version major  # 0.2.0 -> 1.0.0

Konfigurasikan dalam .bumpversion.cfg:

[bumpversion]
current_version = 0.1.0
commit = True
tag = True

[bumpversion:file:pyproject.toml]
search = version = "{current_version}"
replace = version = "{new_version}"

[bumpversion:file:src/mypackage/__init__.py]
search = __version__ = "{current_version}"
replace = __version__ = "{new_version}"

2. Termasuk File Penting

README.md: Deskripsi proyek yang jelas, instalasi, contoh penggunaan LICENSE: Pilih lisensi yang tepat (MIT, Apache 2.0, GPL, dll.) CHANGELOG.md: Dokumentasi perubahan antar versi .gitignore: Ekklusi artefak pembuatan, cache, dan lingkungan virtual

3. Pengujian Komprehensif

# Instal ketergantungan pengujian
pip install pytest pytest-cov

# Jalankan pengujian dengan laporan cakupan
pytest --cov=mypackage tests/

# Buat laporan cakupan
pytest --cov=mypackage --cov-report=html tests/

Konfigurasikan dalam pyproject.toml:

[tool.pytest.ini_options]
testpaths = ["tests"]
python_files = ["test_*.py"]
python_functions = ["test_*"]
addopts = "--strict-markers --cov=mypackage"

4. Alat Kualitas Kode

# Pemformatan
black src/ tests/

# Pemeriksaan lint
flake8 src/ tests/

# Pemeriksaan tipe
mypy src/

# Pengurutan impor
isort src/ tests/

Integrasi ke dalam hook pre-commit (.pre-commit-config.yaml):

repos:
  - repo: https://github.com/psf/black
    rev: 23.9.1
    hooks:
      - id: black
  
  - repo: https://github.com/pycqa/flake8
    rev: 6.1.0
    hooks:
      - id: flake8
  
  - repo: https://github.com/pre-commit/mirrors-mypy
    rev: v1.5.1
    hooks:
      - id: mypy

5. Dokumentasi

Gunakan Sphinx untuk dokumentasi:

# Instal Sphinx
pip install sphinx sphinx-rtd-theme

# Inisialisasi dokumentasi
cd docs
sphinx-quickstart

# Bangun dokumentasi
make html

Atau gunakan MkDocs untuk dokumentasi berbasis Markdown yang lebih sederhana:

pip install mkdocs mkdocs-material
mkdocs new .
mkdocs serve

6. Integrasi Berkelanjutan (CI)

Pengujian paket Python Anda di berbagai platform dan lingkungan sangat penting untuk keandalan. Untuk wawasan tentang kinerja Python dalam skenario deployment berbeda, lihat perbandingan kami tentang AWS Lambda performance: JavaScript vs Python vs Golang, yang mengeksplorasi bagaimana Python berkinerja dalam lingkungan serverless.

Workflow CI/CD lengkap (.github/workflows/ci.yml):

name: CI

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]
        python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']
    
    steps:
      - uses: actions/checkout@v4
      
      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: ${{ matrix.python-version }}
      
      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install -e ".[dev]"          
      
      - name: Run tests
        run: pytest --cov=mypackage --cov-report=xml
      
      - name: Upload coverage
        uses: codecov/codecov-action@v3
        with:
          file: ./coverage.xml
  
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: '3.11'
      
      - name: Install dependencies
        run: |
          pip install black flake8 mypy          
      
      - name: Black formatting check
        run: black --check src/ tests/
      
      - name: Flake8
        run: flake8 src/ tests/
      
      - name: MyPy
        run: mypy src/

Masalah Umum dan Solusinya

Masalah 1: Kesalahan Impor Setelah Instalasi

Masalah: Paket terinstal tetapi impor gagal

Solusi: Pastikan struktur paket yang benar dengan file __init__.py dan konfigurasi pyproject.toml yang tepat:

[tool.setuptools.packages.find]
where = ["src"]
include = ["mypackage*"]

Masalah 2: Ketergantungan Hilang

Masalah: Paket terinstal tetapi gagal di runtime karena ketergantungan yang hilang

Solusi: Nyatakan semua ketergantungan runtime di pyproject.toml:

[project]
dependencies = [
    "requests>=2.28.0",
    "click>=8.1.0",
]

Masalah 3: Konflik Versi

Masalah: Paket berfungsi dalam pengembangan tetapi gagal dalam produksi

Solusi: Gunakan lingkungan virtual dan tentukan versi minimum:

# Buat lingkungan terisolasi
python -m venv .venv
source .venv/bin/activate  # Pada Windows: .venv\Scripts\activate

# Instal dalam mode editable untuk pengembangan
pip install -e ".[dev]"

Masalah 4: Ukuran Paket Besar

Masalah: Paket terlalu lama untuk diunduh/menginstal

Solusi: Eksklusikan file yang tidak diperlukan menggunakan MANIFEST.in:

include README.md
include LICENSE
include pyproject.toml
recursive-include src *.py
recursive-exclude * __pycache__
recursive-exclude * *.py[co]
recursive-exclude tests *
recursive-exclude docs *

Masalah 5: Masalah Platform Spesifik

Masalah: Paket berfungsi di satu OS tetapi gagal di OS lain

Solusi: Uji di berbagai platform menggunakan matrix pembuatan CI/CD (lihat contoh CI di atas)

Daftar Pemeriksaan Sebelum Menerbitkan

Sebelum menerbitkan paket Anda ke PyPI, verifikasi:

  • Semua pengujian melewati versi Python
  • Kode diformat dan diperiksa lint
  • README.md lengkap dengan contoh
  • File LICENSE disertakan
  • Nomor versi diperbarui
  • CHANGELOG.md diperbarui
  • Ketergantungan dinyatakan dengan benar
  • Paket dibangun tanpa kesalahan (python -m build)
  • Paket diuji di TestPyPI
  • Dokumentasi diperbarui
  • Repository Git diberi tag versi
  • Pembaruan GitHub dibuat (untuk penerbitan terpercaya)

Topik Lanjutan

Titik Masuk dan Alat CLI

Buat antarmuka perintah baris:

[project.scripts]
mypackage = "mypackage.cli:main"

Implementasi di src/mypackage/cli.py:

import click

@click.command()
@click.option('--name', default='World', help='Nama untuk diucapkan')
def main(name):
    """Contoh alat CLI sederhana"""
    click.echo(f'Hello, {name}!')

if __name__ == '__main__':
    main()

Untuk contoh nyata pembuatan paket Python yang berinteraksi dengan API eksternal, lihat panduan kami tentang Integrating Ollama with Python, yang menunjukkan pembuatan klien Python dengan integrasi REST API dan perpustakaan resmi.

Sistem Plugin

Aktifkan penemuan plugin:

[project.entry-points."mypackage.plugins"]
plugin_a = "mypackage_plugin_a:PluginA"

Ekstensi C

Untuk kode kritis kinerja:

[tool.setuptools.ext-modules]
name = "mypackage._speedups"
sources = ["src/mypackage/_speedups.c"]

Paket Namespace

Untuk paket terdistribusi di bawah namespace yang sama:

[tool.setuptools.packages.find]
where = ["src"]
include = ["company.*"]

[tool.setuptools.package-data]
"company.mypackage" = ["py.typed"]

Alat dan Sumber Daya Berguna

Alat Pengembangan Paket

  • cookiecutter: Template proyek untuk paket Python
  • tox: Otomatisasi pengujian di berbagai versi Python
  • nox: Otomatisasi pengujian yang fleksibel (alternatif tox)
  • pre-commit: Kerangka kerja hook Git untuk kualitas kode
  • commitizen: Standarkan pesan commit dan versi

Platform Dokumentasi

  • Read the Docs: Hosting dokumentasi gratis
  • GitHub Pages: Hosting MkDocs atau Sphinx dokumentasi
  • pdoc: Generator dokumentasi API sederhana

Registri Paket

  • PyPI: Indeks paket Python resmi (pypi.org)
  • TestPyPI: Lingkungan pengujian (test.pypi.org)
  • Anaconda.org: Distribusi paket Conda
  • GitHub Packages: Hosting paket pribadi

Pemantauan dan Analitik

  • PyPI Stats: Statistik unduhan untuk paket
  • Libraries.io: Pemantauan ketergantungan dan peringatan
  • Snyk: Pemindaian kerentanan keamanan
  • Dependabot: Pembaruan ketergantungan otomatis

Kesimpulan

Pengemasan Python modern telah berkembang menjadi lebih ramah pengembang dengan standar seperti pyproject.toml, backend pembuatan yang kuat, dan penerbitan yang aman melalui Penerbitan Terpercaya. Dengan mengikuti panduan ini, Anda dapat membuat paket Python profesional yang mudah dipelihara dan melayani pengguna secara efektif.

Poin penting:

  1. Gunakan pyproject.toml untuk semua proyek baru
  2. Pilih backend pembuatan yang tepat sesuai kebutuhan Anda
  3. Implementasikan pengujian otomatis dan CI/CD
  4. Gunakan Penerbitan Terpercaya untuk penerbitan aman tanpa token
  5. Ikuti versi semantik dan pertahankan catatan perubahan
  6. Sediakan dokumentasi dan contoh yang komprehensif

Ekosistem pengemasan Python terus berkembang dengan alat yang lebih baik, standar, dan fitur keamanan. Tetap terupdate dengan Python Enhancement Proposals (PEPs) dan praktik terbaik komunitas untuk menjaga paket Anda modern dan mudah dipelihara.

Tautan Berguna

Artikel Berguna Lainnya di Situs Ini