Satu kode pipeline biasanya berjalan di tiga tempat: laptop saat pengembangan, server staging untuk pengujian, dan server production dengan data nyata. Alamat database, tingkat log, dan ukuran batch pasti berbeda antar ketiganya. Bila nilai-nilai tersebut ditulis permanen di dalam kode, setiap deployment menuntut pengubahan kode dan membuka peluang kelalaian. Environment variable menjadi jembatannya: kode membaca pengaturan dari luar, sedangkan setiap lingkungan menyuplai nilai yang sesuai.
Membaca Environment Variable dari Python #
Modul os menyediakan dua pintu baca. Akses os.environ mengambil dari kamus variabel proses, sedangkan fungsi os.getenv() menambahkan kemudahan berupa nilai bawaan (default) saat variabel belum diatur:
import os
# Membaca environment variable dengan os.environ
print("USER :", os.environ.get("USER"))
# os.getenv dengan nilai bawaan bila variable belum diatur
print("APP_ENV :", os.getenv("APP_ENV", "belum diatur"))
print("LOG_LEVEL :", os.getenv("LOG_LEVEL", "INFO"))
print("MAX_RETRIES :", os.getenv("MAX_RETRIES", "3"))Output yang Dihasilkan:
USER : z
APP_ENV : belum diatur
LOG_LEVEL : INFO
MAX_RETRIES : 3Variabel USER memang sudah diatur oleh sistem sehingga nilainya tercetak. Sebaliknya, APP_ENV belum diatur, sehingga nilai bawaan "belum diatur" yang muncul. Kita juga dapat menetapkan variabel hanya untuk satu kali eksekusi, dengan menuliskannya di depan perintah:
APP_ENV=production python3 baca_env.pyOutput yang Dihasilkan:
USER : z
APP_ENV : production
LOG_LEVEL : INFO
MAX_RETRIES : 3Hanya baris APP_ENV yang berubah menjadi production — variabel tersebut hanya hidup selama proses Python berjalan dan tidak mengubah pengaturan shell secara permanen. Dokumentasi lengkap kedua fungsi tersebut ada di https://docs.python.org/3/library/os.html
.
Berkas .env dan python-dotenv #
Mengetik variabel panjang di depan setiap perintah lelah dibaca. Praktik umum: simpan pasangan kunci-nilai di berkas .env pada akar proyek, lalu muat dengan pustaka python-dotenv (pasang lewat pip install python-dotenv). Misalnya berkas .env berikut:
APP_ENV=development
WAREHOUSE_DB_URL=postgresql://budi:YOUR_DATABASE_PASSWORD@localhost:5432/penjualan
LOG_LEVEL=INFOSkrip pembacanya menjadi ringkas:
from dotenv import load_dotenv
import os
# Muat berkas .env dari direktori kerja saat ini
load_dotenv()
print("APP_ENV :", os.getenv("APP_ENV"))
print("WAREHOUSE_DB_URL:", os.getenv("WAREHOUSE_DB_URL"))
print("LOG_LEVEL :", os.getenv("LOG_LEVEL"))Output yang Dihasilkan:
APP_ENV : development
WAREHOUSE_DB_URL: postgresql://budi:YOUR_DATABASE_PASSWORD@localhost:5432/penjualan
LOG_LEVEL : INFOMari kita telaah baris-baris kode di atas:
- Baris 1 (
from dotenv import load_dotenv): mengimpor fungsi pemuat dari pustaka python-dotenv. - Baris 5 (
load_dotenv()): membaca berkas.envdi folder kerja, mengurai setiap barisKUNCI=nilai, lalu mendaftarkannya ke environment variable proses. - Baris 7-9 (
os.getenv(...)): membaca variabel yang barusan didaftarkan dengan pola yang sama seperti contoh sebelumnya.
Perilaku Penimpaan load_dotenv #
Secara bawaan, load_dotenv() tidak menimpa variabel yang sudah terlebih dahulu diatur di shell. Skrip berikut diuji pada mesin yang variabel DATABASE_URL-nya sudah berisi nilai lain, sementara berkas .env menyimpan nilai PostgreSQL:
from dotenv import load_dotenv
import os
# DATABASE_URL sudah diatur di shell sebelum skrip berjalan.
# Secara bawaan load_dotenv() TIDAK menimpa nilai yang sudah ada.
load_dotenv()
print("tanpa override :", os.getenv("DATABASE_URL"))
# Dengan override=True, nilai dari .env menimpa nilai dari shell.
load_dotenv(override=True)
print("dengan override :", os.getenv("DATABASE_URL"))Output yang Dihasilkan:
tanpa override : file:/home/z/my-project/db/custom.db
dengan override : postgresql://budi:YOUR_DATABASE_PASSWORD@localhost:5432/penjualanBaris pertama membuktikan nilai shell tetap dipakai meskipun .env menyimpan nilai lain. Baris kedua menunjukkan parameter override=True membalik perilaku tersebut. Perilaku bawaan justru berguna di production: variabel yang diatur orchestrator selalu menang atas berkas .env yang mungkin lupa diperbarui.
Konfigurasi per Lingkungan #
Dengan pola di atas, satu kode cukup membaca APP_ENV lalu menyesuaikan diri. Perbedaan nilai antar lingkungan biasanya terpetakan rapi seperti tabel berikut:
| Aspek | development | staging | production |
|---|---|---|---|
APP_ENV | development | staging | production |
| Basis data | SQLite lokal | PostgreSQL staging | warehouse production |
LOG_LEVEL | DEBUG | INFO | WARNING |
| Isi data | sampel kecil | salinan tanpa data pribadi | data nyata |
Setiap lingkungan memiliki berkas .env versinya sendiri (atau sekumpulan variabel di sistem orchestrator), dan nilai APP_ENV menjadi saklar yang menentukan perilaku kode. Rincian pustaka python-dotenv tersedia di https://pypi.org/project/python-dotenv/
.
Berkas .env menuntut tata letak proyek yang rapi agar tidak tertukar antar lingkungan. Tata letak tersebut kita susun pada chapter Struktur Proyek Data Engineering.