首页 > 解决方案 > 有没有办法手动处理 FastAPI 中变量验证的异常

问题描述

嘿,我在自己的项目中使用 FastAPI,这是我第一次使用它。我想知道当我收到的数据与我正在等待的类型不匹配时,我是否有办法手动处理异常。

这是一个例子:

async def create_user(password: str = Form("password"), username: str = Form("username"), email: str = Form("email"), pseudo: str = Form("pseudo")):
    conn.execute(user.insert().values(
        username=username,
        email=email,
        password=password,
        pseudo=pseudo
    ))
    return conn.execute(user.select()).fetchall()

例如,当此路由收到一个 int 的用户名时,我想返回一个 400 错误和一条个人消息。技术上不应该,但无论如何我想自己处理它,它可能对其他错误处理情况很有用。

我还没有在我的研究中找到它,这就是我在这里问的原因。感谢帮助 !

标签: pythonfastapi

解决方案


FastAPI 是用 Pydantic 构建的,用于这些类型的验证。我可以想到两种方法:

  • (a)typing.Any用于接受任何输入,并在函数中自己验证输入——HTTPException根据需要引发任何输入。

    from typing import Any
    from fastapi import HTTPException
    
    # @app. ....
    async def create_user(password: str = Form("password"), username: Any = Form("username"), email: str = Form("email"), pseudo: str = Form("pseudo")):
    
        if not isinstance(username, str) or (isistance(username, str) and username.isdigit()):
            raise HTTPException(status_code=400, detail="Must be a string.") 
    
        conn.execute(user.insert().values(
            username=username,
            email=email,
            password=password,
            pseudo=pseudo
        ))
        return conn.execute(user.select()).fetchall()
    
  • (b) 将str输入作为默认值,并检查您要查找的内容。

    from fastapi import HTTPException
    
    # @app. ....
    async def create_user(password: str = Form("password"), username: str = Form("username"), email: str = Form("email"), pseudo: str = Form("pseudo")):
    
        # Assuming you have a proper html form setup in the front-end the expected
        # input to this endpoint will always be a string. If somehow the user sends
        # a request without the form (say with Postman), then Pydantic will be the 
        # one that will catch the error (via 422 error) and not the code below.
        if username.isdigit():
            raise HTTPException(status_code=400, detail="Must be a string.") 
    
        conn.execute(user.insert().values(
            username=username,
            email=email,
            password=password,
            pseudo=pseudo
        ))
        return conn.execute(user.select()).fetchall()
    

无论哪种情况,我认为值得一提的是,FastAPI 的全部意义在于通过 Pyndatic 进行自动验证。如果您打算手动对所有内容进行验证,则最好使用Starlette 之类的东西,它可以让您更好地控制数据流,但代价是没有内置数据验证器。


推荐阅读