Membangun Paket Python: Panduan dari Pengembangan hingga PyPI
Masterkan pengemasan Python dari kode hingga pengiriman ke PyPI
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.

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
- build-system: Menentukan backend pembuatan (setuptools, hatchling, poetry-core, flit-core)
- project: Metadata inti dan ketergantungan
- project.optional-dependencies: Ketergantungan fitur tambahan (dev, docs, pengujian)
- project.scripts: Titik masuk perintah baris
- 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:
- Buka pengaturan proyek PyPI Anda
- Navigasi ke bagian “Publishing”
- Tambahkan “pending publisher” baru
- 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:
- Gunakan pyproject.toml untuk semua proyek baru
- Pilih backend pembuatan yang tepat sesuai kebutuhan Anda
- Implementasikan pengujian otomatis dan CI/CD
- Gunakan Penerbitan Terpercaya untuk penerbitan aman tanpa token
- Ikuti versi semantik dan pertahankan catatan perubahan
- 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
- Python Packaging User Guide
- PEP 518 - Specifying Build System Requirements
- PEP 621 - Storing project metadata in pyproject.toml
- PyPI Trusted Publishing Documentation
- Setuptools Documentation
- Poetry Documentation
- Hatch Documentation
- TestPyPI
- Python Packaging Authority GitHub
- Semantic Versioning
- Choose a License