- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我的路线:
@router.get('/check/{value}', status_code=200)
def ranks_check(value: BasicInput = Depends()):
"""
Test endpoint
"""
return value
我的模型:
class BasicInput:
"""
Get Confidence to score Input class
"""
value: int
@validator('value')
def check_if_value_in_range(cls, v):
if not 0 < v < 1000001:
raise ValueError('Value Exceeded Limit')
我需要做的:
我需要验证输入并在出现 ValueError 时引发 HTTP 400。
我知道我可以使用 Pydantic 的 Field
类型完成整数验证,并在路由函数本身中运行 check_if_value_in_range
。我正在寻找使用该模型的解决方案。
最佳答案
请参阅 Raise an HTTPException in your code 上的 FastAPI 文档:
HTTPException
is a normal Python exception with additional data relevant for APIs.Because it's a Python exception, you don't
return
it, youraise
it.This also means that if you are inside a utility function that you are calling inside of your path operation function, and you raise the
HTTPException
from inside of that utility function, it won't run the rest of the code in the path operation function, it will terminate that request right away and send the HTTP error from theHTTPException
to the client.
from fastapi.exceptions import HTTPException
class BasicInput(BaseModel):
value: int
@validator("value")
def check_if_value_in_range(cls, v):
if not 0 < v < 1000001:
# raise ValueError("Value Exceeded Limit")
raise HTTPException(status_code=400, detail="value exceeded limit")
return v
$ curl -i -XGET localhost:8000/check/1000002
HTTP/1.1 400 Bad Request
...
{"detail":"value exceeded limit"}
$ curl -i -XGET localhost:8000/check/42
HTTP/1.1 200 OK
...
{"value":42}
但要使其正常工作,您当前的代码中有一些问题需要修复:
如果您使用 Pydantic 的 validator装饰器,那么你的类需要是 Pydantic BaseModel
或 a Pydantic dataclass
.
class BasicInput(BaseModel): # <--------------------
value: int
如果您还在 validator
函数上添加 print
语句或断点,您会看到它实际上从未被调用,因为它不是 Pydantic BaseModel
。
if
条件为 False
时验证器函数缺少处理(当 v
在范围内有效时).来自 Pydantic 文档:
validators should either return the parsed value or raise a
ValueError
,TypeError
, orAssertionError
(assert
statements may be used).
class BasicInput(BaseModel):
value: int
@validator("value")
def check_if_value_in_range(cls, v):
if not 0 < v < 1000001:
raise ValueError("Value Exceeded Limit")
# v is good
return v # <--------------------
在您的原始代码中,您 mentioned that you were getting "nothing" .我假设您得到的是针对有效和无效 value
的空 {}
响应:
$ curl -XGET localhost:8000/check/42
{}
$ curl -XGET localhost:8000/check/1000002
{}
这是因为在路由函数中,value
是BasicInput
类,不是{value}
路径值或者BasicInput.value
整数值。
@router.get("/check/{value}", status_code=200)
def ranks_check(value: BasicInput = Depends()):
print(type(value)) # <class 'main.BasicInput'>
return value
您实际上得到的“空”响应是 FastAPI 应用其 jsonable_encoder 的结果到 BasicInput
类。当 FastAPI 到达您的路由函数的 返回值
时,它将使用 jsonable_encoder
将其转换为 JSONResponse
。请参阅 Return a Response Directly 上的文档.
在内部,由于 BasicInput
不是 Pydantic BaseModel
或可迭代对象(例如 dict
类对象),它会产生一个空字典 {}
。 (您可以检查 code for jsonable_encoder
,但这是因为 dict(obj)
和 vars(obj)
)。
因此,如 MatsLindh's answer 中所述,FastAPI 请求/响应上下文中使用的模型通常是 Pydantic BaseModel
的子类,在正确地对其进行子类化之后,您现在应该得到非空响应:
$ curl -XGET localhost:8000/check/42
{"value":42}
$ curl -XGET localhost:8000/check/1000002
Internal Server Error
...
pydantic.error_wrappers.ValidationError: 1 validation error for BasicInput
value
Value Exceeded Limit (type=value_error)
修复后,只需按照 FastAPI 的 Raise an HTTPException in your code 中的指南进行操作即可(正如我在此答案开头提到的)直接从模型中引发 HTTP 错误。
但我同意 MatsLindh's comment ,这不是一个“好的”做法,因为它违反了SRP/Single Responsibility Principle .您的模型正在做两件事:验证您的输入和引发适当的 HTTP 错误响应。
FastAPI 应该处理您的请求和响应,而 Pydantic 应该代表您的模型和数据。您让 FastAPI 接受请求,将其传递给 Pydantic 以验证和存储模型数据,然后让 FastAPI 将结果转换为适当的响应。您的预期解决方案也令人困惑,因为对于有效/成功案例,它是在路由函数中处理的,但对于无效/错误案例,它是在模型验证函数中处理的。
FastAPI 已经知道如何捕获 Pydantic ValidationError
并将它们转换为适当的 HTTP 错误响应。在这种情况下,FastAPI 返回 HTTP 500 内部服务器错误。
如果目的是提供特定于模型的错误响应,您应该在模型上保留 raise ValueError
,然后覆盖 FastAPI 的默认验证错误处理程序。请参阅有关 Override the default exception handlers 的部分.
这是我推荐的代码:
from fastapi import APIRouter, Depends, FastAPI
from fastapi.exceptions import ValidationError
from fastapi.responses import JSONResponse
from pydantic import BaseModel, validator
# MODELS
class BasicInput(BaseModel):
value: int
@validator("value")
def check_if_value_in_range(cls, v):
if not 0 < v < 1000001:
raise ValueError("Value Exceeded Limit")
return v
# VIEWS
api = FastAPI()
router = APIRouter()
@api.exception_handler(ValidationError)
async def validation_exception_handler(request, exc: ValidationError):
return JSONResponse(status_code=400, content={"error": str(exc)})
@router.get("/check/{value}")
def ranks_check(value: BasicInput = Depends()):
return value
api.include_router(router)
$ curl -i -XGET localhost:8000/check/42
HTTP/1.1 200 OK
...
{"value":42}
$ curl -i -XGET localhost:8000/check/1000002
HTTP/1.1 400 Bad Request
...
{"error":"1 validation error for BasicInput\nvalue\n Value Exceeded Limit (type=value_error)"}
关于python - 如何在模型中引发 HTTP 400?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68770979/
我正在使用 SharePoint Online 并使用 Windows Azure 托管访问 SPO 的进程。 我们已将启动任务添加到 Azure 角色以安装 http://www.microsoft
我有一个函数,它获取包含时间的源文件(csv 文件),读取它,然后按顺序对行进行排序并将它们写入目标文件中。但是,如果源 csv 文件不存在,我需要引发 FileNotFoundError。我之前曾引
我试图在目录不存在时引发错误,然后再打开该目录中的文件。根据this response我应该为我的问题使用最具体的异常构造函数,我认为它是 NotADirectoryError。但是运行下面的代码我得
在编码/开发生命的一天或另一天,我们确实遇到了这个特殊的情况,这是最常见的异常(exception)之一。我的问题是关于的而不是。为什么(我知道当我们尝试访问实际上指向null的引用变量的属性时会引发
我想知道在 python 中是否可以在一个 except block 中引发异常并在稍后的 except block 中捕获它。我相信其他一些语言默认会这样做。 这是它的样子" try: som
我有以下代码: br = mechanize.Browser() br._factory.is_html = True br.form = mechanize._form.ParseString(''
我刚刚发现,如果您有一个引发 TOO_MANY_ROWS 异常的 SELECT INTO,该变量仍会从查询检索到的第一条记录中分配值。这是预期的行为吗? 这是我的例子: for co in my_cu
当 SSH 显示 WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! 我知道当您重新安装远程服务器时会发生这种情况,但我尝试列出 其他原因 . 我知道如何
我有一个枚举和一个 EnumMap . 我将 map 放入一个类中以隐藏“字节”值。所以我有一个set(Parameter, int)和set(Parameter, boolean)方法。 publi
在什么情况下会redis-py引发以下 AttributeError 异常? redis-py 不是设计来引发仅基于 redis.exceptions.RedisError 的异常吗? 什么是合理的处
可悲的是,对此异常的引用通常具有异国情调,并且可能发生在您例如通过 Assembly.GetTypes() 枚举类型- 举个例子,它发生在我们的一个部署上,但同一组程序集在集成服务器上运行良好。 为了
我正在为 Android 下的特定平板电脑克隆一个存储库并获取源代码,我必须执行一个 python 脚本。当我执行它时,我收到此错误消息: Traceback (most recent call la
首先,执行此操作(在运行 4.4.2 的 Nexus 5 上测试): 将 PRIORITY_LOW 通知传递给 Service.startForeground()。 观察通知不显示在状态栏中。 使用相
我尝试使用 AppEngine 的 python 模块 api 来获取使用基本缩放的模块的实例数。在我模块的 yaml 文件中,我明确设置了 max_instances 参数。我希望 get_num_
当我如下运行我的 spark python 代码时: import pyspark conf = (pyspark.SparkConf() .setMaster("local")
在我的系统上,一段适用于 Python 2 的代码不适用于 Python 3。 f = open("plotwidget.svg") svgData = f.read() xml_stream = Q
我是 PHP 和 SQL 的新手,但我正在创建一个登录系统。我遇到的问题是: You have an error in your SQL syntax; check the manual that c
我有一个使用 ebaysdk 库的 python 代码,当我运行代码并输入关键字进行搜索时,我得到了这个错误。 Traceback (most recent call last): File "eba
当我将表单数据发送到我的 Flask 应用程序时,出现以下错误。它说它将使用 UTF-8 编码,但语言环境已经是 UTF-8。这个错误是什么意思? /home/.virtualenvs/project
在python2.7中,跟随pympler example : from anotherfile import somefunction, somecustomclass from os import
我是一名优秀的程序员,十分优秀!