Home | Blag Index


From: wayne+blog@waynewerner.com
To: everyone.everywhere.all.at.once
Date: Tue, 09 Sep 2025 13:56:53 -0500
Subject: uv, fabric, and you

Do you like Python's uv or fabric?

Ultraviolent Fabric

Or uv, fabric, and you!

If you're like me, you may be uv-hesitant. After all, uv is really just Yet Another Tool that you have to come to grips with and why can't I just python -m venv --prompt my-cool-stuff and .venv/bin/python -m pip install my packages?

And that's a great question! Ultimately... you can!

But uv provides two things that I mark as absolute killer features.

  1. The cache makes things astoundingly fast, including being able to install when you're hacking on the road without wifi or cell tethering
  2. Running scripts is cool, actually.

Cache

I don't know what there is really to say about the cache. But uv gets it right. Every time you download a new version of a package, uv stores it locally on your machine so instead of pip taking a hot second to do dependency resolution and download all of the packages... it just works. It also has some pretty slick pyproject.toml management features that make a lot of the things I used to do manually completely automatic. Meaning I can build packages and create packages with practically zero effort. I can add dependencies to my packages and it all just does the right thing. It's very nice.

Scripts?

When I first saw this functionality honestly I thought it was stupid.


# /// script
# dependencies = ["requests"]
# ///

import requests
print(requests.get('http://example.com'))

I thought it was a complete waste of my time. I can just create my more or less global python, or do python -m pip install --user request and I'm totally fine here.

But... this actually works great for one-offs, especially coupled with uv's cache. It just checks the version and installs the newer one or whatever you have specified. And you never have to worry about conflicting packages for different versions of your little one-off scripts. If it's too small to make a full package out of, this is an utterly useful tool for writing things and sharing with your team because all they need to do is run uv run yourscript.py and it will download all the dependencies. You don't have to teach them about virtual environments, or site-packages, or anything. Just uv run cool-tool.py

Weaving All of It Together

Fabric is a useful lil' automation platform. It's not ultra powerfull (I mean, it is for what it is), but I would say that it finds a niche in a similar vein to the /// scripts bit. It gives you the ability to run commands on N hosts, including locally, and easily capture output, copy files, and other shenanigans. If you're not in the market for something as robust as Salt then honestly Fabric is pretty hard to beat. But... it's kind of awkward to type this:

uv run --with fabric fab -H localhost sometask

The normal invocation is:

fab -H localhost sometask

Sure, you could uv tool install fabric but what if you don't want to?

Well, even if you declare a @task, you don't get quite the same functionality by running

uv run fabric.py

But with a little reverse engineering of what the entrypoint is for fabric normally, behold:

# /// script
# dependencies = ['fabric']
# ///

from fabric import task

@task
def cool(c):
    c.local('echo Hey dude!')


if __name__ == "__main__":
    import sys
    from fabric.main import program
    sys.exit(program.run())

Save that in a fabric.py and both of these work:

uv run fabric.py -H localhost cool
uv run --with fabric fab -H localhost cool

Take your pick!

^C


Home | Blag Index

This site is Copyleft Wayne Werner - BY-NC-SA 4.0