11 ms·
Using uv and PEP 723 for Self-Contained Python Scripts
- dagenix 2y ago> This approach eliminates the need for complex setup tools like requirements.txt or package managers... And yet, the rest of the article is about uv. According to uv itself: > An extremely fast Python package and project manager, written in Rust. It's a package manager!
- frfl 2y agoSeems like you're dismissing the uv single file setup approach without fully understanding it. I'd recommend giving it a try. It's indeed simpler and snappier than any other package manager to date.
- GolDDranks 2y agoA package manager that is a quick and snappy binary that doesn't need a big runtime, unlike most of the Python tools.
- deleted 2y ago[deleted]
- zahlman 2y agoWhat exactly is your standard for "big"? $ du ~/.local/pipx/venvs/uv/bin/uv | cut -f 1 38812 Stripped and dynamically linked, BTW. Compare the system-provided Python: $ du /usr/bin/python3.12 | cut -f 1 7832 (But also, if you hope not to pay the cost of a Python runtime, what is your remaining use case for uv?)
- frfl 2y agoAnyone use PEP 723 + uv with an LSP based editor? What's your workflow? I looked into it briefly, the only thing I saw after a lot of digging around was to use `uv sync --script <script file>` and get the venv from the output of this command, activate that venv or specify it in your editor. Is there any other way, what I describe above seems a bit hacky since `sync` isn't meant to provide the venv path specifically, it just happens to display it. Edit: I posted this comment before reading the article. Just read it now and I see that the author also kinda had a similar question. But I guess the author didn't happen to find the same workaround as I mention using the `sync` output. If the author sees this, maybe they can update the article if it's helpful to mention what I wrote above.
- nickysielicki 2y agohttps://pyproject-nix.github.io/uv2nix/usage/inline-metadata.html https://pyproject-nix.github.io/uv2nix/usage/inline-metadata... might be an option for you.
- JimDabell 2y agouv v0.6.10 has just been released with a more convenient way of doing this: uv python find --script foo.py — https://github.com/astral-sh/uv/releases/tag/0.6.10 https://github.com/astral-sh/uv/releases/tag/0.6.10 — https://docs.astral.sh/uv/reference/cli/#uv-python-find--script https://docs.astral.sh/uv/reference/cli/#uv-python-find--scr...
- lynx97 2y agoThanks! Came here to ask how to make pyright work with uv scripts... pyright --pythonpath $(uv python find --script foo.py) foo.py
- BoumTAC 2y agoHow does it work ? How does it find the environment ? Let say I have a project in `/home/boumtac/dev/myproject` with the venv inside. If I run `uv python find --script /home/boumtac/dev/myproject/my_task.py`, will it find the venv ?
- stereo 2y agoI used to have a virtual environment for all little scrappy scripts, which would contain libraries I use often like requests, rich, or pandas. I now exclusively use this type of shebang and dependency declaration. It also makes runnings throwaway chatgpt scripts a lot easier, especially if you put PEP-723 instructions in your custom prompt.
- Titan2189 2y agoI've switched all my scripts to include their own dependencies, and it works like a charm. Only problem I haven't been able to solve is how to convince my IDE (PyCharm) to run all scripts through uv before executing them / debugging them. PyCharm does have uv support, but from what I can see only for uv managed projects, not for individual scripts with embedded requirements.
- __float 2y agoThis was discussed somewhat recently in https://news.ycombinator.com/item?id=42855258 https://news.ycombinator.com/item?id=42855258
- alkh 2y agoBonus points for "Bonus: where does uv install its virtual environments?" section! I was wondering the same question for a long time but haven't had a chance to dig in. It's great that venv is not being recreated unless any dependencies or Python version got modified
- MeetingsBrowser 2y agoThe ads make this hard to read on mobile.
- ukuina 2y agoCan uv install Python? Is it possible to curl the uv binary and then invoke such a packaged script with --no-cache to run everything, including the Python installation, from /tmp?
- rtpg 2y agoIm fairly certain the answer to this is “yes”. Probably need to futz with env cars to get all the caches etc into /tmp though. It needs to put Python _somewhere_
- simonw 2y agoYes, uv can install Python: https://docs.astral.sh/uv/guides/install-python/ https://docs.astral.sh/uv/guides/install-python/ There are a bunch of environment variables for controlling where it puts things, here's one that looks relevant: https://docs.astral.sh/uv/configuration/environment/#uv_python_install_dir https://docs.astral.sh/uv/configuration/environment/#uv_pyth...
- rat87 2y agoYes. Uv can install specific Python versions from python build standalone (they have taken over maintenance for it https://astral.sh/blog/python-build-standalone https://astral.sh/blog/python-build-standalone ) instead of from python.org because python doesn't release relocatable binaries (and doesn't release binaries for Linux I think). It works well but does have a few minor https://gregoryszorc.com/docs/python-build-standalone/main/quirks.html https://gregoryszorc.com/docs/python-build-standalone/main/q...
- diego898 2y agoYes - in fact I recently uninstalled pyenv and poetry, switched to uv, used it to install python and poetry (for work projects)
- sireat 2y agoThis is neat writeup on use of uv, but it doesn't solve the "how to give self contained script to grandma" problem. Now anyone you give your script to has to install uv first.
- alanfranz 2y agoFor simple scripts (I never succeeded using it on something really complex, but it's great when you don't want to use bash but need something like Python) I had used this approach that still works nowadays and has no uv dependency (only requires pip to be installed in the same Python interpreter that you're using to run your script): https://www.franzoni.eu/single-file-editable-python-scripts-with-dependencies/ https://www.franzoni.eu/single-file-editable-python-scripts-...
- renewiltord 2y agoYou can write a bash shebang that curl into shell. Unfortunately when I did it and gave to grandma it has failed because grandma has substituted oil shell and linked it as sh which is not best practice. I think grandmother shell script is simply impossible. They have spent decades acquiring idiosyncratic unix environment
- ElectricalUnion 2y agoGood thing those days init is systemd instead of a series of de jure POSIX shell scripts but de facto bashism shell scripts that will fail to boot if you swap /bin/sh away from bash. At least ubuntu helped force the ecosystem to at least pretend to support /bin/dash too.
- oezi 2y agoI think uv should become a default package for most operating systems.
- globular-toast 2y agoIt automatically downloads interpreters from some internet source. It's a security nightmare. It can be configured not to do that but it's not the default.
- aitchnyu 2y agoTangential, I want to whip up simple apps (or instructing an LLM to do so) but its simpler to do formatted text/tables, inputs, graphs etc in a single HTML file+JS. Which library should I adopt? Seems Marimo is the closest, but are there lighter web popups, graphs, inputs etc?
- renewiltord 2y agoI let Claude build them (which it does in React). Then I copy and paste them into o3-mini-high and ask it to port to raw html and JS. It pulls in some chart libraries and goes to town. Give it a crack and see.
- alanfranz 2y agoShameless plug for an old approach I use for various scripts when I think bash is not enough: https://www.franzoni.eu/single-file-editable-python-scripts-with-dependencies/ https://www.franzoni.eu/single-file-editable-python-scripts-... This doesn't require UV, just pip within the same interpreter, but I wouldn't use it for something big, and still requires deps to be updated every now and then ofc (I never tried with raw deps, I always pin dependencies).
- networked 2y agoOh hey, I have seen your post. Making a script download the dependencies on its own is an interesting challenge. I am a big fan of inline script metadata in Python, and I was an early adopter when pipx implemented PEP 722 (the precursor to PEP 723), but I made my version for fun. https://pip.wtf/ https://pip.wtf/ was on HN not that long ago (https://news.ycombinator.com/item?id=38383635 https://news.ycombinator.com/item?id=38383635). I had my own take on it that used virtual environments, supported Windows, and was d a free license: https://github.com/dbohdan/pip-wtenv https://github.com/dbohdan/pip-wtenv.
- networked 2y ago* was under a free license
- indigodaddy 2y agoHow long do these isolated uv-created venvs persist for? If you have a lot of scripts then it’s going to be a lot of venvs hanging around ready for subsequent reuse if the same script is run?
- incognito124 2y agoThey hardlink files so venvs don't take up a lot of disk space
- skeledrew 2y agoI'm generally not a fan of the incremental rustification of the Python ecosystem, but I started using uv a few weeks ago just for this particular case and have been liking it. And to the point where I'm considering to migrate my full projects as well from their current conda+poetry flow. Just a couple days ago I also modified a script I've been using for a few years to patch pylsp so it can now see uv script envs using the "uv sync --dry-run --script <path>" hack.
- oulipo 2y agowhat's the --dry-run hack ?
- skeledrew 2y agoUsing "--dry-run" makes the command a no-op, but still prints the env path.
- ratorx 2y agoOut of curiosity, what are some problems with rustification? Is it an aversion to Rust specifically or a dislike of the ecosystem tools not being written in Python? The former is subjective, but the latter seems like not really much of an issue compared to the language itself being written in C.
- WesolyKubeczek 2y agoA problem with rustification is that it puts a giant ecosystem on a giant ecosystem, with poorly matched tooling. C has a lot of home ground advantage, and CPytjon is built on it. Then you have PyPy which you’d have to accommodate somehow. It doesn’t help that in a case where you have to build everything, Rust build toolchain currently needs Python. That sure would make bootstrapping a bitch if Python and Rust became a circular dependency of one another.
- masklinn 2y ago> Then you have PyPy which you’d have to accommodate somehow. Adding pypy support to a pyo3 + maturin project was literally just a matter of telling maturin to build that wheel. And I added graal while at it. Hopefully they eventually add stable ABI support too so I don’t have to add individual pypy/graal wheel targets. Or pyo3 and maturin may support hpy once that’s stable.
- silvanocerza 2y agoAlbeit uv is amazing this not a unique feature of the project. Hatch has this feature since a year or so too. https://hatch.pypa.io/latest/how-to/run/python-scripts/ https://hatch.pypa.io/latest/how-to/run/python-scripts/
- smitty1e 2y agoAs mentioned in the article, along with PDM.
- ivh 2y agoI have also been switching to uv recently, frequently with --script, and I love it. What I havn't yet figured out though is how to integratge it with VScode's debugger to run the script with F5. It seems to insists on running what it thinks is the right python, not respecting the shebang.
- Galanwe 2y agoDoes anyone know a way to reuse that trick for jupyter notebooks? So that one could share a notebook declaring it's dependencies .
- benrutter 2y agoNot sure it's as performant, but jupyter notebooks can install dependencies at run time with `!pip install my_cool_library==2.3.1`. If feels a little bit less elegant, and you don't get access to uv's caching goodness, but that'd more or less achieve what you're looking for!
- dagw 2y agoThat works with uv as well. Launch Jupyter with uv tool run jupyter lab and then put !uv pip install my_cool_library !uv pip install other_library ... in the first cell. Now you get full uv caching goodness.
- benrutter 2y agoOooh, now that's glorious!
- dagw 2y agoThe only thing to be aware of with this approach is that you don't get an isolate venv for each notebook. So if you're working on one notebook that needs my_lib 1.X and one that needs my_lib 2.X you'll need to manually create separate venvs for each and make sure you start Jupyter in the right venv for each notebook.
- Galanwe 2y agoRight, though that requires an existing virtualenv with jupyter in the first place. I was more dreaming of something where I can send a notebook to someone not technical, and that just bootstraps on the fly an env with jupyter and the required dependencies.
- 2y ago
- ratorx 2y agoSlightly off-topic, but the fact that this script even needs a package manager in a language with a standard library as large as Python is pretty shocking. Making an HTTP request js pretty basic stuff for a scripting language, you shouldn’t need or want a library for it. And I’m not blaming the author, the standard library docs even recommend using a third party library (albeit not the one the author is using) on the closest equivalent (urllib.request)! > The Requests package is recommended for a higher-level HTTP client interface. Especially for a language that has not cared too much about backwards compatibility historically, having an ergonomic HTTP client seems like table stakes.
- gorgoiler 2y agoIt has two! — http.client and urllib.request — and they are really usable. Lots of people just like requests though as an alternative, or for historical reasons, or because of some particular aspect of its ergonomics, or to have a feature they’d rather have implemented for them than have to write in their own calling code. At this stage it’s like using jQuery just to find an element by css selector (instead of just using document.querySelector.)
- ratorx 2y agoSure historical popularity is a good reason for people who are already familiar with it to keep using it. That is not really an excuse for why the standard library docs for the clients you mentioned link to requests though (especially if they were actually good, rather than just being legacy). If they really were good, why would the standard library itself suggest something else?
- WesolyKubeczek 2y agoRequests used to have good PR back in the day and ended up entrenched as a transitive dependency for a lot of things. Because it’s for humans, right? But recently I had to do something using raw urllib3, and you know what? It’s just as ergonomic.
- masklinn 2y ago
- singularity2001 2y agouv add --script wordlookup.py httpx # /// script # requires-python = ">=3.13" # dependencies = [ # "httpx", # ] # /// import httpx That seems pretty redundant. Why can't UV just infer the dependencies from the import statements?
- csunbird 2y agowhich version of httpx?
- singularity2001 2y agosame as in dependencies = [ # "httpx", # ] the current one by default
- chippiewill 2y agoThere's a few things: - uv won't necessarily know which modules aren't already present, because they can load from modules being developed in the current directory - It's not easy to determine what imports will happen in a Python script due to transitive dependencies and dynamic loading - The names of python modules are not always the same as the packages that contain them - for example the yaml module comes from the pyyaml package Also the second line of the Zen of Python is "explicit is better than implicit": https://peps.python.org/pep-0020/ https://peps.python.org/pep-0020/
- singularity2001 2y ago- It's not easy to determine what imports will happen fair enough, but adding option to auto import from the main file would solve 97% of use cases - uv won't necessarily know which modules aren't already present easy to check - The names of python modules are not always the same great opportunity to add convenient simple mapping / name resolution - Zen Should DRY don't repeat yourself be higher up?
- sorenjan 2y agoThis is covered in the Pep 723 document, it's not a uv invention. https://peps.python.org/pep-0723/#why-not-infer-the-requirements-from-import-statements https://peps.python.org/pep-0723/#why-not-infer-the-requirem...
- cjs_ac 2y agoSpeaking as someone who writes Python code for a living, I like the language, but I consider the ecosystem dire. No one seems able to propose a solution to the problem of 'how do I call someone else's code?' that isn't yelling 'MOAR PACKAGE MANAGERS' in their best Jeremy Clarkson impression. I have no idea how any of it works and I see no point in learning any of it because by the time I've worked it out, it'll all have changed anyway. At work, there are plenty of nutjobs who seem to enjoy this bullshit, and as long as following the instructions in the documentation allow me to get the codebase running on my machine, I don't have to deal with any of it. At home, I refuse to use any Python package that isn't in the Debian repositories. Sure, it's all 'out of date', but if your package pushes breaking changes every fortnight, I'm not interested in using it anyway. If people are still talking about how great uv is in five years' time, maybe I'll give it a go then.
- IshKebab 2y agoI totally agree, but uv is the real deal. It's not another Poetry, Pipenv, etc. uv takes Python infra from "jesus this is awful" to "wow this is actually quite nice". It is a game changer. You should really try it now. Waiting 5 years is just needless self-flagellation. IMO the only risk is that Astral run out of money, but given how dire the situation without uv is, I'd say it's easily worth the risk.
- imtringued 2y agoThe python ecosystem will catch up. Before Bambu Lab a lot of 3D printer companies produced garbage printers and after Bambu Lab every 3d printer company has almost 1:1 copied their printers, implying that they were selling garbage all these years, because they have no trouble catching up with Bambu Lab the moment they had to (to stay relevant).
- stickfu 2y agoNot worth trying to drag folks with this mindset into the future. The way I see his workflow(and I do get it, I’m stubborn with some financial stuff), is same way he sees using uv and other new stuff. I agree uv is real deal and will be around for awhile. It has totally reignited my love of writing python. I will say, the love of uv on hacker news has surprised me. I was expecting a lot more replies like theirs.
- sorenjan 2y agoYou don't need to run the script as `py wordlookup.py` or make a batch file `wordlookup.cmd` in Windows. The standard Python installation in Windows installs the py launcher and sets it as the default file handler for .py (and .pyw). So if you try to run `wordlookup.py` Windows will let the py launcher handle it. You can check this with `ftype | find "Python"` or look in the registry. You can make it even easier that that though. If you add .py to the PATHEXT environment variable you can run .py files without typing the .py extension, just like .exe and .bat.
- deleted 2y ago[deleted]
- intellectronica 2y agoIt's one of the coolest features of uv. I'm using it to vibe scripts and execute them immediately - https://everything.intellectronica.net/p/the-little-scripter https://everything.intellectronica.net/p/the-little-scripter