python uv 的基础使用

最近在进行MCP server 的开发,目前主流的 mcp server 主要以node 和python 为主,其中python 主要以uv 来启动服务的,我也是由此才开始接触uv,uv 工具可以管理本地的python 版本,虚拟环境以及打包发布,还可以运行脚本,作为mcp 开发的前序基础,本文主要记录以下使用uv 开发管理python 应用的各个环节。之后在进行mcp 开发时会一直使用uv 来管理环境。

uv 的安装

shell 复制代码
# On macOS and Linux.
curl -LsSf https://astral.sh/uv/install.sh | sh

# On Windows.
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

# With pip.
pip install uv

我习惯使用 pip 安装,如果本地电脑中有多个python 环境,如 python3.11, python3.12 等,需要确认一下用的是哪个版本的pip, 使用 pip --version 来查看一下具体的pip 位置

shell 复制代码
pip --version
pip 23.0.1 from C:\Python310\lib\site-packages\pip (python 3.10)

上面显示我使用的是3.10 的python, 安装完uv 以后,就可以在 C:\Python310\Scripts 目录中找到 uv.exe 和 uvx.exe, 这两个可执行文件后面都用的到。

uv 基础使用

在没有uv 之前,创建项目的流程大概是这样

  1. 先使用python 创建一个虚拟环境 python -m venv venv
  2. 安装项目所需要的第三方包 pip install xxxx
  3. 导出依赖到 requirements.txt 中, pip freeze>requirements.txt
  4. 之后上传到git,如果要上传到pypi, 需要在配置打包脚本

总体来讲,上面的流程没有什么问题,但是每一步都有很多注意的问题

  1. 创建虚拟环境时,需要确认哪个版本的python? 众所周知,不同版本的python差异还是蛮大的,且不会向后兼容。
  2. 使用pip 安装包的时候,缺乏依赖管理,如使用pip 安装了A,A又依赖了B,B又依赖了C,当环境中不在依赖A时,如果卸载了A,则不会卸载B和C。

使用uv 管理python 环境

传统的python 安装需要到官网或者镜像网站下载python 安装包安装,并配置好环境变量,创建虚拟环境的时候需要指明对应的python版本,如系统中有两个python 环境

makefile 复制代码
C:\Python310\python.exe
C:\Python311\python.exe

如果在环境变量 path 中,311的优先级更高,则使用 python -m venv venv 创建出来的python 环境是3.11 的,如果想要创建一个3.10 的,需要将具体的路径打全了

makefile 复制代码
C:\Python310\python.exe -m venv venv

使用 uv 安装python

运行 uv python list 查看系统中的python 版本

bash 复制代码
C:\Users\yangyanxing>uv python list
cpython-3.13.2-windows-x86_64-none                 C:\Python313\python.exe
cpython-3.13.1+freethreaded-windows-x86_64-none    <download available>
cpython-3.13.1-windows-x86_64-none                 <download available>
cpython-3.12.9-windows-x86_64-none                 C:\Python312\python.exe
cpython-3.12.8-windows-x86_64-none                 AppData\Roaming\uv\python\cpython-3.12.8-windows-x86_64-none\python.exe
cpython-3.11.11-windows-x86_64-none                <download available>
cpython-3.11.9-windows-x86_64-none                 C:\Python311\python.exe
cpython-3.10.16-windows-x86_64-none                <download available>
cpython-3.10.11-windows-x86_64-none                C:\Python310\python.exe
cpython-3.9.21-windows-x86_64-none                 <download available>
cpython-3.8.20-windows-x86_64-none                 <download available>
cpython-3.8.10-windows-x86_64-none                 C:\Python38\python.exe
cpython-3.7.9-windows-x86_64-none                  <download available>
pypy-3.10.14-windows-x86_64-none                   <download available>
pypy-3.9.19-windows-x86_64-none                    <download available>
pypy-3.8.16-windows-x86_64-none                    <download available>
pypy-3.7.13-windows-x86_64-none                    <download available>

如果要安装 3.7.9 的python

使用 uv python install 3.7.9

sql 复制代码
uv python install 3.7.9
cpython-3.7.9-windows-x86_64-none ------------------------------ 5.70 MiB/29.97 MiB 

也可以指定安装 pypy 版本的python(也可能安装失败)

使用 uv 创建虚拟环境

先使用uv 创建一个项目,这步骤不是必须的,但是推荐使用uv 创建项目,因为会默认创建pyproject.toml 文件以及初始化git 和README 文件,算是比较正规的操作,否则需要自己手工创建。

shell 复制代码
uv init firstuv

uv 工具会创建一个 firstuv 的目录,并且创建好相应的文件

此时,还没有创建虚拟环境,但是我们注意到,pyproject.toml 文件中有配置 requires-python>=3.12, 如果想修改python 版本,如使用3.8 的python, 则先修改pyproject.toml的配置, 再修改 .python-version 中的python 版本。

注意,如果 pyproject.toml 文件中配置的是 requires-python = ">=3.11", 而 .python-version 写的是 3.10, 则之后运行 uv sync 命令进行安装会报错。

使用 uv sync 命令可以让uv 工具根据pyproject.toml 文件中的配置进行虚拟环境的创建和依赖的下载,当我们从github 上下载一个别人开发的基于uv的python 项目时,这个命令可以很方便的创建好虚拟环境和安装好依赖,这里由于是自己创建的干净的项目,我先不使用sync 命令,手动的去创建虚拟环境, 使用 uv venv 命令创建虚拟环境

bash 复制代码
cd firstuv
uv venv --python 3.11
Using CPython 3.11.9 interpreter at: C:\Python311\python.exe
warning: The requested interpreter resolved to Python 3.11.9, which is incompatible with the project's Python requirement: `>=3.12`
Creating virtual environment at: .venv
Activate with: .venv\Scripts\activate

我使用python 3.11 创建了这个虚拟环境,但注意到得到了一个警告,由于pyproject 中指定python 为 >=3.12, 而我这里安装的是3.11, 会出现不兼容的问题。

这里还贴心的提示出激活虚拟环境命令。

使用 uv 安装第三方包

以往会使用pip install xxxx 来安装包,这已经成为了python 开发者必知必会的操作了,有了uv工具,可以使用 uv add xxxx 来安装第三方库

shell 复制代码
uv add requests fastapi

安装结束以后,uv.lock 文件会添加很多内容,这里的内容不要手工修改,让uv 自己来管理,同时 pyproject.toml 文件也添加上了刚才的依赖。

运行 uv tree 命令查看项目依赖

这个命令可以很清晰的展示项目中各个包的依赖关系。

使用 uv 卸载第三方包

之前有提过,使用pip 安装了A,A又依赖了B,B又依赖了C,那么卸载A时时不会卸载B和C的,这样就会造成一种site-packages 越来越臃肿的问题。

上面的依赖关系

fastapi->pydantic->pydantic-core->typing-extensions

那么我们来看一下卸载 fastapi 会不会同时卸载掉对应的依赖包

生成 pip 的依赖文件

uv 是一个新兴的 python 管理工具,并不是所有的开发者都会习惯使用它,更多的还是使用pip 来管理python 环境, 所以uv 工具也支持使用pip 来管理环境。

导出当前项目依赖到 requirements.txt 文件

通过 pyproject.toml 中的配置信息导出依赖文件,此时的pyproject.toml 中记录为

toml 复制代码
[project]

name = "firstuv"

version = "0.1.0"

description = "Add your description here"

readme = "README.md"

requires-python = ">=3.11"

dependencies = [

    "fastapi>=0.115.12",

    "requests>=2.32.3",

]

执行以下命令

python 复制代码
uv pip compile pyproject.toml -o requirements.txt

即可将项目依赖导出为 requirements.txt 文件。

也可以通过 uv 工具运行 pip 导出requirements.in 文件,

uv pip freeze>requirements.in

此时requirements.in 文件中已经记录了第三方依赖包,

text 复制代码
annotated-types==0.7.0

anyio==4.9.0

certifi==2025.1.31

charset-normalizer==3.4.1

fastapi==0.115.12

idna==3.10

pydantic==2.10.6

pydantic-core==2.27.2

requests==2.32.3

sniffio==1.3.1

starlette==0.46.1

typing-extensions==4.12.2

urllib3==2.3.0

这时使用pip 的开发者可以使用 pip install -r requirements.in 来安装包了。

但是这里推荐使用uv pip compile requirements.in -o requirements.txt 命令来重新编译一下, 生成的requirements.txt 会更加详细的记录包的依赖缘由

ini 复制代码
# This file was autogenerated by uv via the following command:

#    uv pip compile requirements.in -o requirements.txt

certifi==2025.1.31

    # via

    #   -r requirements.in

    #   requests

charset-normalizer==3.4.1

    # via

    #   -r requirements.in

    #   requests


requests==2.32.3

    # via -r requirements.in

......

之后对于习惯使用 pip 管理环境的用户就可以正常的使用 pip install 了。

uv 运行脚本

使用 uv init 创建的项目会自动创建一个hello.py 的文件,未来在实际项目中,创建完项目以后大概率第一件事就是删除掉这个文件,不过作为示例,我们先来看一下这个hello.py 中的内容

python 复制代码
def main():

    print("Hello from firstuv!")

if __name__ == "__main__":

    main()

很简单,就是一个hello world。 在没有uv 工具之前,要运行这个脚本,使用 python hello.py 即可,有了uv 工具,可以使用 uv run hellor.py 命令也可运行脚本

使用 uv 打包发布

我们会使用pip 从pypi 中安装第三方的包,但是很少向pypi 提交自己编写的包,这节使用uv 打包并上传到pypi。

在打包之前,我们来看一下的uv init 初始化项目有哪些不同,官方解释如下 docs.astral.sh/uv/concepts...

几个常用的选项如下

  • uv init --app 创建一个普通的app, 这个也是默认的选项,这种就是最基础的项目,这类型的项目不能直接打包,由于pyproject.toml 中没有配置build system
  • uv init --package 创建一个"包", 这类型的项目可以被打包发布,pyproject.toml 中会自动配置 build system,并且可以发布为工具(tool),使用 uv tool run (或者 uvx )来直接运行(本节重点介绍此种方式创建的包)
  • uv init --lib 创建一个"库", 这种和package 的区别在于没有project.scripts, 不能当工具来使用

上一节使用 uv init xxxx 来初始化一个普通的项目,普通的项目没有打包编译选项,这节我们使用 uv init --package 来初始化项目。

bash 复制代码
uv init --package --python 3.11 mcp-gaodeweather-server

Initialized project `mcp-gaodeweather-server` at `C:\Users\yangyanxing\Desktop\uvtest\mcp-gaodeweather-server`

cd mcp-gaodeweather-server

uv sync

此时就创建好了一个package 类型的项目。

我们来看一下目录结构

vbscript 复制代码
tree mcp-gaodeweather-server
mcp-gaodeweather-server
├── .python-version
├── README.md
├── pyproject.toml
└── src
    └── mcp-gaodeweather-server
        └── __init__.py

这里比之前多了一个scr 目录,包的代码都放到这里。

再看一下 pyproject.toml 文件

toml 复制代码
[project]
name = "mcp-gaodeweather-server"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
authors = [
    { name = "yangyanxing", email = "[email protected]" }
]
requires-python = ">=3.11"
dependencies = []
[project.scripts]
mcp-gaodeweather-server = "mcp_gaodeweather_server:main"
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

这个配置文件比之前多了 project.scripts 和 build-system 选项。build-system 选项为打包时用到的配置,流行的打包方式有多种,可以参考 hellowac.github.io/pypug-zh-cn...

不过如果不熟悉的话就使用默认的 hatchling.build

还有一个project.scripts 配置,mcp-gaodeweather-server = "mcp_gaodeweather_server:main",这个是配置了一个脚本的启动命令。

bash 复制代码
uv run mcp_gaodeweather_server

这行命令将会输出 Hello from mcp-gaodeweather-server!, 这个输出是 src/mcp-gaodeweather-server/__init__.py 中的main 方法定义的输出

python 复制代码
def main() -> None:
    print("Hello from mcp-gaodeweather-server!")

也就是当运行 uv run mcp_gaodeweather_server 时,实际上是执行了mcp_gaodeweather_server 模块中的main方法。

以上只有演示代码,并没有做什么, 之后会创建一个用于查询天气的 mcp 服务。

使用 uv 打包

使用 uv build 命令即可将项目进行打包

bash 复制代码
C:\Users\yangyanxing\Desktop\uvtest\mcp-gaodeweather-server>uv build
Building source distribution...
Building wheel from source distribution...
Successfully built dist\mcp_gaodeweather_server-0.1.0.tar.gz
Successfully built dist\mcp_gaodeweather_server-0.1.0-py3-none-any.whl

编译好的二进制whl文件还有源文件.tar.gz包文件将保存在dist 目录下。在打包之前,也可以编辑一下pyproject.toml 文件中的name,version,description 等元信息。这里就先不改了。

uv tool 的使用

uv 中有个tool 的概念,在 pyproject.toml 文件中定义的脚本

toml 复制代码
[project.scripts]
mcp-gaodeweather-server = "mcp_gaodeweather_server:main"

我们在之后是可以用 uv tool run mcp-gaodeweather-server 来运行的,我们也可以使用 uv tool install xxxx 来安装tool,如 uv tool install arxiv-mcp-server ,执行过程如下

当您运行 uv tool install arxiv-mcp-server 时,uv 会执行以下操作:

  • 解析包名: 确定要安装的包是 arxiv-mcp-server。​

  • 创建或使用现有的虚拟环境: uv 会在全局工具目录中创建一个隔离的虚拟环境,以确保安装的工具不会影响全局 Python 环境。​

  • 安装包及其依赖项: 在上述虚拟环境中,uv 使用 pip 安装 arxiv-mcp-server 及其所有必要的依赖项。​

  • 生成可执行文件: 安装完成后,uv 会在虚拟环境的 bin 目录下创建与 arxiv-mcp-server 相关的可执行文件,通常与包名相同。

上面我们使用了 uv run mcp-gaodeweather-server 来运行脚本,此时的脚本是在本地的,别人是无法使用的,或者我们换了一个虚拟环境也是运行不了的,我们期望使用 uv tool run mcp-gaodeweather-server 命令在任何地方运行我们的脚本, 也可以使用uvx mcp-gaodeweather-server 来运行, uvx 是 uv tool run 的缩写,uvx 可以自动从pypi 上下载安装包。

一般情况下,安装包会从pypi 下载,当然也可以从本地whl 文件安装,上面执行打包步骤以后,生产的whl 文件由于还没有上传到pypi,所以无法从pypi中下载安装的,此时我们可以使用本地文件进行安装。

bash 复制代码
uv tool install dist\mcp_gaodeweather_server-0.1.0-py3-none-any.whl
Resolved 1 package in 3ms
Prepared 1 package in 11ms
Installed 1 package in 22ms
 + mcp-gaodeweather-server==0.1.0 (from file:///C:/Users/yangyanxing/Desktop/uvtest/mcp-gaodeweather-server/dist/mcp_gaodeweather_server-0.1.0-py3-none-any.whl)
Installed 1 executable: mcp-gaodeweather-server.exe

>uv tool list
mcp-gaodeweather-server v0.1.0
- mcp-gaodeweather-server.exe
pycowsay v0.0.0.2
- pycowsay.exe

使用 uv tool install xxxx.whl 即可安装本地工具。使用 uv tool list 查看本地工具显示 mcp-gaodeweather-server.exe 已经安装好了。此时再使用 uvx mcp-gaodeweather-server 或者 uv tool run mcp-gaodeweather-server 即可运行该脚本了。

经过上面的几个步骤,我们基本上已经完成了一个极其简单的工具开发,如果我们将whl 发给别人,本地安装一下就可以使用了,但是在python 的世界里,还是需要将包上传到pypi 中供全世界的python 开发者使用。

使用 uv 上传到pypi 中

到 pypi 中注册账号,到 Account settings, 创建api token,scope 选择 Entire account(all projects),

记录一下这个pypi 开头的token,这个只显示一次。

之后使用 uv publish --token pypi-xxxxx 命令将项目上传到 pypi 中。

终于上传到pypi 了,pypi.org/project/mcp... 这样全世界的python 开发者都可以看到我们的代码了,虽然什么都用都没有。。。

由于我们没有对项目做任何修改,所以看上去什么都没有,这很不符合规范,应该写一些项目介绍来开发者明白项目是做什么的,怎么启动的。

pyproject.toml 中有很多配置选项,可以参考

hellowac.github.io/pypug-zh-cn...

我挑一些常用的进行编辑

编辑README.md 文件

bash 复制代码
## 介绍

这是一个使用高德地图的天气接口,获取当前城市天气的demo。

## 使用方法

## MCP 配置

### uvx
  
```json

{

  "mcpServers": {

    "duckduckgo": {

      "command": "uvx",

      "args": [

        "mcp-gaodeweather-server"

      ]

    }

  }

}

编辑 pyproject.toml 文件,

toml 复制代码
[project]

name = "mcp-gaodeweather-server"

version = "0.1.1"

description = "这是一个使用高德地图的天气接口,获取当前城市天气的demo"

readme = "README.md"

authors = [

    { name = "yangyanxing", email = "[email protected]" }

]

keywords= ["mcp", "gaodeweather", "server"]

requires-python = ">=3.11"

dependencies = []

  

[project.scripts]

mcp-gaodeweather-server = "mcp_gaodeweather_server:main"

  

[project.urls]

Homepage = "https://github.com/kevinkelin/mcp-gaodeweather-server"

Issues = "https://github.com/kevinkelin/mcp-gaodeweather-server/issues"

  

[build-system]

requires = ["hatchling"]

build-backend = "hatchling.build"

添加了 project.urls 配置,并写了一些描述,注意要提升一下版本号。

之后再运行 uv builduv publish --token xxxxx 将package 上传到pypi 中。

现在我们就可以在任何地方使用刚才编写的工具了。新创建一个项目。

bash 复制代码
# 先卸载之前安装的 mcp-gaodeweather-server
uv tool uninstall mcp-gaodeweather-server

# 安装 mcp-gaodeweather-server 工具
uv tool install mcp-gaodeweather-server

# 运行 
uv tool run mcp-gaodeweather-server

# 再卸载
uv tool uninstall mcp-gaodeweather-server

# 直接使用 uvx 运行

uvx mcp-gaodeweather-server 

直接使用 uvx mcp-gaodeweather-server 运行工具时,uv 如果发现本地没有这个工具,则会先从pypi 中下载,之后再运行这个工具,此时我们再任何地方使用我们编写的工具了。

总结

本文简单介绍了如何使用uv 来管理python 项目的创建和打包发布

  • uv python install 安装python
  • uv init xxxx 创建项目
  • uv venv 创建虚拟环境
  • uv add 下载第三方包
  • uv remove 卸载第三方包
  • uv pip 执行 pip 命令
  • uv run 执行脚本
  • uv tool run 或者 uvx 执行包中的script 命令,类似于npm run
  • uv build 打包
  • uv publish 发布

熟练使用uv 工具可以很方便的管理python 项目,之后我们再来学习MCP 服务的开发。

相关推荐
计算机-秋大田11 分钟前
基于Spring Boot的个性化商铺系统的设计与实现(LW+源码+讲解)
java·vue.js·spring boot·后端·课程设计
熬了夜的程序员16 分钟前
Go 语言封装邮件发送功能
开发语言·后端·golang·log4j
uhakadotcom17 分钟前
PostgreSQL 行级安全性(RLS)简介
后端·面试·github
rookie fish30 分钟前
websocket结合promise的通信协议
javascript·python·websocket·网络协议
Heorine31 分钟前
数学建模 绘图 图表 可视化(3)
python·数据可视化
2301_7644413338 分钟前
基于BERT的序列到序列(Seq2Seq)模型,生成文本摘要或标题
人工智能·python·深度学习·bert
小马爱打代码40 分钟前
Spring Boot - 动态编译 Java 类并实现热加载
spring boot·后端
网络风云1 小时前
Flask(二)项目结构与环境配置
后端·python·flask
Doker 多克1 小时前
Python Django系列—多数据库
python·django