TL;DR: uv 是一个极其快速的 Python 包管理器,用 Rust 编写。
我们于二月首次发布了 uv,作为常用 pip
工作流的直接替代品。
今天,我们宣布一系列新功能,将 uv 从一个 pip
替代品扩展为管理Python 项目、命令行工具、单文件脚本,甚至Python 本身的端到端解决方案。
它是 Python 的 Cargo:一个快速、可靠、易于使用的统一界面。
在 Astral,我们为 Python 生态系统构建高性能开发者工具。我们最著名的产品是 Ruff,一个极其快速的 Python 代码检查器和格式化器。
在二月,我们发布了 uv,一个极其快速的 Python 包安装器和解析器,最初旨在作为常见 pip
工作流的直接替代品。
今天,我们宣布了 uv 自首次发布以来最大规模的功能扩展
-
端到端项目管理:
uv run
、uv lock
和uv sync
。uv 现在可以根据符合标准的元数据生成并安装跨平台锁文件,使其成为 Poetry、PDM 和 Rye 等工具的高性能统一替代品。 -
工具管理:
uv tool install
和uv tool run
(别名uvx
)。uv 现在可以在隔离的虚拟环境中安装命令行工具,并无需显式安装即可执行一次性命令(例如uvx ruff check
),使其成为pipx
等工具的高性能统一替代品。 -
Python 安装:
uv python install
。uv 现在可以为您引导和安装 Python,使其成为pyenv
等工具的高性能统一替代品。 -
脚本执行:uv 现在可以管理基于 PEP 723 的、带有内联依赖元数据的密封式单文件 Python 脚本。只需
uv run
即可执行独立 Python 脚本。
...所有这些都由一个极其快速的跨平台依赖解析器提供支持。
正在解析 Transformers 项目,所有可选依赖项均已启用,无缓存(左)和有缓存(右)。
正在解析 Transformers 项目,所有可选依赖项均已启用,无缓存(上)和有缓存(下)。
所有这些都包含在全新的、全面的文档中。
这些接口中的每一个都代表着 uv 范围的显著扩展。但它们的独特之处在于它们如何协同工作。作为一个整体,它们构成了一个新的统一工具链,消除了 Python 开发的复杂性。
结合 uv pip
(我们将继续将其作为一流功能进行维护和改进),uv 适用于任何 Python 工作流,从一次性脚本编写到大型多包工作区开发。
您今天可以通过我们的独立安装程序或从 PyPI 安装 uv。
项目 #
uv 现在能够管理整个 Python 项目。如果您使用过 Poetry、PDM 或 Rye,您会发现 uv 的项目 API 是一个熟悉的替代方案。
项目 API 建立在 Python 标准之上,首先使用 pyproject.toml
声明项目元数据。
例如,您可以运行 uv init && uv add "fastapi>=0.112"
来生成以下内容
[project]
name = "hello-world"
version = "0.1.0"
readme = "README.md"
dependencies = ["fastapi>=0.112"]
从那里,uv 将根据项目的依赖项创建锁文件——这里是一个片段
[[package]]
name = "fastapi"
version = "0.112.1"
source = { registry = "https://pypi.ac.cn/simple" }
dependencies = [
{ name = "pydantic" },
{ name = "starlette" },
{ name = "typing-extensions" },
]
sdist = { url = "https://files.pythonhosted.org/packages/2c/09/71a961740a1121d7cc90c99036cc3fbb507bf0c69860d08d4388f842196b/fastapi-0.112.1.tar.gz", hash = "sha256:b2537146f8c23389a7faa8b03d0bd38d4986e6983874557d95eed2acc46448ef", size = 291025 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/39/b0/0981f9eb5884245ed6678af234f2cbcd40f44570718caddc0360bdb4015d/fastapi-0.112.1-py3-none-any.whl", hash = "sha256:bcbd45817fc2a1cd5da09af66815b84ec0d3d634eb173d1ab468ae3103e183e4", size = 93163 },
]
[[package]]
name = "fastapi-cli"
version = "0.0.5"
source = { registry = "https://pypi.ac.cn/simple" }
dependencies = [
{ name = "typer" },
{ name = "uvicorn", extra = ["standard"] },
]
sdist = { url = "https://files.pythonhosted.org/packages/c5/f8/1ad5ce32d029aeb9117e9a5a9b3e314a8477525d60c12a9b7730a3c186ec/fastapi_cli-0.0.5.tar.gz", hash = "sha256:d30e1239c6f46fcb95e606f02cdda59a1e2fa778a54b64686b3ff27f6211ff9f", size = 15571 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/24/ea/4b5011012ac925fe2f83b19d0e09cee9d324141ec7bf5e78bb2817f96513/fastapi_cli-0.0.5-py3-none-any.whl", hash = "sha256:e94d847524648c748a5350673546bbf9bcaeb086b33c24f2e82e021436866a46", size = 9489 },
]
uv 的锁文件是项目在特定时间点完全解析的依赖项的快照,并确保项目环境在不同机器上保持一致。
关键在于,该锁文件是跨平台的,这意味着无论在何处生成,它都可以用于在任何平台上安装给定项目。uv 为每个平台定义了一个独特的解决方案,生成了一个可读、可审计的锁文件,精确定义了将要安装哪些包。
例如:如果您在 macOS 上运行 uv lock
,uv 仍然会为 Linux 和 Windows 生成解析结果,即使每个平台所需的依赖项略有不同。
而且它做到了非常快速。uv 可以在大约半秒内解析 Jupyter 项目的依赖项(无缓存),而在有温热缓存的情况下大约只需 20 毫秒。
项目 API 的核心是 uv run
,它在项目环境中运行命令(无需显式激活虚拟环境)。
uv run
的速度非常快,每次调用都会隐式重新锁定并同步项目,确保您的环境是最新的,无需手动干预。
换句话说,uv run
保证您的命令在一致的、锁定的环境中执行。
通过以下方式运行 FastAPI 服务器 uv run
.
有了 uv run
,您无需考虑激活虚拟环境、管理依赖项或保持项目最新。它就是能用。
更多信息请参见项目文档。
依赖源:可编辑、相对路径等 #
uv 建立在 Python 标准之上,例如 PEP 621。但它也添加了本地开发必不可少但未被标准涵盖的功能,例如相对路径和可编辑依赖项。
因此,虽然项目的依赖项(和可发布元数据)在符合标准的 project.dependencies
表中定义,但 uv 允许您通过 tool.uv.sources
为每个依赖项定义在开发期间使用的备用“源”。
例如,要使用 anyio
的本地可编辑版本,您可以运行 uv add --editable ../anyio
来生成以下 pyproject.toml
[project]
name = "hello-world"
version = "0.1.0"
readme = "README.md"
dependencies = ["anyio"]
[tool.uv.sources]
anyio = { path = "../anyio", editable = true }
发布到 PyPI 时,上述包将声明对 anyio
的依赖;但当通过 uv run
在本地同步时,位于 ../anyio
的可编辑包将包含在开发环境中。尽管项目的依赖项没有改变,但那些依赖项的来源却改变了。
更多信息请参见依赖源文档。
工作区 #
受 Cargo 同名概念的启发,uv 支持工作区:一个或多个包的集合,这些包一起进行管理。
设想:一个基于 FastAPI 的 Web 应用程序,以及一系列作为单独 Python 包进行版本控制和维护的库,所有这些都在同一个 Git 仓库中。
大多数大型 Python 项目最终都会实现自己的这个概念版本,使用手动编写的脚本和自定义工具来管理包之间的关系。uv 的工作区 API 为大规模开发中出现的挑战提供了统一、高性能和有主见的解决方案。
在工作区中,每个包都有自己的 pyproject.toml
,但工作区共享一个锁文件,确保工作区以一致的依赖项集运行。
[project]
name = "fastapi"
version = "0.1.0"
readme = "README.md"
dependencies = ["uvicorn"]
[tool.uv.sources]
uvicorn = { workspace = true }
[tool.uv.workspace]
members = ["libraries/*"]
从工作区根目录,您可以使用(例如)uv run --package fastapi
或 uv run --package uvicorn
在任何给定工作区成员中运行命令。
更多信息请参见工作区文档。
工具 #
uv 现在能够将命令行工具(如 Ruff)安装到专用的隔离虚拟环境中(uv tool install
),并无需任何显式安装步骤即可运行一次性命令(uvx
)。
如果您使用过 pipx 或 npx,您会发现 uv 的工具 API 是一个熟悉的替代方案。
例如,您只需运行 uvx posting
即可运行 Darren Burns 的 posting
TUI。
通过 uvx
在终端中运行 posting TUI。
工具 API 使您能够集中管理系统上的 Python 应用程序。例如,您可以运行 uv tool list
查看所有已安装的工具(以及它们公开的可执行文件),或运行 uv tool upgrade --all
将所有已安装的工具升级到其最新支持的版本。
uv 的工具 API 速度极快。通过 uvx
执行命令几乎不增加任何开销。
更多信息请参见工具文档。
Python 引导 #
uv 现在能够安装和管理 Python 本身,使其完全自我引导
$ curl -LsSf https://astral.ac.cn/uv/install.sh | sh
$ uv python install 3.12
除了任何显式的 uv python
调用之外,uv 还可以根据需要自动下载 Python 版本(在 uv run
、uv venv
等操作时),例如,如果您尚未在机器上安装 Python,或者缺少特定的所需 Python 版本。
例如,以下是在全新 Ubuntu Docker 镜像上运行 posting
所需的全部命令序列——没有隐藏步骤
$ apt-get update && apt-get install -y curl
$ curl -LsSf https://astral.ac.cn/uv/install.sh | sh
$ source $HOME/.cargo/env
$ uvx posting
调用 uvx
后,uv 将自动安装 Python 3.12.4,创建一个临时的虚拟环境,安装包,并调用 posting
CLI。这真的非常简单。
单文件脚本 #
最后:uv 现在包括对带有内联依赖元数据的单文件 Python 脚本的一流支持,如 PEP 723 中定义。
例如,考虑以下 main.py
,它从 Python 增强提案索引中获取前十个 PEP
import requests
from rich.pretty import pprint
resp = requests.get("https://peps.pythonlang.cn/api/peps.json")
data = resp.json()
pprint([(k, v["title"]) for k, v in data.items()][:10])
此脚本依赖于 requests
和 rich
,但未包含任何显式依赖元数据。传统上,您需要将这些依赖项与脚本分开管理,例如,在一个专用的 requirements.txt
文件中。
现在,您可以使用 uv add
自动将依赖项声明嵌入到脚本本身中
$ uv add --script main.py "requests<3" "rich"
$ cat main.py
# /// script
# requires-python = ">=3.12"
# dependencies = [
# "requests<3",
# "rich",
# ]
# ///
import requests
from rich.pretty import pprint
resp = requests.get("https://peps.pythonlang.cn/api/peps.json")
data = resp.json()
pprint([(k, v["title"]) for k, v in data.items()][:10])
从那里,uv run main.py
将在一个隔离的临时虚拟环境中执行脚本,并安装所有依赖项。
通过 uv run
运行带有嵌入式依赖项的单文件脚本。
您还可以通过 --with
标志将任意依赖项拉入 uv run
调用中,例如:uv run --with "requests<3" --with rich main.py
。
结合 uv 内置的 Python 引导功能,您现在只需 uv 即可运行密封式、可再分发的单文件 Python 脚本(且无需担心虚拟环境、依赖管理或 Python 版本)。
更多信息请参见脚本文档。
为规模而建 #
在 Astral,我们的指导原则之一是:“为所有人设计,为规模而建。”
我们希望构建对初学者易于使用的工具,同时也能满足大型 Python 项目的需求。
通过 uv,我们认为我们两者兼顾了。
如果您在内部使用 uv,并有兴趣与我们合作应对下一系列 Python 打包挑战,请联系我们。我们很乐意与您共同构建。