10 ms·
Self-contained Python scripts with uv
- holysoles 2y agoThis seems like a good packaging alternative to containerizing for smaller utilities. Now to convince all my coworkers to install uv..
- tiltowait 2y agoThe showstopper for us is our SCA vulnerability scanner doesn't work with uv yet :(
- cmgbhm 2y agoYou can add an intermediate sca stage that exports the uv dependencies as requirements.txt
- throwaway48476 2y agoUv is amazingly fast. That should help.
- dharmab 2y agoHas anyone gotten this to work on Windows? I wanted to use this trick for some tooling for a game mod I'm working on but couldn't get the shebang trick to work.
- seabrookmx 2y agoI haven't done dev on windows in many years, but IIRC windows doesn't have shebang support.
- deleted 2y ago[deleted]
- magicalhippo 2y agoBut it does support registering extension handlers[1], so if you name your scripts with say .pyuv and register "uv run --script %1", or whatever it would take to run uv, as the handler of .pyuv files, it should work. Unless uv does something funky that is. You could do this during an installation step, for example. [1]: https://learn.microsoft.com/en-us/windows/win32/shell/fa-file-types https://learn.microsoft.com/en-us/windows/win32/shell/fa-fil...
- _mlbt 2y agoYou could always use something like PyInstaller... https://pyinstaller.org https://pyinstaller.org
- quickslowdown 2y agoI use this frequently on Windows and Linux. These are the steps I take: $> uv init --script <script_name>.py $> uv add --script <script_name>.py <pkg1> <pkg2> ... $> uv add --script <script_name>.py --dev <dev_pkg1> <dev_pkg2> ... $> uv run <script_name>.py Hope this helps :) Source: https://docs.astral.sh/uv/guides/scripts/ https://docs.astral.sh/uv/guides/scripts/
- networked 2y agoUnfortunately, `uv add --dev` doesn't work with `--script`: > uv -V uv 0.6.10 > uv add --script foo.py --dev ruff error: the argument '--script <SCRIPT>' cannot be used with '--dev' Usage: uv add --script <SCRIPT> --link-mode <LINK_MODE> <PACKAGES|--requirements <REQUIREMENTS>> For more information, try '--help'. There is currently no mention of `uv add --script foo.py --dev ...` in https://docs.astral.sh/uv/guides/scripts/ https://docs.astral.sh/uv/guides/scripts/. Inline script metadata in Python doesn't standardize development dependencies. I wrote a recent comment about how I develop scripts with `pyproject.toml` to have a regular development environment: https://news.ycombinator.com/item?id=43503171 https://news.ycombinator.com/item?id=43503171.
- quickslowdown 2y agoInteresting about the --deb flag not working with scripts. I wrote this from memory and feel like I've installed dev dependencies for a script, but it must be a hallucination because I just tried and it doesn't work. Thanks for the correction.
- mixmastamyk 2y agoAside: angle brackets should be avoided in shell examples; one mistaken enter and work can be destroyed.
- sorenjan 2y agoThe regular CPython installer on Windows installs the py launcher and associates it with .py files. The py launcher supports shebang lines. This was covered in a blog post about this same topic that was posted here a few days ago. According to that you have to omit the -S: https://thisdavej.com/share-python-scripts-like-a-pro-uv-and-pep-723-for-easy-deployment/ https://thisdavej.com/share-python-scripts-like-a-pro-uv-and... https://news.ycombinator.com/item?id=43500124 https://news.ycombinator.com/item?id=43500124 I haven't tried it myself, I simply changed the file association so all .py files are opened with uv run as standard. https://docs.python.org/3/using/windows.html#python-launcher-for-windows https://docs.python.org/3/using/windows.html#python-launcher... https://peps.python.org/pep-0397/ https://peps.python.org/pep-0397/
- dharmab 2y agoInteresting. The workflow I've been using skips the CPython installer and only uses uv.
- sorenjan 2y agoWindows doesn't support shebang lines as you probably know, but if you associate uv with .py files you'll get the same result. I think it should be something like this: ftype Python.File=C:\Path\to\uv.exe run %L %* If you don't use the CPython installer the Python.File file type might not be defined, so you might need to set that with `assoc` first: assoc .py=Python.File
- skeledrew 2y agoShebang should work fine from WSL.
- gus_massa 2y agoI'm not sure it's useful, but someone posted how to do a similar thing for Racket with PoweScript https://onor.io/2025/01/more-scripting-with-racket.html https://onor.io/2025/01/more-scripting-with-racket.html
- icameron 2y agoThis looks quite useful! Is uv a safer choice to use for deploying a python based project long term? I’m referring to the anaconda rug pull that happened- using it for managing dependencies about 5 years ago, but then they changed some rules so that any of my clients who are organizations with over 200 employees are no longer free to use anaconda. They must pay a commercial license
- 01HNNWZ0MV43FF 2y agoAs I understand it, relicensing is possible when a project has a Contributor Licensing Agreement (CLA) which says that you're signing over your copyright to your contribution to the project's owners. (Who will eventually be bought out by the worst rich person you can think of - Yes, him.) I peeked in uv's contributing guide and issues and didn't see any CLA. In PyTorch the CLA was mentioned at the top of the contributing guide. Although, there should have been a community fork of the last FOSS version of Anaconda. That's what happened with Redis, and Redis uses a CLA: https://github.com/redis/redis/blob/unstable/CONTRIBUTING.md#redis-software-grant-and-contributor-license-agreement https://github.com/redis/redis/blob/unstable/CONTRIBUTING.md... Don't ever sign a CLA, kids. Hell, only contribute to copyleft projects. We get paid too much to work for free.
- throwaway48476 2y agoNot having a CLA prevents relicensing but open source licenses aren't revokable anyways.
- hansvm 2y agoThat's not been tested much in the courts. Recent rulings suggest OSS at least has consideration and thus can't be blanket terminated without some justification, but the USC provides that justification (with some onerous requirements -- 2-10 years of notice, has to happen in a certain time window, ...), even for licenses stating irrevocability.
- godelski 2y agouv is licensed under either MIT or Apache-2.0[0] They can always stop developing or fork to a different license and all future work belongs under that license, but you can't back date licenses, so what exists is guaranteed Open Source. If you're super worried, you can create a fork and just keep it in sync. But this is essentially true about any other OSS project so I wouldn't be concerned. As far as I'm aware, conda was never open sourced and had always distributed binaries. [0] https://github.com/astral-sh/uv?tab=readme-ov-file#license https://github.com/astral-sh/uv?tab=readme-ov-file#license
- tiltowait 2y agoI really like this pattern, but unfortunately I haven't been able to get it to work with my LSP (pyright, in Helix), even when running my editor via uv (`uv run hx script.py`). I could always do `uv run --with whatever-it-is-i-need hx script.py`, but that's starting to get redundant.
- mayli 2y agoI have my own ugly 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 Hope editor could support the `uv python find --script` soon.
- Galanwe 2y agoFYI, have a look at "trap .. EXIT" to defer cleanups like your unlink. It's neat cause it will run even if the script is interrupted / fails before the unlink.
- kissgyorgy 2y agoWe do the same with Nix, the shebang line looks like this: #! nix-shell -i python3 -p "python312.withPackages (pkgs: [ pkgs.boto3 pkgs.click ])" With this, the only requirement is Nix on the system, you don't even need Python to be installed!
- skavi 2y agoYup, and you can apply the same technique to any language. The obvious example is bash with all the dependencies specified, but I’ve also hacked up quick single file rust scripts using nix shebangs. https://nixos.wiki/wiki/Nix-shell_shebang https://nixos.wiki/wiki/Nix-shell_shebang
- execat 2y agoHow to do the same thing with `nix shell` (The flake based command) instead of `nix-shell`?
- skowalak 2y agoWhile that is true, there are still lots of PyPI packages not yet packaged with nixpkgs, so this is not as universal an approach as uv.
- falcor84 2y ago> you don't even need Python to be installed! Note that this is exactly the case in TFA - uv takes care of installing Python ad-hoc.
- Tractor8626 2y ago
- stared 2y agoMy pet peeve (in general, not specific to UV, which I genuinely appreciate) is using comment sections for controlling code execution. Using comments for linters and developer notes is perfectly acceptable. However, for configuration or execution-related data, a far superior pattern would be something like: UV_ENV = { "dependencies": { "requests": "2.32.3", "pandas": "2.2.3" } } This approach has clear advantages: - It's valid Python syntax. - It utilizes standard, easily-parsable data structures rather than ad-hoc comment parsing. It makes creation and validation smooth. - Crucially, it adheres to a core principle: if you remove all comments from your code, it should still execute identically.
- petters 2y agoI completely agree. Hope something like this is eventually standardized. Problem is that uv probably does not want to execute anything to find out dependencies, so it would have to be a very restrictive subset of python syntax. The fact that is is needed at all of course highlights a weakness in the language. The import statements themselves should be able to convey all information about dependencies
- stared 2y agoIt can be specified that it is a valid, static structure before imports.
- nemetroid 2y agoBetween future statements and other imports, then?
- deleted 2y ago[deleted]
- pedrosorio 2y ago> The fact that is is needed at all of course highlights a weakness in the language. The import statements themselves should be able to convey all information about dependencies What languages convey the version of the dependencies in a script’s import statements?
- ulrischa 2y agoSo now I have to make sure uv is installed instead of python. Whar us this better? And python is available on almost any system
- shawabawa3 2y agoThe whole point of uv is to solve the nightmare that is running a script with the right version of python with the right dependencies "Just use the system python" gets you right back to the start (oh no! It didn't parse because it used python 3.11 features and I'm still on 3.5)
- mr_mitm 2y agouv can seemlessly get the correct python binary on demand. It would be a pain to get, say, python 3.9 or python 3.14 on my system. Making sure uv is installed actually seems to be less of an issue, but of course this varies.
- skeledrew 2y agoPython is not a globally available thing. I was really surprised when I setup Kubuntu 24.04 and found it missing. And now you can do `uv run --python=<version> ...` and have all that automatically handled on a case by case basis.
- whywhywhywhy 2y ago> And python is available on almost any system This is actually the root of all Python problems, by it believing it has a right to be a core part of the operating system all the package design choices treat their installation like they're the only thing running on the machine when the realities of Python packages are they all rely on very specific versioning from the interpreter to between the packages so the idea of having a canonical version of pytorch that all your projects run on just doesn't exist.
- frizlab 2y agoHey I have done the same for Swift scripts! (Well I have rewritten what Homebrew’s creator did some time ago, but does not maintain anymore, to be precise.) https://github.com/xcode-actions/swift-sh https://github.com/xcode-actions/swift-sh
- bityard 2y agoThis has come up a LOT on HN in the past few months, some other recent examples: https://news.ycombinator.com/item?id=43500124 https://news.ycombinator.com/item?id=43500124 https://news.ycombinator.com/item?id=42463975 https://news.ycombinator.com/item?id=42463975 I like uv and all, but I take exception to the "self-contained" claim in two regards: 1) The script requires uv to already be installed. Arguably you could make it a shell script that checks if uv is already installed and then installs it via curlpipe if not... but that's quite a bit of extra boilerplate and the curlpipe pattern is already pretty gross on its own. 2) Auto-creating a venv somewhere in your home directory is not really self-contained. If you run the script as a one-off and then delete it, that venv is still there, taking up space. I can't find any assertion in the uv docs that these temporary virtual environments are ever automatically cleaned up.
- benhurmarcel 2y ago> I can't find any assertion in the uv docs that these temporary virtual environments are ever automatically cleaned up. That’s a good point. I wonder if at least they are reused when you run the script several times.
- dagw 2y agoMy understanding is that uv creates a hash of the script name, python version and dependencies when creating the venv. So if none of those change, it will reuse the venv.
- maxed 2y agoI took a closer look; uv installs the inline required packages in it's cache directory `~/.cache/uv` (if they are not already there). So the packages will probably exist until the cache is cleared with for example `uv clear`. It's not that the inline requirements make a new `.venv` directory or something, uv seems to link the packages to a central location and reuse them if already there.
- dazzawazza 2y agoAgree 100%. Using something like py2exe creates a self contained "python script". This comes with a lot of problems for the developer but minimum problems for the user.
- intellectronica 2y agoEven better: self-contained uv run python scripts generated by AI: https://everything.intellectronica.net/p/the-little-scripter https://everything.intellectronica.net/p/the-little-scripter
- mos_6502 2y agoSeems analogous to bundler/inline [1] on the Ruby side of the world. Happy to see something similar in Python— it’s really handy! [1] https://bundler.io/guides/bundler_in_a_single_file_ruby_script.html https://bundler.io/guides/bundler_in_a_single_file_ruby_scri...
- Szpadel 2y agoI do not really understand how this is self contained, when you have to install additional software to run it. my approach is to use python build-in venv https://gist.github.com/Szpadel/43794d606d9924e7fea3e63fb80042bf https://gist.github.com/Szpadel/43794d606d9924e7fea3e63fb800... that way you can run scripts with external packages with only basic python installation
- maleldil 2y agoYour version needs Python. uv needs needs only uv, as it can manage python installation by itself. It's also a lot easier to install uv than to manage Python installations (there's a reason pyenv and the like exist).
- Szpadel 2y agoThat's fair point. Its maybe different use case. For me main goal was to be able to run project scripts on macos and Linux ootb, and both have some python 3 version already available ootb. But probably if you need specific python version it isn't best way
- hacknneyhoffman 2y ago[dead]
- deleted 2y ago[deleted]
- northisup 2y agohelp get this supported in vscode by liking the issue here: https://github.com/microsoft/vscode-python/issues/24916 https://github.com/microsoft/vscode-python/issues/24916
- amelius 2y agoSo how does this guarantee that it will never raise some libc error, or similar? Unfortunately I have become sceptical about "self contained" distribution methods.
- maxerickson 2y agoThis isn't self contained in that sense, it's deferring dependency management to runtime, with uv apparently doing that reliably enough for the use case.
- winwang 2y agoWhat do people think about pixi?
- yallpendantools 2y agoI learned to love uv because of this usecase but I still find it against the Zen of Python that an official (and, dare I say, extremely useful!) PEP is not supported by the official Python tools. This is the first time that Python didn't come with "batteries included" from my POV. Now I also have two Python dependency managers in my system. I know there are volumes to talk about Python dependency management but all these years, as long as a project had a requirements.txt, I managed to stick to vanilla pip+venv.
- shiandow 2y agoThat's been a bit of a trend for the Python build specs. Pretty sure the pyproject toml predates the tomllib library. So for a few versions you had to specify your module in a language that Python couldn't read natively. Which is worse than just having a default way for including metadata that's not used. That's what makes it metadata after all. Otherwise it would just be Python syntax
- redsky880 2y agoHmmm this seems bad That code is bad for several reasons including not catching+handling exceptions (and possibly retrying), and accessing the JSON properties w/o get() The overhead of re-installing stuff and setting up a header seem very unnecessary to run a simple script If this is about sending some Python for somebody else to run easily - the recipient should always check the code. You should never run arbitrary code. For example, there have been hacks performed using YAML loader (crypto exchange). For dependencies, use the standard pyproject.toml
- bitwize 2y agoWhen Python has something akin to Tcl's starkits, then it'll be cooking with gas -- I might even use it again. Py2exe came close, but was not cross-platform.
- krupan 2y agoOverall, and admittedly from a bit of a distance, uv run feels like a reinvention of Zero Install, but for only Python. I also wondered why virtual environments were invented for Python when general environment managers (like Modules) already existed. These packaging and environment problems have never been specific to Python https://0install.net/ https://0install.net/ https://modules.sourceforge.net/ https://modules.sourceforge.net/
- talideon 2y agouv has little in common with 0install, which has its origins in RISC OS's application directories. uv is an attempt to fix the fragments Python development environment tooling story.
- krupan 2y agoI mean yes, you are correct. UV does a lot of different things, but this particular "self-contained app" feature is a lot like zero install. You run your app, its dependencies are automatically downloaded and cached for other uv/zero install apps to use, and it's all transparent and easy.
- talideon 2y agoIn this case, it's nothing specific to uv though: there's a PEP outlining how this stuff is declared and uv is just one of the tools that happens to support the format. I wouldn't be at all surprised of pipx also supports it.
- amai 2y agoIronically zero install is pretty difficult to install: https://docs.0install.net/details/macos/ https://docs.0install.net/details/macos/
- egeres 2y agoI love it, it feels like an extension of these other HN posts: - Uv's killer feature is making ad-hoc environments easy (valatka.dev): https://news.ycombinator.com/item?id=42676432 https://news.ycombinator.com/item?id=42676432 - Using uv as your shebang line (akrabat.com): https://news.ycombinator.com/item?id=42855258 https://news.ycombinator.com/item?id=42855258
- bheadmaster 2y agoAs mentioned in other comments, the "self-contained" claim depends on `uv` being installed. For those who want a really self-contained Python script, I'd like to point out the Nuitka compiler [0]. I've been using it in production for my gRPC services with no issues whatsoever - just "nuitka --onefile run.py" and that's it. It Just Werks. And since it's a compiler, the resulting binary is even faster than the original Python program would be if it were bundled via Pyinstaller. The author's GitHub page [1] contains the following text: Other than software development, my passion would be no other. It's my life mission to create the best Python Compiler I can possibly do or die trying, ... of old age. [0] https://nuitka.net/ https://nuitka.net/ [1] https://github.com/kayhayen https://github.com/kayhayen