You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FastAPI调用同步Twilio Client时服务器无响应问题排查

FastAPI中调用Twilio同步客户端导致服务器挂起的问题

我有一个FastAPI应用,其中某个端点调用Twilio同步客户端发送短信时出现异常:调用后服务器直接挂起/冻结,永远不会超时;此时修改代码,重载器也会跟着冻结(推测是服务器无响应导致)。无论该路由用同步还是异步函数定义,都会触发这个问题,但其他同步、异步路由目前测试下来都能正常工作。

单独写了一个极简Python文件,仅构造Twilio客户端并发送消息,测试完全正常,排除Twilio服务本身的问题。

环境版本

fastapi==0.104.1
twilio==8.2.0
uvicorn==0.23.2
starlette==0.27.0

本地运行方式

直接通过代码启动或命令行调用uvicorn:

if __name__ == '__main__':
    uvicorn.run('app:app', reload=True, port=5002)

路由采用单独文件定义,在应用构建阶段通过app.include_router(<路由实例>)引入到主应用中。

封装的Twilio客户端代码

from twilio.rest import Client
# ... 获取环境变量(account_sid、auth_token、messaging_service_sid)

class TwilioAPI:
    def __init__(self, phone_number: str):
        self.client = Client(account_sid, auth_token)
        self.phone_number = phone_number

    def send_sms(self, body: str):
        # 能进入该函数,但永远不会返回
        message = self.client.messages.create(
            messaging_service_sid=messaging_service_sid,
            body=body,
            to=self.phone_number,
        )
        return message.sid

问题路由代码

@router.post("/endpoint")
def send_message_or_whatever(input: Input):
    # ... 从input获取数据,构造消息
    # ... 此处调用数据库,可正常工作
    twilio_api_client = CreateAnInstanceOfOurTwilioClient()
    twilio_api_client.send_sms(message)  # <--- 在此处卡住
    return stuff

Twilio官方博客示例代码

@router.post('/endpoint')
async def do_something():
    client = twilio.rest.Client() # 同步客户端
    client.messages.create(...创建消息参数)

已尝试的解决方法

  • 使用同步、异步两种路径定义:同步函数中等待Twilio响应理论上不应有问题(其他网络调用如数据库查询正常),且该客户端不返回需要await的future;异步定义也无效。
  • 在异步路由中尝试await asyncio.get_event_loop().run_in_executor(...),无效果。
  • 使用FastAPI的Background Task,仍然在client.messages.create处卡住(推测该任务是asyncio.to_thread或run_in_executor的封装)。

疑问

我到底哪里出错了?

附:我了解Twilio Client的AsyncHTTPClient,但主要想弄清楚当前同步调用无法工作的原因。

内容的提问来源于stack exchange,提问作者msmedes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 21:23:22