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

使用FastAPI-Mail发送多邮箱时触发邮箱格式无效错误

使用fastapi-mail多邮箱发送报错:not a valid email address

问题详情

用fastapi-mail实现多邮箱多文件发送,单邮箱发送正常,但把邮箱参数改为List[EmailStr]后,触发not a valid email address错误。

错误信息

not a valid email address

相关代码

from fastapi import FastAPI, BackgroundTasks, Form, File, UploadFile
from fastapi.responses import JSONResponse
from pydantic import EmailStr
from fastapi_mail import MessageSchema, FastMail, ConnectionConfig
from typing import List, Optional

# 假设res是读取配置的函数
def res(key):
    # 示例配置,实际替换为你的配置读取逻辑
    config = {
        "MAIL_USERNAME": "your_username",
        "MAIL_PASSWORD": "your_password",
        "MAIL_PORT": 587,
        "MAIL_SERVER": "smtp.example.com",
        "MAIL_TLS": True,
        "MAIL_SSL": False,
        "USE_CREDENTIALS": True,
        "VALIDATE_CERTS": True
    }
    return config.get(key)

app = FastAPI()

@app.post("/file")
async def send_file(
    background_tasks: BackgroundTasks,
    email: List[EmailStr] = Form(...),  # 此处从单个EmailStr改为List[EmailStr]
    file: Optional[List[UploadFile]] = File(...),
) -> JSONResponse:
    print(email)
    print(file)
    message = MessageSchema(
        subject="Fastapi mail module",
        recipients=email,
        body="Simple background task",
        subtype="html",
        attachments=file
    )
    fm = FastMail(ConnectionConfig(
        MAIL_USERNAME=res("MAIL_USERNAME"),
        MAIL_PASSWORD=res("MAIL_PASSWORD"),
        MAIL_FROM="admin@acsebs.com",
        MAIL_PORT=res("MAIL_PORT"),
        MAIL_SERVER=res("MAIL_SERVER"),
        MAIL_FROM_NAME="send attachment email service",
        MAIL_TLS=res("MAIL_TLS"),
        MAIL_SSL=res("MAIL_SSL"),
        USE_CREDENTIALS=res("USE_CREDENTIALS"),
        VALIDATE_CERTS=res("VALIDATE_CERTS")
    ))
    background_tasks.add_task(fm.send_message, message)
    return JSONResponse(status_code=200, content={"message": "email has been sent"})

提交与错误截图

  • Swagger UI提交数据界面:
    Swagger UI提交多个邮箱的界面
  • 错误提示界面:
    邮箱格式错误提示

解决方案

原因分析

FastAPI中List[EmailStr] = Form(...)期望前端提交多个同名的email参数(比如email=a@test.com&email=b@test.com),但你在Swagger UI的单个输入框里用逗号分隔多个邮箱,会被解析成一个字符串,无法通过EmailStr的格式验证,从而报错。

两种解决方式

方式1:保留List[EmailStr]参数,正确提交

在Swagger UI中,点击email字段旁的Add string按钮,添加多个输入框,每个输入框填写一个单独的邮箱地址,再提交即可。这种方式符合FastAPI对表单List参数的解析规则,无需修改代码。

方式2:支持逗号分隔的邮箱输入

如果希望用户在单个输入框用逗号分隔多个邮箱,需要修改代码手动处理:

  1. 将邮箱参数改为str类型
  2. 分割字符串并逐个验证邮箱格式

修改后的核心代码:

from pydantic import validate_email, ValidationError

@app.post("/file")
async def send_file(
    background_tasks: BackgroundTasks,
    email: str = Form(...),  # 改为str类型
    file: Optional[List[UploadFile]] = File(...),
) -> JSONResponse:
    try:
        # 分割并去除空白字符
        email_list = [e.strip() for e in email.split(",") if e.strip()]
        # 逐个验证邮箱格式
        for e in email_list:
            validate_email(e)
    except ValidationError:
        return JSONResponse(status_code=400, content={"message": "无效的邮箱地址"})
    
    # 后续逻辑不变
    message = MessageSchema(
        subject="Fastapi mail module",
        recipients=email_list,
        body="Simple background task",
        subtype="html",
        attachments=file
    )
    fm = FastMail(ConnectionConfig(...))  # 配置部分不变
    background_tasks.add_task(fm.send_message, message)
    return JSONResponse(status_code=200, content={"message": "email has been sent"})

额外验证

确认fastapi-mail的MessageSchema的recipients参数支持List[str]或List[EmailStr](从官方文档来看是支持的,因为单邮箱场景下EmailStr可以正常传入)。


内容的提问来源于stack exchange,提问作者samuel.situmorang

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 18:35:27