5 पॉइंट द्वारा GN⁺ 2025-03-31 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • छोटे API टेस्ट स्क्रिप्ट के लिए भी dependencies की वजह से execution environment मिलाना पड़ता है, लेकिन uv execution shebang का उपयोग करने पर इसे बिना installation प्रक्रिया के सीधे चलने योग्य बनाया जा सकता है
  • उदाहरण jam_users.py, Go API के /users endpoint को टेस्ट करने के लिए httpx, IPython, loguru के साथ users को delete और create करने के बाद REPL में प्रवेश करता है
  • पारंपरिक तरीके में system Python पर packages को global install करना पड़ता है या virtual environment अलग से तैयार करना पड़ता है, इसलिए script share करना और दोबारा चलाना असुविधाजनक होता है
  • # /// script header में dependencies = ["ipython", "httpx", "loguru"] घोषित करके uv run jam_users.py चलाने पर uv isolated environment और dependency installation को संभाल लेता है
  • #!/usr/bin/env -S uv run --script shebang और execution permission जोड़ने पर, Unix सिस्टम में सिर्फ uv installed हो तो ./jam_users.py की तरह चलाया जा सकता है

स्क्रिप्ट के अंदर dependencies घोषित करना

  • उदाहरण jam_users.py local API http://localhost:4000/v1/users के लिए test user data तैयार करता है
    • httpx से API requests भेजता है
    • IPython REPL में प्रवेश करके response देखता है और testing जारी रखता है
    • loguru से delete और create logs छोड़ता है
  • बेसिक स्क्रिप्ट का flow user list को reset करने के बाद test data फिर से भरने का है
    • GET /v1/users से मौजूदा user list लाता है
    • हर user के लिए DELETE /v1/users/{id} कॉल करता है
    • तैयार की गई user list को POST /v1/users पर JSON के रूप में भेजता है
    • उसके बाद IPython.embed() से REPL खोलता है
  • python jam_users.py से चलाने के लिए httpx, IPython, loguru execution environment में पहले से installed होने चाहिए
  • system Python पर global install करने या virtual environment अलग बनाने के तरीके भी हैं, लेकिन दोनों में run करने से पहले तैयारी चाहिए
    • global install से system Python package clutter हो सकता है
    • virtual environment वाले तरीके में create, activate, install, run प्रक्रिया को खुद manage करना पड़ता है
    • दोनों तरीकों में compatible system Python और ज़रूरी packages उपलब्ध होने चाहिए

uv से सीधे executable स्क्रिप्ट बनाना

  • uv का # /// script टैग स्क्रिप्ट के ऊपर जोड़ने से file के अंदर dependencies घोषित की जा सकती हैं
# /// script

# dependencies = ["ipython", "httpx", "loguru"]

# ///
  • यह header होने पर uv run jam_users.py से चलाया जा सकता है
    • uv script के लिए isolated virtual environment बनाता है
    • ज़रूरी dependencies को download और install करता है
    • उसी virtual environment context में script चलाता है
  • सामान्य Python shebang #!/usr/bin/env python में Python, # /// script comments को ignore कर देता है, इसलिए uv के script header का उपयोग नहीं हो पाता
  • shebang में सीधे uv call डालने पर script को executable file की तरह treat किया जा सकता है
#!/usr/bin/env -S uv run --script

# /// script

# dependencies = ["ipython", "httpx", "loguru"]

# ///
  • env का -S flag बाद की string को अलग arguments में बाँटकर env को पास करता है
  • chmod +x jam_users.py से execution permission देने के बाद इसे इस तरह सीधे चलाया जा सकता है
./jam_users.py
  • यह तरीका Unix सिस्टम में अगर uv installed है तो अलग dependency installation या virtual environment management के बिना script चलाने देता है
  • जटिल Python scripts को दूसरे users तक पहुँचाते समय, run करने से पहले लंबी system setup प्रक्रिया समझाने का बोझ कम किया जा सकता है

1 टिप्पणियां

 
GN⁺ 2025-03-31
Hacker News की राय
  • UV खुद नहीं, बल्कि कुल मिलाकर comments के जरिए code execution को control करने का तरीका खटकता है
    linter directives या developer notes के लिए comments इस्तेमाल करना ठीक है, लेकिन अगर बात configuration या execution-related data की है, तो UV_ENV = { "dependencies": { "requests": "2.32.3", "pandas": "2.2.3" } } जैसा रूप कहीं बेहतर लगता है
    यह तरीका valid Python syntax है, arbitrary comments parse करने के बजाय standard data structures इस्तेमाल करता है, इसलिए generate और validate करना आसान है, और सबसे बढ़कर यह सिद्धांत बनाए रखता है कि सारे comments हटाने पर भी code उसी तरह चलना चाहिए

    • सहमत हूं, लेकिन मैं इसे एक कदम और आगे ले जाना चाहूंगा
      आपके सुझाए तरीके में भी runtime पर कुछ नहीं करने वाला एक magic constant है, इसलिए वह सिर्फ static analysis से parse होगा, और uv के पढ़ने के बजाय कोई दूसरा tool उसे unused code मानकर हटा भी सकता है
      इसके बजाय import uv के बाद uv.exec(dependencies=["clown"], python=">=3.10") जैसा कुछ लिखकर uv को सीधे बताना चाहिए कि क्या करना है
      पहली execution किसी भी ऐसे Python runtime में हो जो इस काल्पनिक uv package को ढूंढ सके, और फिर uv package virtual environment और Python runtime तैयार करने के बाद environment variable जैसे flag के साथ re-exec(3) कर दे
      दूसरे runtime में flag detect करने पर uv.exec कुछ भी न करे, बस इतना काफी होगा
    • यह uv की बनाई हुई चीज नहीं है, बल्कि दूसरे tools की तरह standard PEP 723 का इस्तेमाल है
      https://peps.python.org/pep-0723/
    • बात वाजिब है, लेकिन imperative code को parse और evaluate करना, principle of least privilege के हिसाब से declarative data रखने की तुलना में कहीं ज्यादा मुश्किल और कम flexible है
      और shebang line खुद भी असल में comment की तरह ही काम करती है
      45 साल से यह इतनी गहराई से जम चुकी है कि लोग यह बात ज्यादा महसूस ही नहीं करते कि वह shell comment है
    • “comments हटाने पर भी code उसी तरह चलना चाहिए” वाली शर्त अब भी सही है
      अगर वही dependencies install की गई हों, तो code उसी तरह चलेगा
      यह code के अपने meaning को बदलने के बजाय उस environment को बदलता है जिसमें code चलता है, और इस लिहाज से यह shell script के ऊपर लिखे #!/bin/bash comment से अलग नहीं है
    • पूरी तरह सहमत हूं, और उम्मीद है कि आखिरकार ऐसा form standardize हो जाएगा
      हालांकि uv शायद dependencies पता करने के लिए code execute नहीं करना चाहेगा, इसलिए यह Python syntax का बहुत सीमित subset होना चाहिए
      शुरुआत में ही ऐसी चीज की जरूरत होना language की कमजोरी दिखाता है
      import statement को खुद dependency के बारे में सारी जानकारी दे पाने में सक्षम होना चाहिए
  • पिछले कुछ महीनों में HN पर यह topic बहुत बार आया है, और हाल के उदाहरण ये हैं
    https://news.ycombinator.com/item?id=43500124
    https://news.ycombinator.com/item?id=42463975
    uv पसंद है, लेकिन self-contained शब्द से दो वजहों से सहमत होना मुश्किल है
    पहली, script चलाने के लिए uv पहले से installed होना चाहिए
    shell script से यह check कराया जा सकता है कि uv installed है या नहीं, और न हो तो curlpipe से install कराया जा सकता है, लेकिन इससे boilerplate काफी बढ़ जाता है और curlpipe तरीका अपने आप में भी अच्छा नहीं है
    दूसरी, home directory में कहीं virtual environment automatically create करना सच में self-contained नहीं है
    एक बार चलाकर script delete कर दें, तब भी वह virtual environment बचा रहता है और space लेता है, और uv docs में मुझे ऐसी कोई guarantee नहीं मिली कि ऐसे temporary virtual environments अपने-आप clean up होते हैं

    • यह शिकायत वाजिब है कि uv चाहिए, और न हो तो manually install करना होगा या curl | sh इस्तेमाल करना होगा
      हालांकि package managers जैसे-जैसे uv को repositories में शामिल करने लगेंगे, यह समस्या धीरे-धीरे कम होगी
      उदाहरण के लिए uv पहले से Alpine Linux और Homebrew में उपलब्ध है: https://repology.org/project/uv/versions
      साथ ही inline script metadata Python standard है
      अगर system में uv नहीं है और वह packaged भी नहीं है, लेकिन script के लिए सही Python version मौजूद है, तो pipx से चलाया जा सकता है: https://pipx.pypa.io/stable/examples/#pipx-run-examples
      pipx कहीं ज्यादा व्यापक रूप से packaged है: https://repology.org/project/pipx/versions
    • इस तरह की समस्या हल करने के लिए मैंने docker+uv shebang को जबरदस्ती जोड़कर देखा, और वह कुछ हद तक काम करता है
      किसी random developer machine पर uv की तुलना में Docker ज्यादा आम हो सकता है, और मूल लेख भी company project की बात कर रहा था, इसलिए यह plausible लगा
      हालांकि अभी यह बिल्कुल caching नहीं करता, इसलिए हर run पर download होता है, जो अटपटा है; शायद volume से इसे ठीक किया जा सकता है
      कुछ ऐसा है: https://hugojosefson.github.io/docker-shebang/#python
    • आम तौर पर computer पर program चलाने के लिए पहले कुछ न कुछ install करना ही पड़ता है, इसलिए uv install करना अपने-आप में इतना बुरा नहीं लगता
      फिर भी अगर run करते समय internet से कोई अनजान चीज download होती है, तो उसे self-contained कहना मुश्किल है, और सच में पूरी तरह self-contained चीज AppImage के ज्यादा करीब है
    • 100% सहमत
      py2exe जैसी चीज इस्तेमाल करें तो self-contained “Python script” बनाई जा सकती है
      developer के लिए कई problems पैदा होती हैं, लेकिन user के लिए problems कम से कम रहती हैं
    • एक छोटी-सी बात जोड़ूं तो, uv के package deduplication की वजह से जब तक unique dependencies न हों, virtualenv space नहीं लेता
  • Nix से भी यही तरीका इस्तेमाल होता है, और shebang लाइन ऐसी दिखती है
    #! nix-shell -i python3 -p "python312.withPackages (pkgs: [ pkgs.boto3 pkgs.click ])"
    ऐसा करने पर सिस्टम में सिर्फ Nix चाहिए, Python इंस्टॉल होना भी जरूरी नहीं

    • बात सही है, लेकिन अभी भी कई PyPI पैकेज nixpkgs में पैकेज नहीं हुए हैं, इसलिए यह uv जितना सामान्य-उपयोग वाला तरीका नहीं है
    • मूल लेख में भी ठीक यही है कि जरूरत पड़ने पर uv तुरंत Python इंस्टॉल कर देता है
    • यही तकनीक किसी भी भाषा पर लागू की जा सकती है
      सबसे obvious उदाहरण ऐसा bash है जिसमें सभी dependencies निर्दिष्ट हों, और मैंने Nix shebang से तेज single-file Rust script भी बनाई है
      https://nixos.wiki/wiki/Nix-shell_shebang
    • Nix इंस्टॉल होना, uv होना वाली शर्त से कहीं ज्यादा मजबूत requirement है
    • nix-shell के बजाय flake-आधारित command nix shell से वही काम कैसे किया जाए, यह जानने में दिलचस्पी है
  • बाकी comments की तरह “self-contained” वाला दावा इस पर निर्भर है कि uv इंस्टॉल हो
    अगर सच में self-contained Python script चाहिए, तो Nuitka compiler देखने लायक है
    इसे gRPC service production में बिना समस्या इस्तेमाल कर रहा हूं, और बस nuitka --onefile run.py चलाना काफी है
    compiler होने के कारण result binary, PyInstaller से bundle किए गए मूल Python program से तेज भी हो सकती है
    लेखक के GitHub page पर लिखा है, “संभव सबसे अच्छा Python Compiler बनाने के लिए बूढ़ा होकर मरने तक कोशिश करना मेरे जीवन का mission है”
    https://nuitka.net/
    https://github.com/kayhayen

  • यह pattern सच में पसंद है, लेकिन अफसोस कि इसे LSP के साथ ठीक से चला नहीं पाया
    Helix में pyright इस्तेमाल कर रहा हूं, और editor को uv run hx script.py से चलाने पर भी काम नहीं करता
    uv run --with whatever-it-is-i-need hx script.py जैसा कर सकते हैं, लेकिन duplication बढ़ती जाती है

    • खुद की बनाई हुई बदसूरत uve script इस्तेमाल कर रहा हूं
      $ cat ~/.local/bin/uve
      #!/bin/bash
      temp=$(mktemp)
      uv export --script $1 --no-hashes > $temp
      uv run --with-requirements $temp vim $1
      unlink $temp
      अच्छा होगा अगर editor जल्द ही uv python find --script support करे
  • काफी उपयोगी लगता है
    Python-based projects को long-term deploy करते समय uv ज्यादा सुरक्षित विकल्प है या नहीं, यह सोच रहा हूं
    करीब 5 साल पहले dependency management के लिए Anaconda इस्तेमाल किया था, फिर बाद में rules बदल गए और 200 से ज्यादा employees वाले संगठनात्मक customers अब Anaconda मुफ्त में इस्तेमाल नहीं कर सकते थे, commercial license लेना पड़ता था—वही rug pull याद आ रहा है

    • uv MIT या Apache-2.0 license में है
      वे development बंद कर सकते हैं या आगे का काम किसी दूसरे license वाले fork में ले जा सकते हैं, लेकिन पुराने license को retroactively बदल नहीं सकते, इसलिए जो अभी मौजूद है वह open source होने की guarantee रखता है
      अगर सच में चिंता है, तो fork बनाकर sync करते रह सकते हैं
      असल में यही बात लगभग दूसरे OSS projects पर भी लागू होती है, इसलिए मैं ज्यादा चिंता नहीं करूंगा
      मेरी जानकारी में conda कभी open source नहीं था और binaries distribute करता रहा है
      https://github.com/astral-sh/uv?tab=readme-ov-file#license
    • मुझे लगता है Anaconda का rug pull repository side पर था
      conda-forge के packages अभी भी मुफ्त में इस्तेमाल किए जा सकते हैं
      uv तो बस PyPI इस्तेमाल करता है, इसलिए समस्या हो तो uv से pip या Poetry वगैरह पर switch कर सकते हैं, और packages अब भी उसी जगह से आते रहेंगे
    • मेरी समझ है कि अगर project में contributor license agreement (CLA) हो और contribution copyright project owner को सौंपना पड़ता हो, तो relicensing संभव है
      ऐसा owner अंततः कल्पना किए जा सकने वाले सबसे बुरे अमीर व्यक्ति द्वारा खरीद लिया जाएगा
      मैंने uv की contribution guide और issues सरसरी तौर पर देखे, लेकिन CLA नहीं दिखा, जबकि PyTorch की contribution guide के सबसे ऊपर CLA था
      फिर भी Anaconda के आखिरी FOSS version का community fork होना चाहिए था
      Redis में ऐसा हुआ, और Redis भी CLA इस्तेमाल करता है: https://github.com/redis/redis/blob/unstable/CONTRIBUTING.md#redis-software-grant-and-contributor-license-agreement
      CLA पर कभी sign नहीं करना चाहिए
      मेरे हिसाब से बेहतर है कि केवल copyleft projects में ही contribute करें
      हम मुफ्त में काम करने के लिए बहुत ज्यादा पैसा कमाते हैं
  • छोटी utilities के लिए containerization के बजाय यह अच्छा packaging alternative लगता है
    अब सभी colleagues को uv install करने के लिए मनाना पड़ेगा

    • uv हैरानीजनक रूप से तेज है, इसलिए मदद मिलेगी
    • हमारे लिए अड़चन यह है कि SCA vulnerability scanner अभी uv के साथ काम नहीं करता
  • Ruby के bundler/inline जैसा लगता है
    अच्छा है कि Python में भी कुछ ऐसा आया, और सच में बहुत सुविधाजनक है
    https://bundler.io/guides/bundler_in_a_single_file_ruby_script.html

  • जानना चाहूंगा कि क्या Windows पर किसी ने इसे चलाया है
    जिस गेम मोड टूल पर मैं काम कर रहा हूं, उसमें यह ट्रिक इस्तेमाल करना चाहता था, लेकिन shebang ट्रिक चला नहीं पाया

    • Windows और Linux पर इसे अक्सर इस्तेमाल करता हूं, और ऐसे करता हूं
      $> uv init --script .py
      $> uv add --script .py ...
      $> uv add --script .py --dev ...
      $> uv run .py
      उम्मीद है मदद मिलेगी
      स्रोत: https://docs.astral.sh/uv/guides/scripts/
    • Windows के लिए सामान्य CPython installer py launcher install करता है और उसे .py files से associate करता है
      py launcher shebang line को support करता है
      कुछ दिन पहले इसी topic पर आए एक blog post में भी इसे cover किया गया था, और उसके मुताबिक -S हटाना होगा: https://thisdavej.com/share-python-scripts-like-a-pro-uv-and-pep-723-for-easy-deployment/
      https://news.ycombinator.com/item?id=43500124
      खुद try नहीं किया, इसके बजाय file association बदल दी ताकि सभी .py files default रूप से uv run से खुलें
      https://docs.python.org/3/using/windows.html#python-launcher-for-windows
      https://peps.python.org/pep-0397/
    • कई सालों से Windows development नहीं किया, लेकिन याद के मुताबिक Windows में shebang support नहीं था
    • PyInstaller जैसी कोई चीज़ इस्तेमाल कर सकते हैं
      https://pyinstaller.org
    • पता नहीं मददगार होगा या नहीं, लेकिन किसी ने Racket में PowerScript के साथ ऐसा ही कुछ करने का तरीका post किया था
      https://onor.io/2025/01/more-scripting-with-racket.html
  • इस use case की वजह से मुझे uv पसंद आने लगा, लेकिन यह बात Zen of Python के खिलाफ लगती है कि एक official और बहुत useful PEP को official Python tools support नहीं करते
    मेरे नज़रिए से यह वह पहला पल था जब Python “batteries included” नहीं लगा
    अब system में Python dependency managers भी दो हो गए हैं
    मुझे पता है कि Python dependency management पर कहने को बहुत कुछ है, लेकिन पिछले कुछ सालों में अगर project में सिर्फ requirements.txt होता था, तो मैं default pip+venv से काम चला लेता था

    • Python build specs में ऐसा flow कुछ हद तक था
      याद है कि pyproject.toml, tomllib library से पहले आया था
      इसलिए कुछ versions तक modules को ऐसी भाषा में specify करना पड़ता था जिसे Python default रूप से पढ़ नहीं सकता था
      यह उस default तरीके से भी खराब स्थिति है जिसमें unused metadata शामिल होता है
      आखिर इसी वजह से वह metadata है, वरना बस Python syntax होता