• fastapi自定义中间处理过程


    自定义中间件-Middleware

    在FastAPI应用中使用中间件。中间件实际上是一个函数,在每个request处理之前被调用,同时又在每个response返回之前被调用。

    1. 首先接收访问过来的request。
    2. 然后针对request或其他功能执行自定义逻辑。
    3. 传递request给应用程序继续处理。
    4. 接收应用所产生的response。
    5. 然后针对response或其他功能执行自定义逻辑。
    6. 返回response。

    详细说明可看官方文档:https://fastapi.tiangolo.com/tutorial/middleware/?h=middleware

    下面是无敌哥pity平台代码,详细可看git仓库(https://github.com/wuranxu/pity)

    asyncdef set_body(request: Request, body: bytes):
    asyncdef receive() -> Message:
    return {"type": "http.request", "body": body}

    request._receive = receive


    asyncdef get_body(request: Request) -> bytes:
    body = await request.body()
    await set_body(request, body)
    return body


    @pity.middleware("http")
    asyncdef errors_handling(request: Request, call_next):
    body = await request.body()
    try:
    await set_body(request, await request.body())
    returnawait call_next(request)
    except Exception as exc:
    return JSONResponse(
    status_code=status.HTTP_200_OK,
    content=jsonable_encoder({
    "code": 110,
    "msg": str(exc),
    "request_data": body,
    })
    )

    参考issues:https://github.com/tiangolo/fastapi/issues/394 https://stackoverflow.com/questions/61358669/raise-exception-in-python-fastapi-middleware

    自定义路由类-APIRoute

    在某些情况下,您可能希望覆盖Request和APIRoute类使用的逻辑。特别是,这可能是中间件中逻辑的一个很好的替代方案。例如,如果您想在应用程序处理请求正文之前读取或操作请求正文。详细说明可看官方文档:https://fastapi.tiangolo.com/advanced/custom-request-and-route

    class ErrorRouter(APIRoute):
    def get_route_handler(self) -> Callable:
    original_route_handler = super().get_route_handler()

    asyncdef custom_route_handler(request: Request) -> Union[Response]:
    try:
    returnawait original_route_handler(request)
    except Exception as exc:
    log_msg = f"造数平台捕获到系统错误:请求路径:{request.url.path}\n"
    params = request.query_params
    if params:
    log_msg += f"路径参数:{params}\n"
    boby = await request.body()
    if boby:
    body = json.dumps(json.loads(boby),ensure_ascii=False)
    log_msg +=f"请求参数:{body}\n"
    if isinstance(exc, NormalException):
    return JSONResponse(
    status_code=status.HTTP_200_OK,
    content={
    "responseCode": Status.SYSTEM_EXCEPTION.get_code(),
    "responseMsg": exc.errorMsg
    },
    )
    elif isinstance(exc, RequestValidationError):
    message = ""
    for error in exc.errors():
    message += str(error.get('loc')[-1]) + ":" + str(error.get("msg")) + ","
    return JSONResponse(
    status_code=status.HTTP_200_OK,
    content=jsonable_encoder({
    "responseCode": Status.PARAM_ILLEGAL.get_code(),
    "responseMsg": Status.PARAM_ILLEGAL.get_msg() + message[:-1]
    })
    )
    log_msg +=f"错误信息:{str(exc.args[0])}"
    mylog.error(log_msg)
    if PlatConfig.SWITCH == 1:
    WeGroupChatBot.send_text(log_msg)
    return JSONResponse(
    status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
    content=jsonable_encoder({
    "responseCode": Status.FAIL.get_code(),
    "responseMsg": Status.FAIL.get_msg(),
    "errorMsg":str(exc.args[0])
    },
    ))
    return custom_route_handler

    def APIRouter():
    router = AppRouter()
    router.route_class = ErrorRouter
    return router

    统一处理之后,再通过类型判断Exception,返回不同的Response~ 

    注意:用了自定义错误路由,就不能再用 「@app.exception_handler」否则会重复捕获!!!

    参考issues:https://github.com/tiangolo/fastapi/issues/1216 https://github.com/tiangolo/fastapi/issues/2750

  • 相关阅读:
    【JAVASCRIPT】JS实现淘宝,百度评分功能
    【数据结构】链式线性表的几种常用用法
    【JAVASCRIPT】无刷新评论
    【JAVASCRIPT】表单序列化问题
    【JAVASCRIPT】如何不使用jquery函数和ajax框架实现ajax效果
    图灵北京作译者交流会
    是起点,而非终点——评《程序员的思维修炼》
    2011图灵新春特献
    图灵2011.01书讯
    图灵2010.12书讯
  • 原文地址:https://www.cnblogs.com/hushaojun/p/16529849.html
Copyright © 2020-2023  润新知