Projeniz üretim (production) sunucusuna dağıtılmaya hazır ama acaba script’iniz gerçekten izole bir sanal ortam (virtual environment) içinde mi çalışıyor, yoksa sistem genelindeki (global) Python kurulumuna mı bulaşıyor? Bu soruyu manuel kontrol etmek yerine, koda birkaç satırla otomatik bir “sağlık kontrolü” (health check) ekleyebilirsiniz.
Dağıtım Öncesi Son Savunma Hattı
Bu proje, gerçek bir CI/CD boru hattının (pipeline) son adımında çalışacak küçük ama kritik bir doğrulama script’i modelliyor. Amaç basit: uygulamanın üretim sunucusuna çıkmadan hemen önce, çalıştığı ortamın gerçekten izole bir sanal ortam olduğunu ve gerekli üçüncü parti paketlerin (bu örnekte requests) kurulu olduğunu garanti altına almak.
Neden bu kadar önemli? Çünkü global Python kurulumuna paket yüklemek, farklı projelerin birbirinin bağımlılık sürümlerini ezmesine (dependency çakışması) yol açabilir. Bir sunucuda 5 farklı uygulama çalışıyorsa ve hepsi global ortamı paylaşıyorsa, birinin paket güncellemesi diğerini sessizce bozabilir. Sanal ortamlar tam olarak bu riski ortadan kaldırmak için var: her proje kendi bağımlılık “baloncuğunda” yaşar.
Script, üretime çıkmadan önce iki temel soruyu yanıtlıyor:
- Kod, izole bir
.venviçinde mi çalışıyor, yoksa global Python’da mı? - Gerekli bağımlılıklar (
requestsgibi) bu ortamda kurulu mu?
Herhangi biri “hayır” ise, script sys.exit(1) ile pipeline’ı durduruyor — böylece hatalı bir dağıtım, canlıya çıkmadan önce yakalanmış oluyor.
venv, virtualenv ve conda: Hangisi Ne Zaman?
Python ekosisteminde sanal ortam oluşturmanın birden fazla yolu var, bu yüzden kısa bir netleştirme faydalı olacaktır:
venv: Python 3.3 ile birlikte standart kütüphaneye eklendi, ekstra kurulum gerektirmez. Bu projede kullanılan da bu — çünkü hiçbir ek bağımlılık istemeden her Python 3 kurulumunda hazır bulunur.virtualenv:venv‘den önce var olan, üçüncü parti bir pakettir. Daha eski Python sürümlerini de destekler ve bazı gelişmiş özellikler sunar, ancak günümüzde çoğu proje içinvenvyeterlidir.conda: Özellikle veri bilimi ve makine öğrenmesi projelerinde tercih edilir; yalnızca Python paketlerini değil, C/C++ tabanlı sistem kütüphanelerini de yönetebilir.
Bu projede standart venv modülünün seçilmesi tesadüf değil: hiçbir harici araca ihtiyaç duymadan, “her Python kurulumunda çalışır” garantisi vermek istiyoruz — özellikle bir dağıtım/sağlık kontrol script’i için bu güvenilirlik kritik.
Kodun Anatomisi
İşin en zekice kısmı, Python’ın kendi standart kütüphanesindeki iki değişkenin karşılaştırılması: sys.prefix ve sys.base_prefix. Bir sanal ortam aktifken sys.prefix, .venv klasörünü gösterir; sys.base_prefix ise her zaman sistemin asıl Python kurulumunu işaret eder. Bu ikisi birbirinden farklıysa, kod bir sanal ortam içinde çalışıyor demektir:
import sys
# base_prefix, sanal ortam aktif değilken sys.prefix ile aynıdır
in_virtualenv = sys.prefix != getattr(sys, "base_prefix", sys.prefix)
print(f" -> İzolasyon Durumu : {'AKTİF (.venv)' if in_virtualenv else 'PASİF (GLOBAL)'}")
print(f" -> Python Yolu : {sys.executable}")
print(f" -> Python Sürümü : {sys.version.split()[0]}")
if not in_virtualenv:
print("[Kritik Tehlike] Uygulama global olarak çalışıyor! Pipeline durduruluyor.")
sys.exit(1)
getattr(sys, "base_prefix", sys.prefix) kullanımı da dikkat çekici bir savunmacı programlama (defensive programming) örneği: base_prefix özniteliği çok eski Python sürümlerinde bulunmayabilir, bu yüzden getattr ile güvenli bir varsayılan değer (fallback) sağlanıyor.
İkinci kontrol ise klasik bir try/except ImportError deseniyle yapılıyor. requests kütüphanesi içeri aktarılmaya çalışılıyor; başarısız olursa paketin eksik olduğu anlaşılıyor:
try:
import requests
REQUESTS_AVAILABLE = True
except ImportError:
REQUESTS_AVAILABLE = False
if not REQUESTS_AVAILABLE:
print("[Dağıtım Hatası] Gerekli paketler eksik. 'pip install -r requirements.txt' çalıştırın.")
sys.exit(1)
Bu desenin güzelliği şu: kodun geri kalanı requests kütüphanesini doğrudan kullanmadan önce, onun var olup olmadığını zarif bir şekilde (programı çökertmeden) kontrol edebiliyor. Gerçek bir sağlık kontrol script’inde bu mantık genellikle veritabanı bağlantısı, ortam değişkenleri (environment variables) veya disk alanı gibi başka kontrollerle de genişletilir.
Nasıl Çalıştırılır?
Önce script’i hiçbir sanal ortam olmadan, doğrudan global Python ile çalıştırarak güvenlik kontrolünün gerçekten devreye girdiğini görün:
python3 main.py
Beklenen çıktı, pipeline’ı durduran bir uyarı olacaktır:
-> Isolation Layer Status : INACTIVE (GLOBAL)
[Critical Danger] Application is running globally! Aborting pipeline to prevent host pollution.
Şimdi gerçek senaryoyu kurun: izole bir sanal ortam oluşturup aktifleştirin ve bağımlılığı içine kurun:
python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install requests
python3 main.py
Bu kez script’in ACTIVE (.venv) ve SUCCESS mesajlarıyla yeşil ışık yakması gerekir. Bağımlılıkları sabitlemek (pinlemek) için bir requirements.txt dosyası tutmak istiyorsanız, requests==2.31.0 gibi kesin sürüm numaraları yazmak, “benim makinemde çalışıyordu” sorununu büyük ölçüde önler. Bu konuda pip‘in klasik requirements.txt yaklaşımına daha modern bir alternatif arıyorsanız, requirements.txt’ye Veda: Poetry ile Python Paket Yönetimi yazımıza göz atabilirsiniz.
Ne Öğrendik?
Bu projede öğrendiklerimizi özetleyelim:
sys.prefixvesys.base_prefixkarşılaştırması, bir Python script’inin sanal ortam içinde çalışıp çalışmadığını programatik olarak anlamanın standart yolu.try/except ImportError, bir bağımlılığın kurulu olup olmadığını kontrol etmek için basit ama etkili bir desen.sys.exit(1), bir script’in başarısız bir durumu diğer sistemlere (örneğin bir CI/CD aracına) bildirmesinin standart yolu — sıfırdan farklı çıkış kodları genellikle “bir şeyler yanlış gitti” anlamına gelir.- İzolasyonun neden önemli olduğu: sanal ortamlar, farklı projelerin bağımlılıklarını birbirinden ayırarak “bende çalışıyordu” kabusunu önemli ölçüde azaltır.
Bu tarz küçük sağlık kontrolleri, büyük ölçekli dağıtım sistemlerinin görünmeyen ama hayati kahramanlarıdır — genellikle fark edilmezler, ta ki eksik oldukları güne kadar.
Kaynaklar ve Sonraki Adımlar
Bu script’i genişletmek isterseniz, ortam değişkenlerinin (os.environ) doğru ayarlandığını, disk alanının yeterli olduğunu veya bir veritabanına bağlanılabildiğini kontrol eden ek adımlar ekleyebilirsiniz. Daha ileri bir seviyede, tek bir requests paketi yerine requirements.txt dosyasındaki tüm satırları döngüyle kontrol eden, hangi paketin eksik olduğunu tek tek raporlayan bir sürüm de yazılabilir — böylece hata mesajı “bir şey eksik” yerine “tam olarak şu paket eksik” der.
Gerçek bir CI/CD ortamında bu tür script’ler genellikle bir GitHub Actions veya GitLab CI adımı olarak, kod dağıtılmadan hemen önce otomatik çalıştırılır ve başarısız olursa tüm pipeline’ı durdurarak hatalı bir sürümün canlıya sızmasını engeller. Bu, “test et, sonra dağıt” felsefesinin küçük ama somut bir uygulamasıdır.
Ahmet Aksoy
Not: Bu yazıda incelediğimiz kodu ve benzer projelerin kaynak kodlarını https://github.com/ahmetax/practical-python-examples adresinde bulabilirsiniz.



