包含uv库的自包含Python脚本
Self-contained Python scripts with uv

原始链接: http://blog.dusktreader.dev/2025/03/29/self-contained-python-scripts-with-uv/

这篇博文重点介绍了如何使用`uv`创建包含嵌入式依赖项的自包含可执行 Python 脚本。作者利用`uv`的`# /// script`标签直接在脚本中声明依赖项,而不是管理虚拟环境或全局安装依赖项。`uv`随后会自动创建一个隔离的环境,安装依赖项并运行脚本。 博文进一步演示了如何将此功能与shebang行结合使用以创建真正可移植的可执行文件。通过使用`#!/usr/bin/env -S uv run --script`,可以直接执行脚本,调用`uv`透明地管理环境和依赖项。这消除了用户手动设置系统的需要,简化了 Python 脚本(尤其是复杂脚本)在任何安装了`uv`的类 Unix 系统上的部署和执行。作者使用该脚本与一个简单的API进行交互以进行测试。

Hacker News 最新 | 过去 | 评论 | 提问 | 展示 | 招聘 | 提交 登录 使用 uv 编写自包含的 Python 脚本 (dusktreader.dev) todsacerdoti 4小时前 17 分 | 隐藏 | 过去 | 收藏 | 讨论 加入我们,参加 6 月 16-17 日在旧金山举办的 AI 初创公司学校! 指南 | 常见问题 | 列表 | API | 安全 | 法律 | 申请 YC | 联系我们 搜索:

原文

TLDR

You can add uv into the shebang line for a Python script to make it a self-contained executable.

I am working on a Go project to better learn the language. It's a simple API backed by a postgres database.

When I need to test out an endpoint, I prefer to use the httpx python package inside an ipython REPL over making curl requests. It's nice to be able to introspect responses and easily package payloads with dicts instead of writing out JSON.

Anyway, I decided to write a script to upsert some user data so that I can beat on my /users endpoint.

My jam_users.py script looks like this:

This is really straight-forward. It will clear out any existing users and then insert these test users. Right after that, I get dropped into an ipython repl to do what I need for testing. All I have to do is run:

However, if I want to run the script as-is, I will need to choose one of these approaches:

  • Install the dependencies httpx, IPython, and loguru globally in my system python
  • Create a virtual environment, activate it, install deps, and run my script while the venv is activated

These are both not great options in my opinion. These approaches also rely on having a system python installed that is compatible with these packages. This isn't as big of a problem, but something to consider anyway.

I've been using uv a lot lately, and I'm becoming quite enamoured with its usefulness as a package manager, efficiency as a pip replacement, and abilities for isolated python executables. One thing that I haven't used much yet are the special # /// script tags in a python script.

When I first read about this functionality, I was pretty skeptical. I'm not particularly keen on embedding syntax into comments. However, this seemed like the perfect application. So, updated my script to include the deps in the script header like so:

With this added, now I can run the script really easily with uv:

Great! Now, uv will create an isolated virtual environment for the script, download the dependencies and install them, and then run my script in the context of that venv! I don't have to manage the virtual environment myself nor worry about cluttering my system python with packages that I will invariably forget to remove later.

One nice thing about a regular Python script, though, is that you can make it executable with a shebang line:

Now, if I make the script executable (chmod +x jam_users.py), I can invoke it directly as an executable script! However, this won't take advantage of the uv script header because Python itself will just ignore the comment.

So, I did some digging and found out that you can actually embed the invocation of the uv command right in the shebang line like so:

This works because the -S flag tells the system to split everything after it into separate arguments before passing it to the system's env.

Now (after chmod +x jam_users.py, of course), I can execute my script directly:

That's it! What's even better is that I can run this script on any (Unix) system that has uv installed without needing to do ANY dependency or virtual environment management.

Now, this script itself is really trivial and not much more than a toy example. However, in my past I have written rather complex scripts that I needed to hand off to other users to run. Of course, this always came with a long explanation of how to prepare their system just to run the script. This approach solves that problem instantly and painlessly (as long as they have uv installed).

Take it for a spin, and let me know your thoughts.

Thanks for reading!

联系我们 contact @ memedata.com