7 पॉइंट द्वारा GN⁺ 2025-06-25 | 2 टिप्पणियां | WhatsApp पर शेयर करें
  • uv पर स्विच करने से Python dependencies की installation speed, pip की तुलना में लगभग 10 गुना तेज हो जाती है, और अलग venv के बिना non-root user के रूप में भी चलाया जा सकता है
  • pyproject.toml आधारित सेटअप में सिर्फ top-level dependencies लिखनी होती हैं; uv अपने आप lock file मैनेज करता है, और dependency tree व सटीक version management के मामले में pip freeze से बेहतर है
  • Dockerfile में uv और uvx binaries कॉपी करना, pyproject.toml/uv.lock फाइलें इस्तेमाल करना, environment variables सेट करना जैसी step-by-step बदलावों की जरूरत होती है
  • uv sync/add/remove, uv:outdated जैसे commands से dependencies जोड़ना, हटाना, अपडेट करना और package के latest versions देखना आसान हो जाता है
  • lock file को नियमित रूप से मैनेज करना और dependencies अपडेट करना आसान होने से collaboration और deployment environments में consistency बनाए रखने का फायदा मिलता है

10 गुना तेज dependency installation, venv के बिना, non-root environment सेटअप

  • uv, pip की तुलना में Python projects में dependency installation speed को काफी बेहतर बनाने वाला tool है
  • uv अपनाने से Flask/Django जैसे अलग-अलग projects में, मौजूदा pip setup की तुलना में लगभग 10 गुना तेज installation speed मिल सकती है
  • अलग virtual environment (venv) के बिना भी container के अंदर non-root user के रूप में सुरक्षित तरीके से run किया जा सकता है

pyproject.toml vs requirements.txt

  • मौजूदा requirements.txt की जगह pyproject.toml फाइल में सिर्फ top-level dependencies लिखने पर uv अपने आप uv.lock फाइल बना देता है
    • pyproject.toml में [project] dependencies एंट्री जोड़ें
    • मौजूदा requirements.txt हटाएँ
  • uv की lock file, pip freeze के output जैसी लगती है, लेकिन इसमें सटीक dependency tree और version information शामिल होती है

Dockerfile कॉन्फ़िगरेशन में बदलाव

  • uv और uvx binaries को container में कॉपी करके इस्तेमाल किया जाता है (static compiled Rust binaries का उपयोग)
  • मौजूदा requirements*.txt की जगह pyproject.toml, uv.lock* फाइलें कॉपी करें
  • environment variables जोड़ें:
    • UV_COMPILE_BYTECODE=1: build stage में पहले से bytecode compile करना
    • UV_PROJECT_ENVIRONMENT="/home/python/.local": अलग venv बनाए बिना एक तय path पर packages install करना
  • dependency installation command भी मौजूदा pip3-install की जगह uv-install में बदलती है
    • उदाहरण: RUN chmod 0755 bin/* && bin/uv-install

dependency जोड़ना, हटाना, अपडेट करना आदि

  • अलग run script के जरिए container के अंदर uv commands चला सकते हैं
    • ./run deps:install: image build के बाद lock file को host पर export करते हुए install करना
    • ./run deps:install --no-build: build के बिना सिर्फ lock file अपडेट करना
    • ./run uv add mypackage --no-sync: सिर्फ pyproject.toml और lock file अपडेट करना, actual install बाद में चलाना
    • ./run uv remove mypackage --no-sync: package हटाना
    • ./run uv:outdated: मौजूदा dependencies के latest versions देखना

वीडियो और hands-on गाइड उपलब्ध

  • uv अपनाने, pyproject.toml लिखने, Dockerfile बदलने, lock/sync commands, dependencies जोड़ने/हटाने, latest versions देखने आदि के लिए वास्तविक demo और git diff examples दिए गए हैं
  • Flask और Django, दोनों projects के migration diff भी संदर्भ के लिए उपलब्ध हैं

2 टिप्पणियां

 
yangeok 2025-06-26

वैसे भी मैं poetry से डिप्लॉय किए जा रहे सेटअप को माइग्रेट करने की सोच रहा था, और यह स्थिर और सरल लग रहा है ^^

 
GN⁺ 2025-06-25
Hacker News राय
  • यह ध्यान देने की ज़रूरत है कि uv ऐसा workflow सपोर्ट करता है जो pyenv, virtualenv और pip को सीधे replace कर सकता है। यह lockfile या pyproject.toml से मजबूर किया गया तरीका नहीं है। uv python pin <version> कमांड से मौजूदा directory में .python-version फ़ाइल बनाई जा सकती है, uv virtualenv से pyenv की तरह उस version का Python डाउनलोड करके .venv virtual environment बनाया जा सकता है, uv pip install -r requirements.txt से requirements.txt के packages install किए जा सकते हैं, और uv run <command> से .env फ़ाइल के environment variables सहित कमांड चलाया जा सकता है। बस environment variable precedence की समस्या से सावधान रहना चाहिए (संबंधित issue)

    • uv की flexibility वाकई चौंकाने वाली है। pip में 10 मिनट लगने वाला काम uv में 20~30 सेकंड में हो जाने का अनुभव हुआ
    • मैंने uv इस्तेमाल करना इसी वजह से शुरू किया। बेहद सुविधाजनक है। हालांकि कभी-कभी uv pip धीमा होता है और वजह समझ नहीं आती, शायद हमारी कंपनी के network environment की समस्या हो
    • मेरी समझ से Python version की जानकारी pyproject.toml में भी सेव होती है, तो क्या .python-version फ़ाइल सच में ज़रूरी है, यह जिज्ञासा है
  • # हमेशा नवीनतम lock file सुनिश्चित करने वाली स्क्रिप्ट
    if ! test -f uv.lock || ! uv lock --check 2>/dev/null; then
      uv lock
    fi
    

    यह तरीका lock file के मौजूद होने के अर्थ को फीका कर देता है। अगर फ़ाइल नहीं है या invalid है, तो इसका मतलब है कि lock file में गंभीर समस्या है और ऐसे में बेहतर यही है कि उस प्रोजेक्ट से परिचित व्यक्ति सीधे इसका समाधान करे। वरना lock file रखने का कोई कारण नहीं बचता। CI में lock file अपने-आप replace हो जाए तो उलझन पैदा हो सकती है

    • (लेखक का जवाब) अगर lock file invalid है, तो यह चुपचाप आगे बढ़कर नई फ़ाइल नहीं बनाता। uv lock friendly message के साथ fail होता है और shell script का errexit तुरंत execution रोक देता है। uv lock --check में error redirect करने का मकसद वही error दो बार print होने से रोकना है। अगर lock फ़ाइल को जानबूझकर गलत बनाकर script चलाई जाए, तो specific error message के साथ build रुक जाता है। script को if-else में बदलकर और स्पष्ट कर दिया गया है। lock फ़ाइल न हो तो उसे नया बनाना सही flow है। फिर उसे generate करके commit किया जा सकता है
    • uv sync --locked option यह हिस्सा cover करता है। lock file न हो या पुरानी हो तो यह साफ़ तौर पर fail करता है। हमेशा --locked option के साथ build करने की सलाह है
    • Python ecosystem में अक्सर lock file को version control में नहीं डाला जाता, और installation process के "अजीब चरण" की तरह treat किया जाता है
    • इस तरीके में गंभीर bug है। --frozen flag का मतलब होना चाहिए कि lock file update न हो, लेकिन व्यवहार उल्टा है। lock file न हो या match न करे तो इंसानी दखल ज़रूरी है, इस बात से सहमत हूँ
    • फिर भी अगर lock file नहीं है, तो या तो यह पहली run है, या वैसे भी git upstream से overwrite हो जाएगी। अगर यह टूटी हुई है तो किसी ने install करते समय गलती की है, और इसे फिर से बनाना ही व्यावहारिक रूप से एकमात्र उचित तरीका लगता है। यह rare exception है, लेकिन simple handling के लिए पर्याप्त है
  • Python tools का Python के बाहर की भाषा में लिखा जाना मुझे पूरी तरह गलत दिशा लगता है। C पहले से मौजूद है और CPython standardized है, तो बेवजह किसी नई भाषा (जैसे Rust) की ज़रूरत नहीं। Pendulum package में 3.13 support 7 महीने से ज़्यादा देर से आया, और मेरा मानना है कि इसकी वजह Rust native code थी क्योंकि उसे ठीक कर सकने वाले लोग कम थे। अगर यह C में होता तो मैं खुद ठीक कर देता। (संबंधित issue) आदर्श रूप में, अगर Rust जैसी बाहरी भाषा में तेज़ datetime बनाना है, तो उसे FFI के ज़रिए ऐसे रूप में बनाना चाहिए जिसे कई भाषाएँ इस्तेमाल कर सकें। Rust-based तरीका अभी भी खास पसंद नहीं, और Linux community के हिचकिचाने की वजह अब समझ आती है

    • मैं इस नज़रिए का सम्मान करता हूँ, लेकिन uv जैसे tool को Rust में बनाना मुझे अच्छा विचार लगता है। Python management tool अगर Python में लिखा जाए तो "मुर्गी पहले या अंडा पहले" जैसी स्थिति बन जाती है। Python tool चलाने के लिए पहले Python खुद installed होना चाहिए, कौन-सा Python version इस्तेमाल हो रहा है, tool की libraries और असली app के बीच conflict की संभावना, environment variable management, debugging—सब कुछ जटिल हो जाता है। दूसरी ओर Rust आदि से बने binary tools बस download करके चलाए जा सकते हैं; ये सब सोचे बिना तुरंत काम करते हैं। आम तौर पर user को यह फ़र्क नहीं पड़ता कि tool किस भाषा में लिखा गया है
    • मुझे Python पसंद है, लेकिन uv की सादगी और speed की तुलना नहीं। EOL हो चुके server पर नया Python चाहिए हो, या किसी छोटे script के लिए dependencies जल्दी install करनी हों, हर जगह uv सबसे अच्छा है। कुछ बातों से सहमत भी हूँ—पहले pure Python में लिखते हैं, फिर धीरे-धीरे C extension इस्तेमाल करने लगते हैं, और सीमा महसूस होते ही लगभग सब कुछ C में लिखने का मन होने लगता है। C मुश्किल है, इसलिए हाल में Rust में refactor कर रहा हूँ। जब external code internal code से ज़्यादा हो जाए, तो कभी-कभी सब कुछ दूसरी भाषा में बदल देना ही बेहतर होता है
    • अगर आपको सच में लगता है कि tools सिर्फ Python में ही बनने चाहिए, तो धीमे Pylint का इंतज़ार करते समय मैं टहलने चला जाऊँगा
    • कई भाषाओं का support user पर कोई खास बोझ नहीं डालता। tool तेज़ हो और समस्या ठीक से हल करे, वही काफी है। असल में speed काफ़ी बेहतर है। management tools developers के लिए होते हैं, end users के लिए नहीं
    • मेरे लिए यह मायने नहीं रखता कि वह किस भाषा में लिखा गया है, बस काम अच्छे से होना चाहिए। यह सही है कि Python users tool में योगदान दे सकते हैं, लेकिन अगर tool अपना उद्देश्य ठीक से पूरा करता है तो भाषा मायने नहीं रखती। उल्टा, environment problem आने पर Python में बना tool उसी समस्या से खुद भी प्रभावित हो सकता है
  • pip की जगह uv इस्तेमाल करते समय सावधान रहना चाहिए। default रूप से यह pyc files नहीं बनाता, इसलिए service startup धीमा हो सकता है (संदर्भ)

    • container में uv इस्तेमाल करते समय guide docs ज़्यादा मददगार हैं (Docker guide)
  • flask container में uv इस्तेमाल करने पर सिर्फ build time का अंतर ही बहुत बड़ा नहीं होता, installation process भी बहुत predictable हो जाती है। pip के साथ dependency versions बदल जाने वाली परेशानी नहीं रहती। pyproject.toml इस्तेमाल करें, uv lock चलाएँ और काम हो गया। docker में सिर्फ pyproject.toml और uv.lock फ़ाइलें copy (HOT COPY) करके uv sync --frozen --no-install-project चलाने से app code को छोड़े बिना installation layer को cache किया जा सकता है। अगर आपने सिर्फ एक package बदलने पर पूरी layer फिर से rebuild होने का दर्द देखा है, तो समझ आएगा कि यह feature क्यों महत्वपूर्ण है। environment variable UV_PROJECT_ENVIRONMENT=/home/python/.local इस्तेमाल करने पर venv के बिना base image को pre-warm किया जा सकता है, जिससे build sharing और infra cost कम होती है। UV_COMPILE_BYTECODE=1 option से build के समय .pyc files बनाई जा सकती हैं। mutable environment खत्म हो जाता है और reproducibility लागू होती है; अब अगर build fail होता है, तो वजह साफ़ तौर पर lockfile पर आती है

  • 2025 में भी Python packaging और dependency management अब भी अव्यवस्थित है

    • मुझे लगता है कि भ्रम इसलिए बना हुआ है क्योंकि सब लोग uv इस्तेमाल नहीं कर रहे
    • यह सीख है कि भाषा design के शुरुआती दौर से ही ऐसी चीज़ें सही तरह set करनी चाहिए। v2.0 के बाद पर मत टालो, metadata को executable scripts में डालने से पहले कई बार सोचो, और यह भी समझो कि जो तरीका किसी एक भाषा पर फिट बैठता है वह Python के लिए अच्छा हो यह ज़रूरी नहीं
    • मैंने dependency से जुड़ी समस्या कभी झेली ही नहीं। requirements.txt और venv ही काफी हैं
    • dependency management अब भी बिखरा हुआ है, अब इसमें Rust भी जुड़ गया है
  • uv, pip, conda जैसे Python package managers की security तुलना जानने की उत्सुकता है। speed अच्छी बात है, लेकिन package manager की security उससे कहीं ज़्यादा महत्वपूर्ण लगती है

    • uv, pip से ज़्यादा सुरक्षित माना जा सकता है। यह arbitrary code चलाए बिना dependency analyze करता है, default रूप से package hash verify करता है, और typosquatting जैसी कई जोखिमों से बचता है। speed और reproducibility भी बेहतर हैं (तकनीकी परिचय, compatibility docs)
    • लेकिन मूल रूप से हर package manager को unverified third-party code download और execute करना पड़ता है। uv और pip के implementation-level security differences से भी बड़ा जोखिम यह है कि बाहरी code के लिए पहले से कोई policy ही न हो
  • मैं PyPI पर package publish करता हूँ, इसलिए व्यक्तिगत रूप से speed की वजह से uv इस्तेमाल करना चाहता हूँ, लेकिन अगर यह गारंटी न हो कि इसका व्यवहार pip जैसा ही होगा, तो आसानी से switch नहीं कर सकता। अगर users को pip install xxx में error मिले, तो मुझे भी वही environment दोहराकर reproduce और debug करना पड़ता है

    • यह pip के साथ 100% एक जैसा नहीं है। बड़े अंतर compatibility docs में बताए गए हैं। कुछ अंतर standards के अनुसार बदलती प्रक्रिया की वजह से हैं, और कुछ uv के अपने design choices हैं
  • मुझे लगता है कि UV हाल के Python packaging में सबसे सकारात्मक बदलावों में से एक है—बस चलाइए और यह अच्छा परिणाम देता है

  • production environment containers बनाने के लिए uv पर एक शानदार guide भी साझा की गई है (guide देखें)