将Mailgun邮件发送逻辑转为Python类后无法发送,疑与异步响应有关
问题分析与修复方案
核心问题点
- 异步函数未执行:
SendMail是异步函数,主脚本直接调用只会返回协程对象,不会实际执行发送逻辑。 - 邮件构建标记未更新:
BuildMail方法没有将self.built设为True,导致SendMail直接返回"Msg Not Built"。 - Base URL占位符未替换:
self.base_url中的{url}是占位符,需要替换为你的Mailgun实际域名(比如xxx.mailgun.org)。 - 异步客户端使用不当:
__MsgSend中重复使用async with client as C,会导致客户端被提前关闭,影响请求发送。
修正后的代码
Mail类代码
import httpx import asyncio class Mail: def __init__(self): # 替换{your-mailgun-domain}为实际域名,比如xxx.mailgun.org self.base_url = 'https://api.mailgun.net/v3/{your-mailgun-domain}' self.api_key = '{your-api-key}' # 替换为你的Mailgun API密钥 self.lstAttachment = [] self.built = False def BuildMail(self): self.build_request_kwargs = { "url": "/messages", "method": "POST", "data": { "from": "from@address.com", "to": ["to@address.com"], "subject": "Python E-mail Send", "html": "<p>Hello from Python</p>" }, "files": self.lstAttachment } # 标记邮件已构建完成 self.built = True async def SendMail(self): if not self.built: return 'Msg Not Built' # 正确使用异步客户端上下文管理器 async with httpx.AsyncClient(base_url=self.base_url, auth=("api", self.api_key)) as client: request = client.build_request(**self.build_request_kwargs) response = await client.send(request) response.raise_for_status() return response
主脚本代码
# 假设Mail类在M模块中 import M import asyncio async def main(): Email = M.Mail() Email.BuildMail() result = await Email.SendMail() print(result.status_code) print(result.json()) # 运行异步主函数 asyncio.run(main())
关键修复说明
- 执行异步函数:用
asyncio.run()包裹异步逻辑,确保协程被实际执行。 - 更新构建标记:在
BuildMail末尾添加self.built = True,让SendMail进入发送分支。 - 修正Base URL:替换占位符为真实的Mailgun域名,否则请求会指向错误地址。
- 简化客户端使用:在
SendMail中直接用async with创建并管理AsyncClient,避免重复上下文管理导致的问题。
内容的提问来源于stack exchange,提问作者J. Flood
相关产品推荐
相关产品推荐

