/usr/bin/env -S uv run
125 points
10 months ago
| 15 comments
| simonwillison.net
| HN
BiteCode_dev
10 months ago
[-]
Other neat tricks with uvx (uv equivalent of npx) to run one time commands in some contexts:

- alias download_mp3="uvx --no-cache --from yt-dlp[default] yt-dlp --extract-audio --audio-format mp3" to download sound from Youtube videos, SoundCloud pages, etc. This update yt-dlp every time, which is required given the counter measures change so often and the dl rarely affect the total processing time anyway (requires ffmpeg).

- "uvx --with <package> --with pyqt5 --from qtconsole jupyter qtconsole" starts a qtconsole (GUI version of ipython) with <package> installed so you can test it quickly. Temp venv, everything cached so next time it's instant, one single copy of pyqt5 for the current use no matter how many times you run those.

- "uvx --with virtualenv pipx run pipsi install nodejs-bin". Ok it's useless, but it's fun that it even works :)

uv's cache system and downloads optimization are quite smart, as Charlie marsh (astral CEO) explains in the interview: https://www.bitecode.dev/p/charlie-marsh-on-astral-uv-and-th...

reply
smaddox
10 months ago
[-]
I've been using this for a few weeks now, and it's really handy. But I did learn the hard way that it fails if you don't have internet connection, even if you already have the venv cached.
reply
usrme
10 months ago
[-]
That's really unexpected! I'd default to the assumption that it would "just work" if all the dependencies are already met.
reply
BiteCode_dev
10 months ago
[-]
`--offline` :)
reply
chippiewill
10 months ago
[-]
Except you can't put that in the shebang for the first run
reply
BiteCode_dev
10 months ago
[-]
True, for servers you can't warm up, shiv is your best bet: https://shiv.readthedocs.io/

Or points to your own private pypi instance with --index-url.

reply
mrweasel
10 months ago
[-]
While neat, doesn't it also comes with certain issues?

Startup times has to be slower, but probably only for the first run?

There's a some level of violation of the "Principle Of Least Surprise", depending on the setting. For some it will be the reverse, the script they got just works, without any setup or package installation. For others we'll wonder why it just started downloading a bunch of packages we already have.

Probably not the greatest idea for production environments, where you should not or can not just pull in packages from the internet.

It's really cool that it works, but I think I'd recommended using it highly selectively.

reply
BiteCode_dev
10 months ago
[-]
Definitely not for prod, but I used to have (and recommend: https://www.bitecode.dev/i/114175324/whats-a-good-name-for-a...) a giant venv just for my laptop scripts. Having one per script is too much, but none is inviting pain.

The problem with that is that eventually too many scripts means you will hit incompatibilities in Python where you can only install one version of a lib in each venv.

This trick is perfect because:

- From now on, I always install uv on all my machines anyway.

- After the first run, not only the cache make it fast, but it uses hard links so that you don't even pay the of multiple install on disk space (that's also how they are so fast in creating the envs, that and some interesting HTTP/zip tricks: https://www.bitecode.dev/p/charlie-marsh-on-astral-uv-and-th...).

- Deps are clearly defined in the script, so it's self-documenting.

For prod, shiv (https://shiv.readthedocs.io/) is probably your best bet but I'm betting uv will come up with a version of that soon.

reply
quickslowdown
10 months ago
[-]
I want to understand shiv, but I just can't grok it. I've successfully made a PyInstaller executable in the past.

Do you have any good sources for learning shiv? The docs are very sparse & lack examples and there aren't as many blogs discussing shiv as I'd hoped.

Also, do you know if shiv works on Windows?

reply
BiteCode_dev
10 months ago
[-]
Unfortunatly no, plus the docs are indeed not great and the UI itself is lacking.

But yes, unlike pex, shiv works on windows.

It's very different than pyinstaller in the sense that:

- it uses a standard (the zipapp format from python stdlib)

- it assumes python is already installed (it's not stand alone)

I definitely should write on article on that on Bite Code on day. Adding it to the list.

reply
quickslowdown
9 months ago
[-]
I'd read it! :) I want to understand Shiv, but I haven't even gotten it to work after a few hours tinkering, and that's usually where I give up and look to another tool.
reply
chippiewill
10 months ago
[-]
> but probably only for the first run?

It's slow on every run because it has to build the python virtual environment every time, even if it's cached all the packages

reply
simonw
10 months ago
[-]
If you benchmark that you'll find uv spends microseconds getting the virtual environment up and running - that's its USP, they've invested a huge amount of work and ingenuity into making virtual environments so fast to create that you no longer have to think about that.

(Mainly through tricks involving hard links)

reply
heresie-dabord
10 months ago
[-]
> Probably not the greatest idea for production environments

Nor for any system where one takes care to not needlessly increase the threat surface.

reply
thewisenerd
10 months ago
[-]
this builds upon PEP 723, which is "accepted", so it's likely here to stay.

https://peps.python.org/pep-0723/

I've been very slowly migrating scripts to work with this, and `pipx run`. glad to know uv has also picked it up.

reply
skavi
10 months ago
[-]
reminds me of nix-shell shebang [0] which enables a similar pattern for scripts of arbitrary languages.

[0]: https://nixos.wiki/wiki/Nix-shell_shebang

reply
p4bl0
10 months ago
[-]
It's a neat trick, but it still depends on uv being installed and network connectivity.

What's the advantage of this that makes it worth despite these constraints, compared to e.g. using pyinstaller [1] to build and distribute a single executable file with the python interpreter and all the dependencies of your project bundled in it in the exact versions you chose in your development virtual environment?

[1] https://pyinstaller.org/

reply
chippiewill
10 months ago
[-]
It's not for production grade stuff, it's for small scripts you want to send to someone for a little job.
reply
fernandotakai
10 months ago
[-]
sometimes, i want to share a script with a friend or with a coworker and setting everything up from scratch is such a pain.

this makes everything SO much easier.

reply
Hikikomori
10 months ago
[-]
Can just share a clear text script with a colleague over slack and let him just run it without extra steps.
reply
ginko
10 months ago
[-]
Doesn't look like my Ubuntu machine comes with 'uv' installed at least. Can't say I've ever heard of it either.
reply
austinjp
10 months ago
[-]
It's the new hotness in Python package management:

https://docs.astral.sh/uv/

reply
fmajid
10 months ago
[-]
reply
teroshan
10 months ago
[-]
`uv` is not a new standard though, just a wrapper.
reply
tspng
10 months ago
[-]
`uv` is definitely not a wrapper. It's written from scratch. If you mean by wrapper that it's mostly compatible with pip (using `uv pip`), that's one of their adoption strategies to make it easier to switch to. But it does a lot more than that.
reply
wasyl
10 months ago
[-]
I mean, it's right there as the first highlight in the docs

> A single tool to replace pip, pip-tools, pipx, poetry, pyenv, twine, virtualenv, and more.

reply
kixpanganiban
10 months ago
[-]
Curious - how many containers and machines images these days come with uv by default?
reply
delusional
10 months ago
[-]
It's worth noting that this is not portable. The /usr/bin/env -S flag is not standardized by posix and not implemented on busybox.
reply
SAI_Peregrinus
10 months ago
[-]
Neither is Python.
reply
jauntywundrkind
10 months ago
[-]
Zx adds a couple nice ease of use things to node.js, designed to help shell scripting. Among other things, if you call /usr/bin/env zx, it will automatically retrieve any module imports you have in your code! https://github.com/google/zx
reply
jas39
10 months ago
[-]
I have been doing this for a while. Voila:

#!/usr/bin/env -S uv run -q --no-project --python ">=3.12" --with "openai"

reply
lofaszvanitt
10 months ago
[-]
Who wants to give a script rights to download anything and configure and whatever? For development, sure it's ok.
reply
theanonymousone
10 months ago
[-]
Maybe surprisingly, JBang has offered this functionality for Java since 2020. Happy we have it un Python too, now.
reply
rikthevik
10 months ago
[-]
Fantastic. I'm very impressed with Simon Willison in general (what a dynamo) and this in particular.
reply
manfre
10 months ago
[-]
Simon is an impressive individual, but in this instance, you're praising the messenger and not the source.

> Code from this PR [1] by David Laban.

That leverages the features of uv run with embedding script dependencies [2].

[1] https://github.com/alsuren/sixdofone/pull/8 [2] https://docs.astral.sh/uv/concepts/projects/run/#running-scr...

reply
rikthevik
10 months ago
[-]
Praise for everybody!
reply
ryandvm
10 months ago
[-]
What's `uv`? Oh, another Python package manager. Is it a new lunar cycle already?

Not to shit on anyone's hard work, but how is Python the only popular language whose package management situation is always actively getting more complicated?

I used to love Python, but I won't touch it anymore because I just don't have it in me to learn what the new idiomatic package management practices are in any given Python ecosystem.

For any aspiring language designers out there - take good notes about what happens if you don't bake package management into the official tooling.

reply
simonw
10 months ago
[-]
A lot of very experienced people in the Python world are taking uv very seriously.

Sometimes if you reinvent the wheel enough times you eventually get a round one.

reply
yjftsjthsd-h
9 months ago
[-]
> how is Python the only popular language whose package management situation is always actively getting more complicated?

I don't think it is? Did javascript suddenly get boring when I looked away?

> I used to love Python, but I won't touch it anymore because I just don't have it in me to learn what the new idiomatic package management practices are in any given Python ecosystem.

While people keep trying to invent newer better options, you can in fact manage 95% of cases with just pip+virtualenv. (Granted, the other 5% is a quick descent to madness, usually courtesy of non-Python integrations.)

reply
fragmede
9 months ago
[-]
the problem isn't virtualenv itself, it's that using one is cumbersome. python-wool, that I wrote, works around this but still requires technical understanding before you're fully able to use it. you're right that those are 95% of the way there, but that last 5% is where people get lost.
reply