如何解决fastapi自定义响应类作为默认响应类
我正在尝试将自定义响应类用作default response。
from fastapi.responses import Response
from bson.json_util import dumps
class MongoResponse(Response):
def __init__(self,content,*args,**kwargs):
super().__init__(
content=dumps(content),media_type="application/json",**kwargs,)
当我明确使用响应类时,这很好用。
@app.get("/")
async def getDoc():
foo = client.get_database('foo')
result = await foo.bar.find_one({'author': 'fool'})
return MongoResponse(result)
但是,当我尝试将此参数作为参数传递给FastAPI构造函数时,似乎只在从请求处理程序返回数据时才使用它。
app = FastAPI(default_response_class=MongoResponse)
@app.get("/")
async def getDoc():
foo = client.get_database('foo')
result = await foo.bar.find_one({'author': 'fool'})
return result
当我查看下面的堆栈跟踪时,似乎它仍使用正常的默认响应json response。
ERROR: Exception in ASGI application
Traceback (most recent call last):
File "/home/blue/podman/test/.venv/lib/python3.6/site-packages/uvicorn/protocols/http/httptools_impl.py",line 390,in run_asgi
result = await app(self.scope,self.receive,self.send)
File "/home/blue/podman/test/.venv/lib/python3.6/site-packages/uvicorn/middleware/proxy_headers.py",line 45,in __call__
return await self.app(scope,receive,send)
File "/home/blue/podman/test/.venv/lib/python3.6/site-packages/fastapi/applications.py",line 181,in __call__
await super().__call__(scope,send) # pragma: no cover
File "/home/blue/podman/test/.venv/lib/python3.6/site-packages/starlette/applications.py",line 111,in __call__
await self.middleware_stack(scope,send)
File "/home/blue/podman/test/.venv/lib/python3.6/site-packages/starlette/middleware/errors.py",in __call__
raise exc from None
File "/home/blue/podman/test/.venv/lib/python3.6/site-packages/starlette/middleware/errors.py",line 159,in __call__
await self.app(scope,_send)
File "/home/blue/podman/test/.venv/lib/python3.6/site-packages/starlette/exceptions.py",line 82,in __call__
raise exc from None
File "/home/blue/podman/test/.venv/lib/python3.6/site-packages/starlette/exceptions.py",line 71,sender)
File "/home/blue/podman/test/.venv/lib/python3.6/site-packages/starlette/routing.py",line 566,in __call__
await route.handle(scope,send)
File "/home/blue/podman/test/.venv/lib/python3.6/site-packages/starlette/routing.py",line 227,in handle
await self.app(scope,line 41,in app
response = await func(request)
File "/home/blue/podman/test/.venv/lib/python3.6/site-packages/fastapi/routing.py",line 199,in app
is_coroutine=is_coroutine,File "/home/blue/podman/test/.venv/lib/python3.6/site-packages/fastapi/routing.py",line 122,in serialize_response
return jsonable_encoder(response_content)
File "/home/blue/podman/test/.venv/lib/python3.6/site-packages/fastapi/encoders.py",line 94,in jsonable_encoder
sqlalchemy_safe=sqlalchemy_safe,File "/home/blue/podman/test/.venv/lib/python3.6/site-packages/fastapi/encoders.py",line 139,in jsonable_encoder
raise ValueError(errors)
ValueError: [TypeError("'ObjectId' object is not iterable",),TypeError('vars() argument must have __dict__ attribute',)]
解决方法
因此,事实证明,默认响应类以及路由上的响应类仅适用于开放API文档。默认情况下,文档将记录每个端点,就像它们将返回json一样。
因此,在下面的示例代码中,每个响应都将被标记为内容类型text / html。 在第二次溃败中,这被application / json覆盖
app = FastAPI(default_response_class=HTMLResponse)
@app.get("/")
async def getDoc():
foo = client.get_database('foo')
result = await foo.bar.find_one({'author': 'Mike'})
return MongoResponse(result)
@app.get("/other",response_class=JSONResponse)
async def json():
return {"json": "true"}
从这种意义上讲,我可能应该显式使用我的类,并将默认响应类保留为JSON,以便将它们记录为JSON响应。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。