- Küçük API test betiklerinde bile bağımlılıklar yüzünden çalışma ortamını eşleştirmek gerekir; uv çalıştırma shebang’i kullanıldığında kurulum adımları olmadan doğrudan çalıştırılabilir bir biçim elde edilebilir
- Örnek
jam_users.py, Go API’sinin /users endpoint’ini test etmek için httpx, IPython ve loguru ile kullanıcıları silip oluşturduktan sonra REPL’e girer
- Geleneksel yöntemde paketleri sistem Python’una global olarak kurmak ya da sanal ortamı elle hazırlamak gerektiğinden, betiği paylaşmak ve yeniden çalıştırmak zahmetlidir
# /// script başlığında dependencies = ["ipython", "httpx", "loguru"] tanımlanıp uv run jam_users.py çalıştırıldığında uv, izole ortamı ve bağımlılık kurulumunu yönetir
#!/usr/bin/env -S uv run --script shebang’i ve çalıştırma izni eklendiğinde, Unix sistemlerde yalnızca uv kurulu olarak ./jam_users.py gibi çalıştırılabilir
Bağımlılıkları betiğin içinde tanımlama
- Örnek
jam_users.py, yerel API http://localhost:4000/v1/users üzerinde test kullanıcı verilerini hazırlar
- httpx ile API istekleri gönderir
- IPython REPL’ine girerek yanıtları inceler ve teste devam eder
loguru ile silme ve oluşturma logları bırakır
- Temel betik akışı, kullanıcı listesini sıfırladıktan sonra test verilerini yeniden doldurur
GET /v1/users ile mevcut kullanıcı listesini alır
- Her kullanıcı için
DELETE /v1/users/{id} çağrısı yapar
- Hazırlanan kullanıcı listesini JSON olarak
POST /v1/users’a gönderir
- Ardından
IPython.embed() ile REPL’i açar
python jam_users.py ile çalıştırmak için httpx, IPython ve loguru’nun çalışma ortamında zaten kurulu olması gerekir
- Sistem Python’una global kurulum yapmak veya ayrı bir sanal ortam oluşturmak da mümkündür, ancak ikisi de çalıştırmadan önce hazırlık gerektirir
- Global kurulum, sistem Python’unu paketlerle karmaşık hale getirebilir
- Sanal ortam yöntemi; oluşturma, etkinleştirme, kurulum ve çalıştırma süreçlerini elle yönetmeyi gerektirir
- Her iki yöntemde de gerekli paketlerle uyumlu bir sistem Python’u bulunmalıdır
uv ile doğrudan çalıştırılabilir betik oluşturma
- uv’nin
# /// script etiketini betiğin üst kısmına koyarsanız dosya içinde bağımlılıkları tanımlayabilirsiniz
# /// script
# dependencies = ["ipython", "httpx", "loguru"]
# ///
- Bu başlık varsa
uv run jam_users.py ile çalıştırılabilir
- uv, betik için izole bir sanal ortam oluşturur
- Gerekli bağımlılıkları indirir ve kurar
- Betiği ilgili sanal ortam bağlamında çalıştırır
- Normal Python shebang’i olan
#!/usr/bin/env python, Python # /// script yorumlarını yok saydığı için uv’nin betik başlığından yararlanamaz
- Shebang’e uv çağrısını doğrudan koyarsanız betiği çalıştırılabilir dosya gibi ele alabilirsiniz
#!/usr/bin/env -S uv run --script
# /// script
# dependencies = ["ipython", "httpx", "loguru"]
# ///
env’in -S bayrağı, ardından gelen dizgenin ayrı argümanlara bölünerek env’e iletilmesini sağlar
chmod +x jam_users.py ile çalıştırma izni verdikten sonra şu şekilde doğrudan çalıştırılabilir
./jam_users.py
- Bu yöntem, Unix sistemde uv kuruluysa ayrı bir bağımlılık kurulumu veya sanal ortam yönetimi olmadan betiğin çalıştırılmasını sağlar
- Karmaşık Python betiklerini başka kullanıcılara iletirken, çalıştırma öncesi sistem hazırlık adımlarını uzun uzun anlatma yükünü azaltabilir
1 yorum
Hacker News yorumları
Özellikle uv özelinde değil, genel olarak yorumlarla kod yürütmesini kontrol etme yaklaşımı rahatsız edici
Linter yönergeleri ya da geliştirici notları için yorum kullanmak sorun değil, ama ayar veya çalıştırmayla ilgili veriler söz konusuysa
UV_ENV = { "dependencies": { "requests": "2.32.3", "pandas": "2.2.3" } }gibi bir biçim çok daha iyi olurduBu yaklaşım geçerli Python sözdizimidir, rastgele yorum ayrıştırması yerine standart veri yapıları kullandığı için üretmesi ve doğrulaması kolaydır ve her şeyden önemlisi tüm yorumlar kaldırılsa bile kod aynı şekilde çalışmalıdır ilkesine uyar
Önerdiğiniz yaklaşım da çalışma zamanında hiçbir şey yapmayan, yalnızca statik analizle ayrıştırılan bir sihirli sabit; bu yüzden uv okumasa bile başka bir araç bunu kullanılmayan kod sanıp silebilir
Bunun yerine
import uvsonrasındauv.exec(dependencies=["clown"], python=">=3.10")gibi bir çağrıyla uv'ye ne yapacağını doğrudan söylemek mümkün olabilirİlk çalıştırma, bu varsayımsal
uvpaketini bulabilen herhangi bir Python çalışma zamanında yapılır;uvpaketi sanal ortamı ve Python çalışma zamanını hazırladıktan sonra ortam değişkeni gibi bir bayrak ekleyipre-exec(3)yaparİkinci çalışma zamanında ise bayrağı algılayan
uv.exechiçbir şey yapmazhttps://peps.python.org/pep-0723/
Ayrıca shebang satırının kendisi de aslında yorum olarak çalışır
Sadece 45 yıldır o kadar yerleşmiştir ki insanlar onun bir shell yorumu olduğunu pek fark etmez
Aynı bağımlılıklar kurulduysa kod aynı şekilde çalışır
Bu, kodun kendi anlamını değiştirmekten çok kodun çalıştığı ortamı değiştiriyor; bu açıdan shell script’in başındaki
#!/bin/bashyorumundan farklı değilYine de uv muhtemelen bağımlılıkları anlamak için kodu çalıştırmak istemez; dolayısıyla bu, Python sözdiziminin çok sınırlı bir alt kümesi olmak zorunda kalırdı
Zaten böyle bir şeye ihtiyaç duyulması, dilin zayıf yönünü gösteriyor
importifadesinin kendisi bağımlılıklarla ilgili tüm bilgiyi aktarabilmeliydiSon birkaç ayda bu konu HN'de çok sık gündeme geldi; yakın tarihli örnekler şunlar:
https://news.ycombinator.com/item?id=43500124
https://news.ycombinator.com/item?id=42463975
uv'yi seviyorum ama self-contained ifadesine iki açıdan katılmak zor
Birincisi, script’i çalıştırmak için uv'nin zaten kurulu olması gerekiyor
Bir shell script ile uv'nin kurulu olup olmadığını kontrol edip yoksa curlpipe ile kurdurabilirsiniz, ama bu hem ciddi miktarda boilerplate ekler hem de curlpipe yaklaşımının kendisi pek iyi değildir
İkincisi, home dizininin bir yerinde otomatik olarak sanal ortam oluşturulması gerçekten self-contained sayılmaz
Tek seferlik çalıştırıp script’i silseniz bile o sanal ortam kalır ve yer kaplamaya devam eder; uv belgelerinde de bu tür geçici sanal ortamların otomatik temizlendiğine dair bir garanti bulamadım
curl | shkullanmak zorunda kalınması yönündeki şikâyet yerindeYine de paket yöneticileri uv'yi depolarına almaya başladıkça bu daha az sorun olacaktır
Örneğin uv zaten Alpine Linux ve Homebrew'de mevcut: https://repology.org/project/uv/versions
Ayrıca satır içi script metadata Python standardının bir parçası
Sistemde uv yoksa ve paketlenmemişse ama script için uygun bir Python sürümü varsa, pipx ile çalıştırılabilir: https://pipx.pypa.io/stable/examples/#pipx-run-examples
pipx çok daha yaygın şekilde paketlenmiş durumda: https://repology.org/project/pipx/versions
Rastgele bir geliştirici makinesinde Docker, uv'den daha yaygın olabilir; üstelik orijinal yazı da bir şirket projesinden söz ettiği için kulağa makul geldi
Ancak şu anda hiç önbellekleme yapmadığı için her çalıştırmada indirme olması tuhaf duruyor; muhtemelen volume ile düzeltilebilir
Şöyle bir şey: https://hugojosefson.github.io/docker-shebang/#python
Yine de çalışma sırasında internetten kaynağı belirsiz bir şey indiriliyorsa buna self-contained demek zor; gerçekten tam self-contained olana en yakın şey AppImage gibi duruyor
py2exe gibi araçlar kullanılarak self-contained bir “Python script'i” yapılabilir
Geliştirici tarafında pek çok sorun çıkarır ama kullanıcı tarafındaki sorunları en aza indirir
Nix ile de aynı yaklaşım kullanılıyor ve shebang satırı şöyle görünüyor
#! nix-shell -i python3 -p "python312.withPackages (pkgs: [ pkgs.boto3 pkgs.click ])"Bunu yapınca sistemde gerekli olan tek şey Nix oluyor; Python’ın kurulu olması bile gerekmiyor
nixpkgsiçinde paketlenmiş değil; bu yüzden uv kadar genel amaçlı bir yaklaşım sayılmazEn bariz örnek, tüm bağımlılıkların belirtildiği bash; ayrıca Nix shebang ile hızlı tek dosyalık Rust betikleri de yaptım
https://nixos.wiki/wiki/Nix-shell_shebang
nix-shellyerine flake tabanlınix shellkomutuyla aynı işi nasıl yapabileceğimi merak ediyorumDiğer yorumlarda da olduğu gibi, “self-contained” iddiası
uvkurulu olmasına dayanıyorGerçekten self-contained bir Python betiği istiyorsanız Nuitka derleyicisine bakmaya değer
Bunu production’daki gRPC servislerinde sorunsuz kullanıyoruz ve tek yapmanız gereken
nuitka --onefile run.pyçalıştırmakBir derleyici olduğu için ortaya çıkan ikili dosya, PyInstaller ile paketlenmiş özgün Python programından daha hızlı bile olabiliyor
Yazarın GitHub sayfasında “Hayat misyonum, mümkün olan en iyi Python Compiler’ı yapmak için ölünceye kadar uğraşmak” yazıyor
https://nuitka.net/
https://github.com/kayhayen
Bu deseni gerçekten seviyorum ama ne yazık ki LSP ile düzgün çalıştıramadım
Helix’te pyright kullanıyorum; editörü
uv run hx script.pyile başlatsam da işe yaramıyoruv run --with whatever-it-is-i-need hx script.pygibi yapabiliyorum ama giderek daha fazla tekrar oluşuyoruvebetiği kullanıyorum$ cat ~/.local/bin/uve#!/bin/bashtemp=$(mktemp)uv export --script $1 --no-hashes > $tempuv run --with-requirements $temp vim $1unlink $tempUmarım editör yakında
uv python find --scriptdesteği eklerOldukça faydalı görünüyor
Python tabanlı projeleri uzun vadeli dağıtırken uv’nin daha güvenli bir tercih olup olmadığını merak ediyorum
Yaklaşık 5 yıl önce bağımlılık yönetimi için Anaconda kullanmıştım; sonra kurallar değişti ve 200’den fazla çalışanı olan kurumsal müşteriler artık Anaconda’yı ücretsiz kullanamaz, ticari lisans ödemek zorunda kalır oldu; bu rug pull olayını hatırlatıyor
Geliştirmeyi durdurabilirler ya da gelecekteki çalışmayı başka lisanslı bir fork’a taşıyabilirler, ama geçmiş lisansları geriye dönük olarak değiştiremezler; yani şu anda var olan şeyin açık kaynak olduğu garanti
Gerçekten endişeleniyorsanız bir fork oluşturup senkron tutabilirsiniz
Pratikte bu, neredeyse tüm diğer OSS projeleri için de aynı şekilde geçerli; o yüzden çok dert etmezdim
Bildiğim kadarıyla conda hiçbir zaman açık kaynak olmadı ve ikili dosya dağıtıyordu
https://github.com/astral-sh/uv?tab=readme-ov-file#license
conda-forgepaketleri hâlâ ücretsiz kullanılabiliyoruv zaten sadece PyPI kullanıyor; bir sorun çıkarsa uv’den pip veya Poetry gibi başka bir araca geçersiniz ve paketleri yine aynı yerden almaya devam edersiniz
Böyle bir sahip de eninde sonunda akla gelebilecek en kötü zengine satılır
uv’nin katkı rehberine ve issue’larına göz attım ama CLA görmedim; PyTorch’un katkı rehberinin en üstünde ise CLA vardı
Yine de Anaconda’nın son FOSS sürümü için bir topluluk fork’u olmalıydı
Redis’te böyle oldu ve Redis de CLA kullanıyor: https://github.com/redis/redis/blob/unstable/CONTRIBUTING.md#redis-software-grant-and-contributor-license-agreement
Asla CLA imzalamamalısınız
Bana kalırsa sadece copyleft projelere katkı vermek daha iyi
Bedava çalışmak için fazla para kazanıyoruz
Küçük yardımcı araçlar için container kullanmak yerine iyi bir paketleme alternatifi gibi görünüyor
Şimdi bütün ekip arkadaşlarımı uv kurmaları için ikna etmem gerekecek
Ruby tarafındaki bundler/inline’a benziyor
Python’da da benzer bir şeyin gelmesine sevindim ve pratikte gerçekten çok kullanışlı
https://bundler.io/guides/bundler_in_a_single_file_ruby_script.html
Bunu Windows'ta çalıştıran biri olup olmadığını merak ediyorum
Üzerinde çalıştığım oyun modu aracı için bu hileyi kullanmak istedim ama shebang hilesini çalıştıramadım
$> uv init --script .py$> uv add --script .py ...$> uv add --script .py --dev ...$> uv run .pyUmarım yardımcı olur
Kaynak: https://docs.astral.sh/uv/guides/scripts/
.pydosyalarıyla ilişkilendirirpy launcher shebang satırını destekler
Birkaç gün önce paylaşılan aynı konudaki blog yazısında da bundan bahsediliyordu; oraya göre
-Sçıkarılmalı: https://thisdavej.com/share-python-scripts-like-a-pro-uv-and-pep-723-for-easy-deployment/https://news.ycombinator.com/item?id=43500124
Kendim denemedim; onun yerine dosya ilişkilendirmesini değiştirip tüm
.pydosyalarının varsayılan olarakuv runile açılmasını sağladımhttps://docs.python.org/3/using/windows.html#python-launcher-for-windows
https://peps.python.org/pep-0397/
https://pyinstaller.org
https://onor.io/2025/01/more-scripting-with-racket.html
Bu kullanım senaryosu sayesinde uv'yi sevdim ama resmi ve çok faydalı bir PEP'in resmi Python araçları tarafından desteklenmemesi bana Zen of Python'a aykırı geliyor
Benim açımdan bu, Python'ın ilk kez “batteries included” olmadığı andı
Artık sistemimde iki Python bağımlılık yöneticisi var
Python bağımlılık yönetimi hakkında söylenecek çok şey olduğunu biliyorum ama son birkaç yıldır projede sadece
requirements.txtvarsa varsayılanpip+venvile idare ediyordumpyproject.toml'ıntomllibkütüphanesinden önce çıktığını hatırlıyorumBu yüzden birkaç sürüm boyunca modülleri Python'ın varsayılan olarak okuyamadığı bir dilde belirtmek gerekiyordu
Bu, kullanılmayan meta veri içeren varsayılan bir yöntem olmasından daha kötü bir durum
Zaten bu yüzden meta veri; aksi halde sadece Python sözdizimi olurdu