Takip et

Giriş ve Neden Python Uygulamalarını Paketlemeliyiz?

Giriş ve Neden Python Uygulamalarını Paketlemeliyiz? Python, esnekliği ve geniş kütüphane ekosistemi sayesinde web geliştirmeden veri bi

Giriş ve Neden Python Uygulamalarını Paketlemeliyiz?

Python, esnekliği ve geniş kütüphane ekosistemi sayesinde web geliştirmeden veri bilimine, otomasyondan masaüstü uygulamalarına kadar birçok alanda yaygın olarak kullanılmaktadır. Ancak bir Python uygulamasını veya kütüphanesini geliştirmek, işin sadece yarısıdır. Geliştirilen bu yazılımın başkaları tarafından kolayca kullanılabilmesi, bağımlılıklarının doğru bir şekilde yönetilmesi ve farklı ortamlarda sorunsuz çalışabilmesi için “paketleme” süreci kritik öneme sahiptir.

Paketleme, Python kodunuzu ve ilişkili tüm dosyaları (veri dosyaları, yapılandırma dosyaları, belgeler vb.) tek bir dağıtılabilir birim haline getirme işlemidir. Bu birim, genellikle bir arşiv dosyası (.tar.gz, .whl) şeklinde olup, Python Paket Dizini (PyPI) gibi depolarda barındırılabilir veya doğrudan dağıtılabilir. Paketlemenin temel faydaları şunlardır:

  • Yeniden Kullanılabilirlik: Kodunuzu bir paket olarak yayımladığınızda, başkaları (veya siz kendiniz) onu projelerine kolayca dahil edebilir ve tekrar tekrar kullanabilir.
  • Bağımlılık Yönetimi: Paketleme araçları, projenizin ihtiyaç duyduğu diğer kütüphaneleri (bağımlılıkları) açıkça belirtmenize olanak tanır. Bu sayede kullanıcılar paketinizi kurduklarında gerekli tüm bağımlılıklar otomatik olarak yüklenir ve “bağımlılık cehennemi” yaşanmaz.
  • Kolay Dağıtım: PyPI gibi merkezi depolar sayesinde, paketinizi dünyanın dört bir yanındaki geliştiricilere birkaç komutla ulaştırabilirsiniz.
  • Profesyonellik ve Güvenilirlik: İyi paketlenmiş bir proje, geliştiricinin yazılıma verdiği önemi gösterir ve kullanıcılar için daha güvenilir bir izlenim yaratır.
  • Sürüm Kontrolü: Paketleme, yazılımınızın farklı sürümlerini yönetmenizi kolaylaştırır, hataları düzeltmeyi ve yeni özellikler eklemeyi sistematik hale getirir.

Bu rehberde, Python uygulamalarınızı ve kütüphanelerinizi nasıl paketleyeceğinizi, bağımlılıkları nasıl yöneteceğinizi ve sonuçta nasıl dağıtacağınızı adım adım inceleyeceğiz.

Temel Paketleme Araçları ve Proje Yapısı

Python paketleme ekosistemi zaman içinde gelişmiş ve farklı araçlar ortaya çıkmıştır. Doğru araçları seçmek ve projenizi standartlara uygun bir şekilde yapılandırmak, başarılı bir paketleme sürecinin temelidir.

setup.py vs. pyproject.toml

Geleneksel olarak, Python projeleri setuptools kütüphanesini kullanarak paketleme bilgilerini bir setup.py dosyası içinde tanımlardı. Bu dosya, paketin adını, sürümünü, bağımlılıklarını ve diğer meta verilerini içeren bir Python betiğidir. Ancak son yıllarda, Python paketleme standardı (PEP 517 ve PEP 518) ile birlikte pyproject.toml dosyası ön plana çıkmıştır.

  • setup.py: Esnektir, karmaşık yapılandırmalar için Python kodunun gücünü kullanır. Ancak, paketin kendisi kurulmadan önce bazı bağımlılıkların (örneğin setuptools‘un kendisi) karşılanması gerektiğinde sorunlar yaratabilir.
  • pyproject.toml: Bildirimsel (declarative) bir yaklaşıma sahiptir ve TOML formatını kullanır. Projenin derleme araçlarını (build backend) açıkça belirtir ve bu sayede paketin derlenmesi için gereken bağımlılıkların daha erken ve güvenli bir şekilde yönetilmesini sağlar. Modern Python paketleme araçları (Poetry, Flit ve hatta setuptools‘un yeni versiyonları) pyproject.toml dosyasını tercih etmektedir. Yeni bir projeye başlıyorsanız, pyproject.toml kullanmak daha iyi bir seçimdir.

Tipik Bir Python Proje Yapısı

İyi yapılandırılmış bir proje, paketin anlaşılmasını, bakımını ve dağıtımını kolaylaştırır. İşte tipik bir Python paketinin önerilen dizin yapısı:


my_package_name/
├── my_package_name/
│   ├── __init__.py
│   ├── module1.py
│   └── subpackage/
│       └── __init__.py
│       └── module2.py
├── tests/
│   ├── test_module1.py
│   └── test_module2.py
├── README.md
├── LICENSE
├── pyproject.toml  # Veya setup.py
├── requirements.txt # Geliştirme bağımlılıkları için
└── .gitignore
  
  • my_package_name/ (ana dizin): Projenin kök dizini.
  • my_package_name/ (iç dizin): Gerçek Python paket kodunuzu içeren dizin. Bu dizin adı, paketin pip install ile kurulduğunda import edilecek adı olacaktır (örneğin, import my_package_name).
  • __init__.py: Bir dizinin bir Python paketi olduğunu belirtir. Ayrıca paket seviyesinde değişkenleri veya fonksiyonları tanımlamak için kullanılabilir.
  • moduleX.py: Paketinizi oluşturan Python modülleri.
  • tests/: Projenizin testlerini içeren dizin.
  • README.md: Projenizin açıklaması, kurulum talimatları ve kullanım örnekleri gibi bilgileri içeren Markdown dosyası.
  • LICENSE: Projenizin lisansını belirten dosya (örn. MIT, Apache 2.0).
  • pyproject.toml (veya setup.py): Paketleme meta verilerini ve yapılandırmasını içerir.
  • requirements.txt: Projenin geliştirme veya belirli bir dağıtım ortamı için tüm bağımlılıklarını ve sürümlerini listeleyen dosya.

Paket Oluşturma ve Bağımlılık Yönetimi

Proje yapımızı oluşturduktan sonra, paketin nasıl oluşturulacağını ve bağımlılıkların nasıl yönetileceğini öğrenelim.

setuptools ile Paketleme (setup.py örneği)

Eğer hala setup.py kullanmayı tercih ediyorsanız veya mevcut bir projeyi güncellemeniz gerekiyorsa, işte temel bir setup.py örneği:


from setuptools import setup, find_packages

setup(
    name='my_package_name',
    version='0.1.0',
    author='Adınız Soyadınız',
    author_email='email@example.com',
    description='Bu, harika Python paketimin kısa bir açıklamasıdır.',
    long_description=open('README.md').read(),
    long_description_content_type='text/markdown',
    url='https://github.com/kullaniciadi/my_package_name',
    packages=find_packages(), # my_package_name/ dizinini otomatik bulur
    classifiers=[
        'Programming Language :: Python :: 3',
        'License :: OSI Approved :: MIT License',
        'Operating System :: OS Independent',
    ],
    python_requires='>=3.6', # Python 3.6 ve üzeri gereksinimi
    install_requires=[ # Paketinizin çalışması için gereken bağımlılıklar
        'requests>=2.20.0',
        'beautifulsoup4==4.9.3',
    ],
    # extras_require={ # İsteğe bağlı bağımlılıklar
    #     'dev': [
    #         'pytest',
    #         'flake8',
    #     ],
    #     'docs': [
    #         'sphinx',
    #         'sphinx_rtd_theme',
    #     ],
    # },
    # entry_points={ # Komut satırı araçları için
    #     'console_scripts': [
    #         'mycommand=my_package_name.cli:main',
    #     ],
    # },
)
  

Bu setup.py dosyasını kullanarak paketinizi oluşturmak için:


python setup.py sdist bdist_wheel
  

Bu komut, dist/ dizini altında bir kaynak dağıtım (.tar.gz) ve bir ikili dağıtım (.whl – wheel) dosyası oluşturacaktır.

Bağımlılıkları Belirtme: install_requires ve requirements.txt

Python projelerinde bağımlılıkları belirtmenin iki ana yolu vardır:

  • install_requires (setup.py veya pyproject.toml içinde): Bu kısım, paketin temel işlevselliği için mutlaka gerekli olan bağımlılıkları ve bunların minimum/maksimum sürümlerini belirtir. Bir kullanıcı paketinizi kurduğunda (pip install my_package_name), bu bağımlılıklar otomatik olarak yüklenir. Sürüm kısıtlamaları önemlidir (örneğin, requests>=2.20.0).
  • requirements.txt: Bu dosya genellikle bir uygulamanın veya geliştirme ortamının tam ve sabitlenmiş bağımlılık listesini içerir. Genellikle üretim ortamında belirli bir uygulamanın kesinlikle aynı bağımlılıklarla çalışmasını sağlamak için kullanılır. pip freeze > requirements.txt komutu ile mevcut ortamdaki bağımlılıklar bu dosyaya yazılabilir. Kurulumu ise pip install -r requirements.txt şeklindedir.

Fark: install_requires paketin kendisinin bağımlılıklarını tanımlarken, requirements.txt belirli bir projenin veya ortamın tam bağımlılık setini tanımlar. Bir kütüphane geliştiriyorsanız install_requires kullanmalısınız. Bir uygulama geliştiriyorsanız hem install_requires (eğer uygulamanız da bir paket gibi düşünülüyorsa) hem de requirements.txt kullanabilirsiniz.

Sanal Ortamlar (Virtual Environments)

Farklı Python projeleri genellikle farklı kütüphane sürümlerine ihtiyaç duyar. Bu durum, “bağımlılık çakışmaları”na yol açabilir. Sanal ortamlar, her proje için izole edilmiş Python ortamları oluşturarak bu çakışmaları önler. Her sanal ortamın kendi Python yorumlayıcısı, pip aracı ve bağımlılıkları vardır.

Python 3.3 ve üzeri sürümlerde, venv modülü yerleşik olarak gelir ve sanal ortam oluşturmak için en yaygın yoldur.


Proje dizininde sanal ortam oluşturma

python3 -m venv .venv

Sanal ortamı etkinleştirme (Linux/macOS)

source .venv/bin/activate

Sanal ortamı etkinleştirme (Windows - PowerShell)

.venv\Scripts\Activate.ps1

Sanal ortamı etkinleştirme (Windows - Command Prompt)

.venv\Scripts\activate.bat

Sanal ortam etkinleştirildikten sonra pip ile bağımlılıkları kurma

pip install -r requirements.txt pip install my_package_name # Kendi paketinizi de kurabilirsiniz

Sanal ortamdan çıkış

deactivate

Sanal ortamları kullanmak, geliştirme sürecinizi çok daha düzenli ve sorunsuz hale getirecektir. Her zaman yeni bir projeye başlarken veya mevcut bir projenin üzerinde çalışırken sanal ortam oluşturup etkinleştirmeyi alışkanlık haline getirmelisiniz.

Dağıtım ve Yayınlama

Paketinizi başarılı bir şekilde oluşturduktan sonra, sıra onu diğer geliştiricilerin kullanımına sunmaya gelir. Bunun en yaygın yolu Python Paket Dizini (PyPI) üzerinden yayınlamaktır.

PyPI’a Yükleme

PyPI (Python Package Index), Python topluluğunun merkezi paket deposudur. pip install komutuyla yüklediğiniz tüm kütüphaneler buradan gelir. Paketinizi PyPI’a yüklemek için aşağıdaki adımları izleyin:

  1. Gerekli Araçları Kurun: build paketi dağıtım dosyalarını (.tar.gz ve .whl) oluşturmak için, twine ise bu dosyaları PyPI’a güvenli bir şekilde yüklemek için kullanılır.
  2. 
    pip install build twine
        
  3. Paket Dosyalarını Oluşturun: Projenizin ana dizininde (setup.py veya pyproject.toml dosyasının bulunduğu yer) aşağıdaki komutu çalıştırın. Bu komut, dist/ dizini altında dağıtım dosyalarını oluşturacaktır.
  4. 
    python -m build
        
  5. TestPyPI’a Yükleyin (Önerilen): Paketinizi doğrudan PyPI’a yüklemeden önce, her şeyin yolunda gittiğinden emin olmak için TestPyPI‘a yüklemeniz şiddetle tavsiye edilir. TestPyPI, gerçek PyPI’ın bir kopyasıdır ve denemeleriniz için kullanabilirsiniz.
  6. 
    twine upload --repository testpypi dist/*
        

    Bu komutu çalıştırdığınızda, TestPyPI kullanıcı adınızı ve şifrenizi (veya API token’ınızı) isteyecektir. TestPyPI’da bir hesap oluşturmanız gerekmektedir.

  7. PyPI’a Yükleyin: TestPyPI’da paketinizi başarıyla yükleyip test ettikten sonra, gerçek PyPI’a yüklemeye hazırsınız demektir.
  8. 
    twine upload dist/*
        

    Yine, PyPI kullanıcı adınızı ve şifrenizi (veya API token’ınızı) girmeniz istenecektir. PyPI’da bir hesap oluşturmayı unutmayın.

Yükleme tamamlandıktan sonra, paketinize pip install my_package_name komutuyla erişilebilir olacaktır.

Diğer Dağıtım Yöntemleri (wheel, sdist)

  • Source Distribution (sdist): .tar.gz uzantılı dosyalardır. Paketin kaynak kodunu, setup.py dosyasını ve diğer meta verileri içerir. Kullanıcı kurduğunda, paketi kendi sisteminde derler. Bu, farklı platformlarda çalışabilir ancak kurulum süresi daha uzun olabilir ve derleme bağımlılıkları gerektirebilir.
  • Wheel (bdist_wheel): .whl uzantılı dosyalardır ve ikili dağıtım formatıdır. Önceden derlenmiş Python paketleridir. Kurulumu çok daha hızlıdır çünkü derleme adımına gerek kalmaz. Platforma özgü olabilirler (örneğin, my_package-1.0-cp39-cp39-linux_x86_64.whl). Çoğu durumda, hem sdist hem de wheel dosyalarını PyPI’a yüklemek en iyi yaklaşımdır.

Uygulama Paketleme (Executable)

Bazen bir Python uygulamasını, Python kurulu olmayan son kullanıcılara dağıtmak isteyebilirsiniz. Bu durumda, uygulamanızı bağımsız bir çalıştırılabilir dosya (.exe, .app, .deb) haline getirmeniz gerekir. Bu işlem, uygulamanızın Python yorumlayıcısını ve tüm bağımlılıklarını tek bir pakette birleştirir.

Bu amaçla kullanılan popüler araçlar şunlardır:

  • PyInstaller: En yaygın kullanılan araçlardan biridir. Python betiklerinizi Windows, macOS ve Linux üzerinde bağımsız çalıştırılabilir dosyalara dönüştürür.
  • cx_Freeze: PyInstaller’a benzer bir işlevsellik sunar.
  • Nuitka: Python kodunu C koduna derleyerek daha performanslı çalıştırılabilir dosyalar oluşturur.

PyInstaller ile örnek kullanım:


PyInstaller'ı kurun

pip install pyinstaller

Uygulama betiğinizi (örneğin, my_app.py) tek bir dosyaya derleyin

pyinstaller --onefile my_app.py

GUI uygulaması için konsol penceresini gizleyin

pyinstaller --onefile --windowed my_app.py

Bu komutlar, projenizin kök dizininde dist/ adında bir dizin oluşturacak ve içinde çalıştırılabilir dosyanızı barındıracaktır.

Sonuç ve Sıkça Sorulan Sorular (SSS)

Python uygulamalarını ve kütüphanelerini paketlemek ve dağıtmak, yazılım geliştirme sürecinin ayrılmaz bir parçasıdır. Bu rehberde ele aldığımız teknikler sayesinde, projelerinizi daha düzenli, yeniden kullanılabilir ve geniş kitlelere ulaştırılabilir hale getirebilirsiniz. Doğru proje yapısı, bağımlılık yönetimi ve PyPI gibi platformları etkin kullanmak, hem sizin hem de projenizin kullanıcıları için büyük kolaylıklar sağlayacaktır. Modern araçları ve en iyi uygulamaları takip etmek, Python ekosistemindeki yerinizi sağlamlaştırmanıza yardımcı olacaktır.

Sıkça Sorulan Sorular (SSS)

Soru 1: Yeni bir projede setup.py mi yoksa pyproject.toml mi kullanmalıyım?
Cevap: Yeni projeler için kesinlikle pyproject.toml kullanmanız önerilir. Bu, modern Python paketleme standartlarına (PEP 517/518) uygun daha deklaratif ve geleceğe dönük bir yaklaşımdır. Poetry, Flit gibi araçlar veya setuptools‘un yeni versiyonları pyproject.toml‘u destekler.
Soru 2: requirements.txt ile install_requires arasındaki temel fark nedir?
Cevap: install_requires (setup.py veya pyproject.toml içinde) paketin kendisinin çalışması için gereken minimum bağımlılıkları ve sürüm kısıtlamalarını belirtir. Bir kütüphane veya paket dağıtırken kullanılır. requirements.txt ise belirli bir uygulamanın veya geliştirme ortamının tam ve sabitlenmiş bağımlılık listesini içerir. Genellikle bir uygulamanın dağıtımı veya geliştirme ortamının kurulumu için kullanılır ve bağımlılıkların tam sürüm numaralarını içerir.
Soru 3: Sanal ortam kullanmak neden bu kadar önemli?
Cevap: Sanal ortamlar, her Python projesi için izole edilmiş bir geliştirme ortamı sağlar. Bu, farklı projelerin farklı kütüphane sürümlerine ihtiyaç duyması durumunda ortaya çıkabilecek “bağımlılık çakışmalarını” önler. Projeleriniz arasında temiz bir ayrım yapar ve her projenin kendi bağımlılık setini yönetmesini kolaylaştırır, bu da geliştirme sürecini çok daha güvenilir ve tahmin edilebilir hale getirir.
Soru 4: Uygulamamı Python kurulu olmayan kullanıcılara nasıl dağıtabilirim?
Cevap: Uygulamanızı bağımsız bir çalıştırılabilir dosyaya (örneğin, Windows’ta .exe, macOS’ta .app) dönüştürmek için PyInstaller, cx_Freeze veya Nuitka gibi araçları kullanabilirsiniz. Bu araçlar, Python yorumlayıcısını ve uygulamanızın tüm bağımlılıklarını tek bir pakette birleştirerek son kullanıcının sisteminde Python kurulu olmasa bile uygulamanızın çalışmasını sağlar.
Soru 5: Paketimi PyPI’a yüklemeden önce test edebilir miyim?
Cevap: Evet, kesinlikle! PyPI’ın bir test sürümü olan TestPyPI (test.pypi.org) mevcuttur. Paketinizi gerçek PyPI’a yüklemeden önce burada denemeler yapabilir, kurulumunu test edebilir ve her şeyin doğru çalıştığından emin olabilirsiniz. Yükleme için twine upload --repository testpypi dist/* komutunu kullanmanız yeterlidir.

Yorumlar
İçeriği beğendiniz mi? Bir tartışma başlatın veya görüşlerinizi paylaşın.
Yorum Yaz

Bir yanıt yazın

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

Gönder

E-posta Bülteni
Yazılım Topluluğuna Katılın
En son güncellemeleri, yaratıcı ipuçlarını ve özel kaynakları doğrudan e-posta kutunuza alın. Tasarım ve inovasyonun geleceğini birlikte keşfedelim.
Mobil sürümden çık