- Karena tren terbaru dalam pengembangan AI, saya mulai serius mempelajari dan menggunakan Python, dan kini merasa sangat puas dengan ekosistemnya
- Python telah berkembang menjadi bahasa yang jauh lebih cepat dan modern dibanding masa lalu, dan saya merasakan langsung kemajuan pesatnya, termasuk peningkatan performa melalui Cython
- Saya secara aktif mengadopsi alat dan pustaka pengembangan modern seperti uv, ruff, pytest, dan Pydantic ke dalam alur kerja saya untuk meningkatkan produktivitas pengembangan
- Saya juga menerapkan struktur proyek dan otomatisasi untuk memperkecil perbedaan antara lingkungan produksi dan pengembangan berbasis Jupyter notebook/skrip
- Dengan memanfaatkan GitHub Actions, Docker, dan lainnya, saya membangun CI/CD, pengujian, dan pengelolaan infrastruktur secara efisien
Ringkasan I’m Switching to Python and Actually Liking It
Mengapa beralih ke Python
- Dalam lingkungan pengembangan yang berpusat pada AI, Python telah menjadi bahasa standar de facto
- Dulu saya hanya menggunakannya untuk menulis skrip sederhana, tetapi belakangan saya mulai menggunakannya secara serius untuk membuat “aplikasi siap pakai” seperti RAG, agent, dan AI generatif
- Dalam prosesnya, saya merasakan bahwa ekosistem Python telah berevolusi sangat jauh dibanding masa lalu
Tiga kekuatan Python
- Ekosistem pustaka dan alat yang kaya: sangat kuat untuk pemrosesan data, analisis, web, dan AI
- Peningkatan performa lewat Cython dan lainnya: memungkinkan optimasi berbasis kompilasi
- Keterbacaan sintaks yang makin baik: sintaks lama seperti
__init__, __new__ makin tersembunyi, dan tersedia sintaks yang lebih intuitif
Struktur proyek (berbasis monorepo)
Alat dan konfigurasi utama
-
uv
- Package manager dan build tool Python modern dari Astral
- Menangani sebagian besar pekerjaan dengan cepat, seperti pengelolaan dependensi, pembuatan virtual environment, dan inisialisasi proyek
pyproject.toml adalah berkas konfigurasi inti yang menyatukan seluruh metadata dan informasi dependensi
- Lingkungan proyek dapat disiapkan dengan cepat lewat perintah
uv init, uv add, uv sync
-
ruff
- Linter dan formatter Python super cepat
- Alat yang menggabungkan
isort, flake8, autoflake, dan lainnya
- Linting dan perbaikan otomatis dapat dilakukan dengan
ruff check, ruff format
- Mendukung panduan gaya penulisan kode PEP 8 secara bawaan
-
ty
- Static type checker untuk Python buatan Astral
- Efektif untuk analisis statis dan pencegahan bug sejak awal jika dipadukan dengan
typing
- Meski masih pada tahap awal pengembangan, alat ini sudah cukup stabil untuk digunakan
-
pytest
- Framework pengujian Python yang representatif untuk unit test dan lingkungan pengujian yang dapat diperluas
- Dengan aturan penamaan berkas yang sederhana dan satu baris perintah, integrasi pengujian bisa langsung dilakukan
- Susun pengujian sebagai
test_*.py, lalu jalankan dengan uv run pytest
- Sintaks ringkas dan ekosistem plugin yang kaya
-
Pydantic
- Pustaka validasi data dan pengelolaan konfigurasi lingkungan
- Mendukung pemuatan konfigurasi berbasis variabel lingkungan
.env serta validasi tipe
- Kelas
BaseSettings memungkinkan pengelolaan API key, DB URL, dan lainnya secara aman
-
MkDocs
- Memudahkan pembuatan situs web statis dan dokumentasi untuk proyek Python
- Memungkinkan penerapan cepat desain menarik bergaya proyek open source
- Juga mudah diintegrasikan dengan GitHub Pages
-
FastAPI
- Framework untuk membangun RESTful API dengan cepat
- Keunggulannya meliputi validasi dan dokumentasi otomatis, performa tinggi, serta integrasi mudah dengan Pydantic
- Berbasis Starlette dan Pydantic untuk memberikan stabilitas tipe dan performa yang tinggi
-
Dataclasses
- Fitur standar Python untuk mendefinisikan kelas berfokus data dengan mudah
- Mengurangi boilerplate code secara signifikan melalui pembuatan metode khusus otomatis
Kontrol versi dan otomatisasi
-
GitHub Actions
- Pipeline CI terpisah disusun masing-masing untuk
project-api dan project-ui
- Menyediakan workflow yang optimal untuk membangun pipeline CI di berbagai OS
- Dengan lingkungan pengujian berbasis Docker, pengujian dapat dilakukan dalam lingkungan yang sama dengan produksi
-
Dependabot
- Mengotomatiskan pembaruan dependensi dan pengelolaan patch keamanan
-
Gitleaks
- Alat untuk mencegah kebocoran informasi sensitif seperti kata sandi dan API key dengan menjalankan pemeriksaan keamanan sebelum git commit
-
Pre-commit Hooks
- Alat untuk linting, formatting, dan pemeriksaan keamanan otomatis sebelum commit
- Digunakan bersama ruff, gitleaks, dan lainnya untuk menjaga konsistensi serta kualitas kode
Otomatisasi infrastruktur
-
Make
- Mendukung alur kerja pengembangan yang konsisten melalui perintah seperti
make test, make infrastructure-up
- Terdapat Makefile masing-masing di root proyek dan di
project-api
-
Docker & Docker Compose
project-api dan project-ui dijalankan secara terpisah sebagai kontainer
- Seluruh aplikasi dapat dijalankan dengan satu baris
docker compose up --build -d
Dockerfile mencakup instalasi uv dan perintah untuk menjalankan aplikasi FastAPI
Penutup
- Seperti di atas, lingkungan pengembangan Python modern memungkinkan penyusunan workflow produksi yang efisien dan tangguh
- Di berbagai area seperti AI, data, dan pengembangan web, banyak manfaat bisa dirasakan dari pertumbuhan ekosistem Python dan kemajuan alat-alatnya
- Struktur monorepo, alat otomatisasi, linter dan type checker, lingkungan pengujian instan, dokumentasi, hingga orkestrasi infrastruktur dapat diwujudkan sebagai satu budaya pengembangan yang terpadu
6 komentar
Python punya kelebihan berupa pustaka dan framework yang melimpah, tetapi kekurangannya adalah manajemen versi paket yang kurang baik dan konflik yang sering terjadi.
Kecenderungan kelebihan dan kekurangannya mirip dengan Java di masa lalu
uvyang disebut di artikel itu memang benar-benar mantap. Selain cepat, pengelolaan versi dan dependensinya juga rapi sepertinpm, jadi saya sedang mulai menetap pakaiuv.Namun belakangan ini, sepertinya sebagian besar masalah manajemen versi dan konflik sudah teratasi lewat uv dan poetry.
Apakah Python juga cocok untuk mencakup ekosistem hingga React dan bagian-bagian seperti ini?
Karena bahasanya berbeda, integrasi langsung dengan React memang ada bagian yang cukup sulit, tetapi tergantung apa yang Anda inginkan, sepertinya ada juga bagian yang memungkinkan.
Secara pribadi, saya merasa pengembangan frontend melalui Python adalah area yang belum terlalu berkembang.
Opini Hacker News
Dalam kode, saat ada variabel lingkungan yang hilang lalu menampilkan pesan seperti “YOUTUBE_API_KEY atau YOUTUBE_CHANNEL_ID tidak ada” dengan OR, itu justru menyusahkan pengguna dalam situasi yang sebenarnya tidak perlu memakai OR. Jauh lebih baik memeriksa masing-masing nilai secara terpisah dan memberi tahu dengan jelas mana yang hilang. Selisih waktu pengembangannya juga nyaris tidak ada, jadi ini yang direkomendasikan
Ini memang terdengar seperti membahas detail kecil secara obsesif, tapi menurut saya kasus seperti ini sangat cocok untuk memakai operator := (walrus operator). Misalnya bisa langsung ditulis seperti
if not (API_KEY := os.getenv("API_KEY")):. Secara pribadi, untuk alat internal saya biasanya membiarkanKeyErrormeledak begitu saja darios.environ["API_KEY"]. Menurut saya itu juga sudah cukup jelasLebih jauh lagi, menurut saya jauh lebih baik memeriksa kondisi satu per satu lalu jika ada yang hilang, beri tahu semuanya sekaligus. Ini mengurangi kerepotan menjalankan program hanya untuk melihat satu variabel hilang, lalu melihat error variabel lain sesudahnya. Terkadang memang tidak bisa dihindari, tetapi sebisa mungkin lebih baik ditampilkan dalam satu kali proses
Cara terbaik adalah mengambil semua variabel lingkungan, lalu melaporkan mana saja yang hilang sekaligus
Ada juga cara memakai boolean flag lalu cukup
exit(1)sekali di bagian akhir. Dengan begitu, semua variabel lingkungan yang hilang bisa ditampilkan sekaligusBisa juga langsung keluar dengan kode 1 sambil mencetak pesan, seperti
exit("Missing ...")Jika sedang mencari alat yang otomatis membuat struktur proyek, saya merekomendasikan cookiecutter. Saya punya beberapa template yang sering dipakai, seperti python-lib, click-app, datasette-plugin, llm-plugin. Cara pakainya seperti ini:
uvx cookiecutter gh:simonw/python-libSaya membuat sesuatu bernama baker dalam Ruby. baker tidak menyalin repo template, melainkan membuat daftar pekerjaan yang harus dilakukan (daftar langkah imperatif), dan bisa mencampur pekerjaan manual (mengambil API key lalu mengaturnya) dengan pekerjaan otomatis (
'uv init'dan sejenisnya). Bisa memakai sintaks Markdown, Ruby string interpolation, dan bash. Saya membuatnya karena sudah sangat lelah dengan config berbasis ymlYang sedang naik daun belakangan ini adalah alat bernama Copier. Detailnya lihat dokumentasi copier
Saya justru menikmati menyiapkan proyek baru. Saya tidak merasa perlu mengotomatiskan hal seperti ini
Saya rasa alat otomatisasi struktur seperti ini memang area yang sangat cocok untuk workflow pengembangan LLM berbasis agen saat ini
Penilaian bahwa "Python lebih ramah manusia karena sudah terpasang bawaan di sebagian besar Unix" terasa agak terlalu optimistis. Begitu melewati level
import json, Anda cepat atau lambat akan jatuh ke neraka virtualenv. Untuk menjalankan di lingkungan Python 3.13.x pada Ubuntu 22.04 atau 24.04, Rocky 9, dan sebagainya, pada akhirnyavenv, container, atau version manager jadi keharusanBahkan pustaka dasar seperti “import json”, jika bahasanya tidak disertakan, biasanya tetap harus diinstal terpisah, tetapi Python memberi produktivitas awal yang tinggi berkat standard library. Memang untuk proyek besar standard library saja tidak cukup, tetapi saya benar-benar pernah mendistribusikan berbagai kode produksi hanya dengan standard library tanpa masalah deployment atau manajemen keamanan. Mengelola
venvjuga tidak sesulit dulu, dan package manager pun sudah berkembangSalah satu teori bercanda yang sering saya katakan adalah bahwa setengah alasan Docker/container menyebar secepat ini adalah karena ia membantu mengatasi neraka dependensi Python. Pengalaman Python pertama saya adalah memasang layanan Python di server pada 2012, dan itu benar-benar mengerikan: neraka dependensi, perintah
venv, pengaturan environment yang sulit ditangani. Dipip,brew, dan environment macOS pun saya cuma terus-terusan berkutat tanpa hasil, jadi begitu melihat Python saya langsung menghindar. Tapi belakangan, berkatuv, dari sudut pandang pemula pun Python terasa jauh lebih baik.uv init,uv add, danuv runsaja sudah cukupSaya rasa virtualenv memang harus selalu dipakai. Pada akhirnya itu hanya sebuah direktori, dan sekarang kalau mencoba instal secara global ke sistem dengan
pip, akan muncul peringatan dan sebagainya, jadi tidak sesulit duluSebaiknya memang wajib memakai virtualenv atau container. Meski terasa sulit ditangani, itu membantu menghindari dampak ke seluruh sistem saat ada update atau kenaikan versi library
Dulu sering kali yang tersedia bawaan di sistem hanya Python2, dan kadang sistem itu sendiri bergantung pada Python2 tersebut, jadi justru lebih berbahaya
Python terasa sekaligus bertele-tele dan kurang memadai. Untuk melakukan sesuatu yang sederhana, kadang harus menambahkan 500 dependensi, atau kalau tidak, kode malah membengkak dari puluhan hingga ratusan baris bahkan untuk hal yang sangat sepele. Karena itulah saya menghindari Python karena terlalu banyak kerja sia-sia yang tidak perlu. Dengan Perl, saya bisa menyelesaikan hal yang sama jauh lebih cepat dan ringkas, jadi saya lebih memilih Perl. Python terasa seperti pemrograman demi pemrograman, bukan demi pekerjaan yang ingin dilakukan
Saya juga membuat banyak proyek tanpa dependensi. Dengan standard library dan satu file saja, sebenarnya bisa melakukan sangat banyak hal. Selama Python terpasang, tinggal unduh pakai
curllalu jalankan. Misalnya saya punya alat CLI pengelolaan uang sepanjang 2000 baris, plutus, yang hanya memakai sekitar 12 modul standar. Sekitar 25% dari kodenya adalah bagian parsing command denganargparse. Saya suka menulisnya dengan jelas, misalnya satu baris untuk tiap parameterAnda bilang Perl lebih cepat dan lebih kuat daripada Python; saya penasaran contoh konkretnya seperti apa
Python enak karena saat menumpuk struktur data, saya bisa langsung menulis tanpa banyak berpikir. List berisi tuple, dictionary, dan lain-lain bisa dicampur bebas, dan semuanya bisa diakses dengan sintaks yang seragam. Perl jelas lebih pintar dan lebih menyenangkan, tetapi justru karena itu kepala saya lebih mudah kusut, jadi kurang cocok untuk saya. Python memang terasa membosankan, tetapi kejernihannya sangat tinggi sehingga lima tahun kemudian pun masih mudah dipahami
Saya rasa Python cukup layak dipakai bahkan hanya dengan standard library
Saya penggemar struktur monorepo, tetapi di perusahaan lama saya, pendekatan ini pernah membuat struktur menjadi sangat besar dan gemuk sampai tak seorang pun berani menyentuhnya karena takut tanpa sengaja merusak kode tim lain. Inti masalahnya sebenarnya bukan pada repo itu sendiri, melainkan karena
requirements.txtdikelola sebagai satu file untuk seluruh repo atau karena skrip build menjadi kusut. Secara teori, sekali update dependensi seharusnya semua kode menjadi aman dengan patch terbaru, tetapi di dunia nyata tak seorang pun bisa menyentuhnya. Monorepo hanya berjalan baik ketika organisasinya sangat NIH (punya kecenderungan membuat semuanya sendiri, seperti Google). Karena pengalaman seperti ini, saya malah mulai lebih menghargai arsitektur microservice di mana tiap layanan selaras dengan struktur tim dalam organisasi. Lihat juga Conway's lawPython adalah bahasa yang paling mendekati cara kerja pseudocode yang saya tulis. Setiap bagian yang dalam kepala saya terasa jelas begitu saja, Python benar-benar menyediakan abstraksi intuitif untuk itu. Saya datang dari latar belakang berbasis matematika, jadi bahasa ini terasa sangat memuaskan. Tentu sekarang saya juga suka bahasa lain, tetapi Python tetap punya daya tarik tersendiri
Saya membangun struktur proyek dengan pola yang nyaris sama. Miripnya sampai terasa menyeramkan. Saya jadi berpikir bahwa ekosistem developer Python makin lama makin berkumpul ke gaya yang serupa. Dulu saya mengira pilihan saya unik, tetapi kalau ternyata semua orang melakukan hal yang sama, rasanya kebebasan saya ini ke mana. Mirip fenomena memberi nama bayi yang umum, saat pilihan yang kita kira unik ternyata sebenarnya adalah nama populer nomor 2
Struktur seperti ini sudah populer di dunia Python sejak 10 tahun lalu. Pada akhirnya, sepertinya banyak engineer rasional yang setelah mempertimbangkan matang-matang akan secara alami berkumpul pada pola ini
Rasanya ego manusia seperti gelombang kuantum pilot-wave yang tersebar di seluruh spektrum, lalu berubah menjadi eksistensi. becoming-being, bikin tertawa sendiri
Senang rasanya melihat orang lain juga mulai menyukai Python. Dulu saya lebih menyukai Ruby, tetapi karena tuntutan pelanggan saya terpaksa memakai Python. Dahulu Ruby memang jauh lebih lambat, namun sambil dipaksa mempelajari Python saya lama-lama terbiasa, dan sekarang cukup menikmatinya. Soal cara memakai Make, saya agak berbeda pendapat: kalau sama sekali tidak memakai dependensi, itu pada dasarnya tidak beda dengan skrip yang berisi case statement... setengah bercanda saya bilang begitu, tetapi melihat generasi sekarang tidak akrab dengan Make rasanya agak getir. Semacam perasaan “di zaman saya dulu”
Ruby jauh lebih indah secara sintaks. Python yang membedakan scope hanya dengan indentasi bukan gaya saya
Awalnya saya juga mulai dari skrip dengan case statement, lalu akhirnya berevolusi menjadi Makefile datar. Makefile lebih standar dan lebih mudah dipahami daripada skrip acak
Saya penasaran kapan sebaiknya memakai Dataclass dan kapan Pydantic Basemodel. Kalau sudah memakai Pydantic, bukankah lebih baik sekalian menyeragamkan semuanya ke Pydantic? Saya bertanya-tanya apakah masih ada alasan untuk tetap memakai Dataclass
Ada tulisan perbandingan yang sangat rapi dari proyek attrs. Ada perbandingan resmi attrs, tentu mungkin ada sedikit bias, tetapi menurut saya dasar logikanya cukup kuat. Dan blog ini juga membantu
Dataclass tidak mendukung validasi nested object. Jadi untuk struktur datar yang sederhana sebagai pengantar argumen fungsi, lebih baik memakai dataclass. Itu lebih jelas daripada menerima terlalu banyak argumen dalam list
Ada isu penurunan performa karena validasi data saat pembuatan objek. Ada juga alternatif yang jauh lebih ringan dan cepat seperti msgspec
Kalau memang tidak perlu validasi atau serialisasi, Pydantic justru hanya menjadi overhead yang tidak perlu. Prinsip saya: kalau perlu serialisasi, pakai Pydantic; kalau tidak, pakai dataclass
Anda bisa langsung memakai dataclass yang sudah ada seperti
TypeAdapter(MyDataclass), jadi saya merasa tidak ada alasan kuat untuk membuat model Pydantic terpisahBelakangan ini justru saya pindah dari Python ke bahasa lain dan lebih puas. Pikiran saya tentang Python saya rangkum di tulisan ini. Kalau nanti ada kesempatan memakai Python lagi, saya pasti ingin mencoba
uv,ruff, dantyasyncadalah peningkatan produktivitas terbesar. Python memang punyaasyncio, tetapi ada banyak pendekatan yang saling bersaing dan tidak ada standar yang benar-benar mapan. Saya lebih nyaman dengan JS karena semua berkumpul pada satu cara. Kalau dijumlahkan, banyak hal kecil juga menghasilkan perbedaan besar, dan bagi saya Python kalah di beberapa sisi seperti scoping berbasis indentasi, masalah relative path pada import, sintaks object di JS, dan lain-lain yang terasa lebih nyaman. Lihat juga penjelasan terkait