别让你的SSE MCP服务卡住!一行 requests.post 引发的性能危机
问题出现
在使用 Python 开发基于 MCP 的 SSE 服务时,如果不小心写了同步阻塞的代码,就非常容易踩进 IO 阻塞的大坑。来看下面这段示例代码:
在使用 Python 开发基于 MCP 的 SSE 服务时,如果不小心写了同步阻塞的代码,就非常容易踩进 IO 阻塞的大坑。来看下面这段示例代码:
在使用 UV 进行软件包管理和 Python 安装时,由于网络环境的限制,国内用户通常需要设置代理或镜像来加速下载过程。本文将详细介绍如何在不同场景下设置国内加速镜像。
在使用 uv add
命令安装第三方包时,有两种方法可以设置国内加速镜像:
今天我们来聊一个使用 uv 工具进行python 项目管理时会遇到的包版本的问题。
当我们从远程仓库下载以个新的项目时,有了uv 工具,可以使用 uv sync
来一键同步项目开发的python 环境和第三方库,但是我们想象一个问题,如果项目在最早开发或者首次开发时,如使用 uv add mcp
安装了当时的最新版,此时,在pyproject.toml 文件记录的包版本为 "mcp>=1.6.0"
之后过了好久,这个包在pypi 中也更新了,如更新到 "1.7.0",那么当再次使用 uv sync
时,是安装 1.6.0 版本还是 1.7.0 版本呢?
今天给大家分享一个Python中非常容易踩坑的特性——类属性中默认值为可变对象(比如列表)时的诡异行为。
我们先看一个简单的Person
类定义:
看起来很正常对吧?我们创建一个Person
实例时,如果没有提供frients
参数,就会默认使用空列表。
前面文章我们使用python 实现了简单的天气查询mcp server,并使用cherry studio 和 Cline 实现了mcp server 的调用,之前是使用stdio 类型的mcp,本章看一下如何开发sse类型的mcp 服务。
sse,Server-Sent Events 是基于http 长连接的服务,以往我们在开发大模型应用的时候,由于大模型生成token 不是一次性生成的,是一个token 一个token 生成的,为了避免调用端长时间等待,会一点点的输出给调用端。
在mcp 的开发过程中,也会用到sse,但是这里的sse 和大模型输出稍微有一点不同,sse 类型的mcp 会建立一个http 监听端口,客户端在调用mcp server 时,先和mcp 建立一个长连接,之后工具的输出都是通过这个长连接发送给客户端,由于sse是单向传输,客户端只能被动的接受服务端的数据,而不能在建立连接以后再次接收客户端的数据,所以客户端在调用mcp 工具时,需要向另外一个接口发送数据。所以开发sse 的mcp 会稍微复杂一些,但是官方python sdk 中FastMCP已经做了高级封装,开发者只需要关注工具的具体实现即可。
本地stdio 类型的mcp server,通过标准的输入输出来进行数据的交互,调用端需要提前安装好环境,如python 或者 node,当然如果mcp 是一个可执行的二进制文件也可以不用安装配置环境,只是目前大部分的mcp 使用python 或者 node 进行开发的。
上一篇文章介绍了UV工具的使用,有了uv 的基础,本篇我们来看一下如何使用python开发mcp server,目前主流的 mcp 分为 stdio 和 sse,stdio 为标准输入输出,通过调用工具获取工具的输出来交互,比如你在终端输入 ping host 命令,返回ping host 的输出,SSE 稍微复杂一些,通过http 接口,返回一个sse长连接,之后工具调用输入输出遵循JSONRPC规范,通过http 调用,但是结果通过SSE长连接返回,实现起来稍微复杂一些,但是调用工具和工具配置sse会更简单一些,本篇先介绍开发简单的 stdio 类型的 mcp server。工具为调用高德地图的天气查询接口返回某地的天气情况。
最近在进行MCP server 的开发,目前主流的 mcp server 主要以node 和python 为主,其中python 主要以uv 来启动服务的,我也是由此才开始接触uv,uv 工具可以管理本地的python 版本,虚拟环境以及打包发布,还可以运行脚本,作为mcp 开发的前序基础,本文主要记录以下使用uv 开发管理python 应用的各个环节。之后在进行mcp 开发时会一直使用uv 来管理环境。
在python的整体生态中,虽然已经有很多库支持了异步调用,如可以使用httpx或者aiohttp代替requests库发起http请求,使用asyncio.sleep 代替time.sleep, 但是依然还有很多优秀的第三方库是不支持异步调用也没有可代替的库,那么如何在FastAPI中调用这种没有实现异步的库但是又不阻塞整个系统呢?
今年随着ChatGPT的爆火,也带火了一种前后端数据通信模式,使用SSE,可以让服务端一边生成内容,一边将数据返回给客户端,这样客户端可以不用等待服务端将内容全部生成。本文介绍如何在FastAPI中使用这种SSE方式返回数据,并且使用requests和aiohttp这两个第三方库调用这种SSE接口并且展示数据。
我们都知道,在java中有接口(interface)的概念,类可以实现多个接口,但是必须要实现所有接口中的方法,但是在python 中并没有接口的概念,类可以通过多继承的方式继承自多个类,现在如果我们想要实现在java中的接口的效果,强制要求子类必须实现一些方法,该如何操作呢?