Meminta pengguna mengetik python -m toko_api.main setiap kali menjalankan aplikasi itu tidak ramah: panjang, bergantung pada folder aktif, dan mudah salah tik. Entry points menyelesaikannya dengan cara mendeklarasikan sebuah perintah di pyproject.toml, lalu pip membuatkan program kecil yang bisa dipanggil dari mana saja. Pada chapter ini kita membangun CLI sungguhan, memasangnya dengan editable install, dan membedah wrapper yang dihasilkan pip.
Mendeklarasikan [project.scripts] #
Bentuk deklarasinya memetakan nama perintah ke module:fungsi:
[project.scripts]
hitung-kata = "hitung_kata.cli:main"Tiga bagian perlu dipahami: nama di kiri (hitung-kata) adalah perintah yang diketik pengguna; hitung_kata.cli di kanan adalah module tempat fungsi berada; dan main setelah titik dua adalah nama fungsi yang dipanggil saat perintah dijalankan. Fungsi target harus bisa dipanggil tanpa argument — argument baris perintah dibaca sendiri oleh fungsi tersebut lewat sys.argv atau parser.
Demo Nyata dari Awal sampai Akhir #
Package hitung-kata berisi satu fungsi penghitung kata:
# src/hitung_kata/cli.py
import sys
def main() -> None:
if len(sys.argv) < 2:
print("Pemakaian: hitung-kata <teks>")
raise SystemExit(1)
teks = " ".join(sys.argv[1:])
jumlah = len(teks.split())
print(f"Jumlah kata: {jumlah}")Berkas pyproject.toml berisi deklarasi [project.scripts] di atas beserta metadata dasar. Setelah venv dibuat dan diaktifkan, pasang package dalam mode editable:
pip install -e .Output yang Dihasilkan (jalur dan hash akan berbeda di komputer Anda):
Obtaining file:///tmp/hitung-kata
Installing build dependencies: started
Installing build dependencies: finished with status 'done'
Checking if build backend supports build_editable: started
Checking if build backend supports build_editable: finished with status 'done'
Getting requirements to build editable: started
Getting requirements to build editable: finished with status 'done'
Preparing editable metadata (pyproject.toml): started
Preparing editable metadata (pyproject.toml): finished with status 'done'
Building wheels for collected packages: hitung-kata
Building editable for hitung-kata (pyproject.toml): started
Building editable for hitung-kata (pyproject.toml): finished with status 'done'
Created wheel for hitung-kata: filename=hitung_kata-0.1.0-0.editable-py3-none-any.whl size=1519 sha256=88d932f45d3cb7229458c700b06c1615c4e479fc460a6c75f6bb856c3adb7c69
Successfully built hitung-kata
Installing collected packages: hitung-kata
Successfully installed hitung-kata-0.1.0Baris Checking if build backend supports build_editable memperlihatkan hook PEP 660 — yang dibahas pada Chapter Build System dan Package Metadata — sedang bekerja.
Sekarang perintah hitung-kata hidup di dalam venv. Mari kita jalankan:
hitung-kata "belajar packaging python itu menyenangkan"Output yang Dihasilkan:
Jumlah kata: 5Perilaku saat argument hilang juga patut diuji:
hitung-kata
echo $?Output yang Dihasilkan:
Pemakaian: hitung-kata <teks>
1Angka 1 dari echo $? adalah exit code — fungsi main() sengaja menaikkan SystemExit(1) supaya script otomatis dan CI dapat mendeteksi kegagalan, konvensi yang dibahas pada Chapter Membangun CLI Profesional.
Bagaimana Wrapper Dibuat #
pip tidak menaruh sihir apa pun di terminal. Saat instalasi, pip membaca entry_points.txt di dalam wheel (kita melihat berkas ini pada chapter sebelumnya), lalu menulis sebuah script Python ke folder bin/ venv. Inilah isi .venv/bin/hitung-kata persis seperti yang dihasilkan pip:
#!/tmp/hitung-kata/.venv/bin/python
import sys
from hitung_kata.cli import main
if __name__ == '__main__':
sys.argv[0] = sys.argv[0].removesuffix('.exe')
sys.exit(main())Mari kita telaah baris per baris:
- Baris 1 (shebang
#!): mengarah ke interpreter venv tempat package dipasang. Inilah alasan perintah otomatis memakai Python venv aktif tanpa kita mengetikpython— dan perintah tidak akan menemukan package bila venv-nya dihapus. - Baris 3 (
from hitung_kata.cli import main): mengimpor fungsi target yang dideklarasikan dimodule:fungsi. - Baris 5 (
removesuffix('.exe')): kebersihan nama perintah di Windows, tempat script berakhiran.exe. - Baris 6 (
sys.exit(main())): nilai kembalian fungsi menjadi exit code proses — mengembalikanNoneberarti exit code0(sukses).
Karena wrapper sekecil ini, nama perintah bisa dibuat ulang kapan saja dengan reinstall — tidak ada proses kompilasi.
Konvensi Nama Perintah #
Nama perintah mengikuti distribution name: kebab-case, singkat, dan mudah diketik. Dua jebakan perlu dihindari. Pertama, jangan pakai nama yang bertabrakan dengan perintah sistem (ls, sort, test) — folder bin venv biasanya mendahului /usr/bin di PATH, sehingga perintah sistem bisa tertutup tanpa sadar. Kedua, untuk aplikasi dengan banyak subperintah, deklarasikan satu perintah induk saja (misalnya toko-api), lalu pecah menjadi subperintah dengan argparse di dalamnya — pola git yang dikenal semua orang.
Entry points melengkapi kemasan library. Selanjutnya kita membalik sudut pandang: bagaimana mengemas aplikasi — kode yang kita jalankan sendiri, bukan diserahkan ke pengguna.