Python ile requirements.txt Oluşturma ve Kullanımı

Python projeleri geliştirirken en sık karşılaşılan sorunlardan biri, “bende çalışıyor ama sende çalışmıyor” durumudur. Bu klasik problem genellikle eksik ya da uyumsuz kütüphanelerden kaynaklanır. İşte tam bu noktada requirements.txt dosyası hayat kurtarıcı oluyor. Bir projede hangi paketlerin hangi versiyonlarıyla kullanıldığını kayıt altına alan bu basit metin dosyası, hem ekip çalışmasını hem de deployment süreçlerini son derece kolaylaştırıyor. Bu yazıda requirements.txt dosyasını nasıl oluşturacağınızı, nasıl kullanacağınızı ve gerçek dünya senaryolarında nelere dikkat etmeniz gerektiğini ele alacağız.

requirements.txt Nedir ve Neden Önemlidir?

requirements.txt, bir Python projesinin bağımlılıklarını listeleyen düz metin dosyasıdır. Her satırda bir paket adı ve isteğe bağlı olarak versiyon bilgisi bulunur. Bu dosya sayesinde projenizi başka bir makineye taşıdığınızda ya da bir ekip arkadaşınız projeyi klonladığında, tek bir komutla tüm bağımlılıklar kurulabilir.

Gerçek dünya senaryosu şu şekilde işliyor: Diyelim ki bir Flask uygulaması geliştirdiniz. Geliştirme ortamınızda Flask 2.3.2, SQLAlchemy 2.0.1 ve Requests 2.28.0 kullanıyorsunuz. Projeyi production sunucusuna taşıdığınızda ya da CI/CD pipeline’ınızda bu versiyonları tek tek kurmak zorunda kalmak istemezsiniz. İşte requirements.txt bu sorunu elegantça çözüyor.

Ayrıca bir projeyi altı ay sonra tekrar açtığınızda hangi kütüphane versiyonlarını kullandığınızı hatırlamanız neredeyse imkansızlaşır. Requirements.txt bu konuda da bir belgeleme aracı işlevi görüyor.

Sanal Ortam ile Çalışmanın Önemi

Requirements.txt’den bahsetmeden önce sanal ortamları konuşmak şart. Sanal ortam olmadan requirements.txt kullanmak, sisteminizdeki tüm paketleri projenizin bağımlılıkları olarak listelemek anlamına gelir. Bu hem kirli hem de yönetilmesi zor bir durum yaratır.

# Python ile sanal ortam oluşturun
python3 -m venv proje_env

# Sanal ortamı aktif edin (Linux/macOS)
source proje_env/bin/activate

# Sanal ortamı aktif edin (Windows)
proje_envScriptsactivate

# Sanal ortamı deaktif etmek için
deactivate

Sanal ortamı aktifleştirdikten sonra kurduğunuz tüm paketler yalnızca bu ortama özgü olur. Böylece requirements.txt oluşturduğunuzda gerçekten sadece projenizle ilgili paketler listeye girer.

pip freeze ile requirements.txt Oluşturma

En temel yöntem pip freeze komutunu kullanmaktır. Bu komut, aktif ortamda kurulu tüm paketleri ve versiyonlarını listeler.

# Sanal ortamı aktifleştirdikten sonra paketleri kurun
pip install flask sqlalchemy requests

# pip freeze ile requirements.txt oluşturun
pip freeze > requirements.txt

# Dosyanın içeriğini görüntüleyin
cat requirements.txt

Bu komutu çalıştırdığınızda içerik şuna benzer görünecektir:

blinker==1.6.2
click==8.1.3
Flask==2.3.2
greenlet==2.0.2
itsdangerous==2.1.2
Jinja2==2.11.3
MarkupSafe==2.1.1
requests==2.28.0
SQLAlchemy==2.0.1
urllib3==1.26.15
Werkzeug==2.3.4

Burada dikkat etmeniz gereken bir nokta var: pip freeze doğrudan kurduğunuz paketlerin yanı sıra bu paketlerin bağımlılıklarını da listeler. Flask kurduğunuzda otomatik gelen Werkzeug, Jinja2 gibi paketler de listeye dahil olur. Bu bazen gereksiz bir karmaşıklık yaratabilir.

pip list ile Kurulu Paketleri Görüntüleme

Freeze komutunu kullanmadan önce hangi paketlerin kurulu olduğunu görmek isterseniz pip list işinizi görür.

# Kurulu tüm paketleri listele
pip list

# Sadece güncel olmayan paketleri listele
pip list --outdated

# Belirli bir formatta çıktı al
pip list --format=columns

pip list ile pip freeze arasındaki temel fark şudur: pip list daha okunabilir bir formatta çıktı verirken, pip freeze requirements.txt formatında yani doğrudan kullanılabilir biçimde çıktı üretir.

requirements.txt Dosyasını Manuel Oluşturma

Her zaman otomatik oluşturma en iyi yol değildir. Özellikle hangi paketlerin direkt bağımlılık olduğunu, hangilerinin alt bağımlılık olduğunu ayırt etmek istiyorsanız, requirements.txt dosyasını manuel yazmanız mantıklı olabilir.

# Örnek bir requirements.txt dosyası

# Web framework
Flask==2.3.2

# Veritabanı
SQLAlchemy==2.0.1

# HTTP istekleri
requests>=2.28.0

# Güvenlik
cryptography~=41.0

# Test araçları (sadece geliştirme ortamı için)
pytest>=7.0.0
pytest-cov==4.1.0

Versiyon belirtme sözdiziminde birkaç farklı yöntem kullanılabilir:

  • Flask==2.3.2: Tam versiyon eşleşmesi, yani sadece bu versiyon kurulur
  • requests>=2.28.0: 2.28.0 ve üzeri herhangi bir versiyon kurulabilir
  • requests<=2.28.0: 2.28.0 ve altı herhangi bir versiyon kurulabilir
  • requests>=2.26.0,<3.0.0: Belirtilen aralıkta bir versiyon kurulur
  • cryptography~=41.0: 41.0 ile uyumlu versiyonlar kurulabilir, yani 41.x serisi
  • flask: Versiyon belirtmeden kurulum, her zaman en güncel versiyon kurulur

Production ortamları için tam versiyon eşleşmesi (==) kullanmanızı şiddetle öneririm. Bu sayede beklenmedik güncelleme sorunlarının önüne geçersiniz.

requirements.txt’den Paket Kurma

Dosyayı oluşturduktan sonra kullanımı son derece basittir.

# requirements.txt'deki tüm paketleri kur
pip install -r requirements.txt

# Belirli bir dosyadan kur
pip install -r /path/to/requirements.txt

# Sessiz modda kur (az çıktı)
pip install -q -r requirements.txt

# Önce cache temizle sonra kur (temiz kurulum için)
pip install --no-cache-dir -r requirements.txt

-r parametresi “requirements” anlamına gelir ve pip’e bir dosyadan okuma yapmasını söyler. Proje deposunu klonladıktan sonra yapmanız gereken ilk şey genellikle budur.

Ortam Bazlı requirements Dosyaları

Gerçek projelerde genellikle farklı ortamlar için farklı bağımlılıklar gerekir. Geliştirme ortamında test kütüphaneleri, debug araçları, code formatter gibi araçlara ihtiyaç duyarsınız. Ancak production’a bu araçları taşımanız gerekmez.

Bu durumu yönetmek için birden fazla requirements dosyası kullanmak yaygın bir pratiktir.

# Proje dizin yapısı
requirements/
    base.txt        # Tüm ortamlar için ortak bağımlılıklar
    development.txt # Sadece geliştirme ortamı için
    production.txt  # Sadece production için
    testing.txt     # Test ortamı için

base.txt dosyası şöyle görünebilir:

# requirements/base.txt
Flask==2.3.2
SQLAlchemy==2.0.1
requests==2.28.0
python-dotenv==1.0.0
gunicorn==21.2.0

development.txt dosyasında ise base.txt’e referans verip üzerine geliştirme araçları ekleyebilirsiniz:

# requirements/development.txt
-r base.txt

# Debug araçları
flask-debugtoolbar==0.13.1
ipython==8.14.0

# Code quality
black==23.7.0
flake8==6.0.0
isort==5.12.0

# Test araçları
pytest==7.4.0
pytest-flask==1.2.0
factory-boy==3.3.0

Bu yapıyı kullanmak için:

# Geliştirme ortamında
pip install -r requirements/development.txt

# Production ortamında
pip install -r requirements/production.txt

# Test ortamında
pip install -r requirements/testing.txt

Bu yaklaşım hem temiz hem de sürdürülebilir bir yapı sağlar. Özellikle Docker container’larınızı oluştururken production.txt kullanmak, image boyutunu ciddi ölçüde küçültebilir.

pipreqs ile Akıllı requirements.txt Oluşturma

pip freeze ile oluşturulan dosya ortamdaki tüm paketleri listeler, bu yüzden gereksiz bağımlılıklar da dahil olabilir. pipreqs aracı ise kaynak kodunuzu analiz ederek sadece gerçekten kullanılan paketleri listeler.

# pipreqs'i kurun
pip install pipreqs

# Proje dizininde requirements.txt oluşturun
pipreqs /path/to/project

# Mevcut requirements.txt dosyasını üzerine yaz
pipreqs /path/to/project --force

# Encoding belirterek çalıştırın
pipreqs /path/to/project --encoding=utf-8

# Sadece çıktıyı görüntüle, dosya oluşturma
pipreqs /path/to/project --print

pipreqs‘in avantajı, import ifadelerinizi tarayarak gerçekte projenizde kullandığınız paketleri tespit etmesidir. Sanal ortamda kurulu ama projede kullanmadığınız paketler listeye girmez. Öte yandan dezavantajı da var: bazen import adı ile paket adı farklı olduğunda yanılabilir. Örneğin PIL import edildiğinde Pillow paketini tanımayabilir.

Bu yüzden pipreqs’i kullandıktan sonra oluşturulan dosyayı mutlaka kontrol edin ve gerekirse düzeltin.

pip-tools ile Gelişmiş Bağımlılık Yönetimi

Daha büyük projelerde pip-tools paketi çok işe yarar. Bu araç, pip compile ve pip sync komutlarıyla bağımlılıkları daha kontrollü bir şekilde yönetmenizi sağlar.

# pip-tools'u kurun
pip install pip-tools

# requirements.in dosyası oluşturun (sadece direkt bağımlılıklar)
cat > requirements.in << EOF
Flask
SQLAlchemy
requests
EOF

# pip-compile ile requirements.txt oluşturun
pip-compile requirements.in

# Güncel versiyonlara yükselt
pip-compile --upgrade requirements.in

# pip-sync ile ortamı senkronize edin
pip-sync requirements.txt

pip-tools‘un sağladığı asıl değer şudur: requirements.in dosyasında sadece direkt bağımlılıklarınızı tutarsınız. pip-compile komutu ise tüm alt bağımlılıkları çözümleyerek versiyon kilitli ve deterministik bir requirements.txt oluşturur. Bu dosya, tam olarak hangi versiyonların kurulacağını garanti eder.

Ayrıca pip-sync komutu, ortamınızı requirements.txt ile tam olarak senkronize eder. Listede olmayan paketleri siler, listelenen ama kurulu olmayanları kurar. Bu özellik özellikle CI/CD süreçlerinde çok değerlidir.

Gerçek Dünya Senaryo: Docker ile requirements.txt Kullanımı

Docker kullanan bir Flask uygulaması geliştirdiğinizi düşünün. Aşağıdaki Dockerfile örneği, requirements.txt’i production ortamında nasıl kullanacağınızı gösteriyor.

# Dockerfile içinde requirements.txt kullanımı

# requirements.txt dosyasını oluşturmak için
pip freeze > requirements.txt

# Gereksiz paketleri temizlemek için
pip install --no-cache-dir -r requirements.txt

# Docker build sırasında cache'den faydalanmak için
# önce requirements.txt kopyalanır, sonra uygulama kodu
# Bu sayede bağımlılıklar değişmediğinde cache kullanılır
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .

Bu Dockerfile stratejisi önemli bir optimizasyon sağlar. Docker katmanlarını verimli kullanan bu yaklaşımda, eğer sadece uygulama kodunuz değişmişse ve bağımlılıklarınız aynıysa, pip install adımı cache’den gelir ve build süreci ciddi ölçüde hızlanır.

Güvenlik Açısından requirements.txt

Bağımlılık yönetiminde güvenlik son derece önemli. Kullandığınız paketlerde güvenlik açıkları olup olmadığını düzenli olarak kontrol etmelisiniz.

# pip-audit ile güvenlik taraması yapın
pip install pip-audit
pip-audit -r requirements.txt

# safety aracı ile kontrol edin
pip install safety
safety check -r requirements.txt

# Belirli bir paketi güvenli versiyona yükseltin
pip install --upgrade requests
pip freeze > requirements.txt

Özellikle açık kaynak projelerde ya da müşteri verisiyle çalışan uygulamalarda bu taramaları CI/CD pipeline’ınıza dahil etmenizi öneririm. GitHub Actions ya da GitLab CI’da otomatik güvenlik taraması yapmak artık standart bir pratik haline geldi.

Hash Doğrulama ile Güvenli Kurulum

Production ortamlarında paket bütünlüğünü doğrulamak için hash kullanabilirsiniz.

# Hash ile requirements.txt oluşturmak için pip-compile kullanın
pip-compile --generate-hashes requirements.in

# Hash doğrulamalı kurulum
pip install --require-hashes -r requirements.txt

Hash doğrulamalı bir requirements.txt dosyası şöyle görünür:

Flask==2.3.2 
    --hash=sha256:8c2f9abd47a9e8df7f0c3f091ce9497d011dc3b31effcf4c85a6e2b50f4114ef 
    --hash=sha256:2e2d6a7b392e5c6b9f1a3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f

Bu yöntem özellikle supply chain saldırılarına karşı etkili bir koruma sağlar. PyPI’daki bir paket ele geçirilse bile, hash eşleşmediği için kurulum başarısız olur.

Sık Yapılan Hatalar ve Çözümleri

Yıllar içinde en sık gördüğüm hataları ve çözümlerini paylaşayım:

  • Sanal ortam aktif değilken freeze çalıştırmak: Sistem genelindeki tüm paketler requirements.txt’e dahil olur. Çözüm, her zaman sanal ortamı aktifleştirip kontrol edin: which python komutu sanal ortamın python’ını göstermelidir.
  • Versiyon belirtmemek: Flask yazmak yerine Flask==2.3.2 yazın. Versiyonsuz paketler zamanla uyumsuzluk sorununa yol açar.
  • requirements.txt’i Git’e eklememek: Bu dosya projenizin ayrılmaz bir parçası, mutlaka commit edin. Tersine, proje_env/ ya da venv/ dizinini .gitignore‘a ekleyin.
  • Alt bağımlılıkları manuel düzenlemek: pip-tools kullanıyorsanız direkt requirements.txt’i değil, requirements.in’i düzenleyin.
  • Ortam dosyalarını karıştırmak: Geliştirme paketlerini production requirements.txt’ine eklemeyin. Büyük ölçüde artan image boyutu ve güvenlik riski yaratır.

Sonuç

Requirements.txt, Python projelerinde bağımlılık yönetiminin temel taşıdır. Basit görünen bu metin dosyası, aslında projenizin taşınabilirliğini, tekrarlanabilirliğini ve güvenilirliğini doğrudan etkiler.

Küçük kişisel projeler için pip freeze > requirements.txt yeterli olacaktır. Ekip projeleri ya da kurumsal uygulamalar için ise ortam bazlı requirements dosyaları ve pip-tools kombinasyonu çok daha sağlıklı bir yol sunar. Production ortamlarında ise hash doğrulama ve düzenli güvenlik taramasını ihmal etmeyin.

Son olarak şunu vurgulamak isterim: requirements.txt sadece bir dosya değil, projenizin bir belgelemesidir. Bu dosyaya baktığınızda projenizin hangi ekosisteme dayandığını, hangi araçları kullandığını ve hangi döneme ait teknoloji kararları aldığınızı görebilirsiniz. Bu yüzden onu ciddiye alın, güncel tutun ve versiyonlama sisteminizde mutlaka takip edin.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir