python - flask-restful - 当前请求的资源类

标签 python flask flask-restful

问题

我的应用程序的所有路由都是通过 flask-restful 资源定义的。 如何找到正在处理当前请求的资源对象/类?

我为什么要这个

我想记录处理请求时引发的所有异常。我连接到 flask.got_request_exception,如 http://flask.pocoo.org/docs/1.0/api/#signals 中所述像这样的东西效果很好:

from flask import got_request_exception, request

def log_exception(sender, exception, **extra):
    logger.info("URL: {}, Exception: {}".format(request.url, type(exception).__name__))

got_request_exception.connect(log_exception, app)

唯一的问题是我想记录一些请求数据,但不是所有数据——例如我想隐藏密码。我认为将日志记录数据逻辑与请求处理逻辑结合在一起是个好主意,如下所示:

from flask import request
import flask_restful

class SomeResource(flask_restful.Resource):
    def get(self):
        # ... GET processing
    def log_data(self):
        # log all body params
        return request.get_json()

class Login(flask_restful.Resource):
   def post(self):
       # ... authentication
   def log_data(self):
       # log selected body params
       return {'login': request.get_json()['login'], 'password': 'HIDDEN!'}

然后在我的 log_exception 中使用它:

from flask import got_request_exception, request

def log_exception(sender, exception, **extra):
    resource_class = # THIS IS THE THING I'M MISSING
    logger.info("URL: {}, Exception: {}, Data: {}".format(request.url, type(exception).__name__), 
                resource_class.log_data())

got_request_exception.connect(log_exception, app) 

但也许这应该以其他方式完成?

最佳答案

与其继承自 flask_restful.Resource,不如继承自定义资源

class MyResource(flask_restful.Resource):
    def dispatch_request(self, *args, **kwargs):
        try:
            return super(MyResource,self).dispatch_request(*args, **kwargs)
        except Exception as ex:
            setattr(ex, "_raised_by", self)
            raise ex

然后你就可以使用异常处理器了

def log_exception(sender, exception, **extra):
    _raised_by = getattr(exception, "_raised_by", None)
    if _raised_by:
        print(_raised_by)
    property("URL: {}, Exception: {}".format(request.url, type(exception).__name__))

这是我试过的完整代码

from flask import request, Flask
import flask_restful

app = Flask(__name__)

api = flask_restful.Api(app)


class MyResource(flask_restful.Resource):
    def dispatch_request(self, *args, **kwargs):
        try:
            return super(MyResource,self).dispatch_request(*args, **kwargs)
        except Exception as ex:
            setattr(ex, "_raised_by", self)
            raise ex

# MyResource = flask_restful.Resource

class SomeResource(MyResource):
    def get(self):
        raise Exception("Not implemented")

    def log_data(self):
        # log all body params
        return request.get_json()


class Login(MyResource):
    def post(self):
        raise Exception("Not implemented")

    def log_data(self):
        # log selected body params
        return {'login': request.get_json()['login'], 'password': 'HIDDEN!'}


from flask import got_request_exception, request

api.add_resource(Login, '/login')
api.add_resource(SomeResource, '/some')


def log_exception(sender, exception, **extra):
    _raised_by = getattr(exception, "_raised_by", None)
    if _raised_by:
        print(_raised_by)
    property("URL: {}, Exception: {}".format(request.url, type(exception).__name__))


got_request_exception.connect(log_exception, app)

if __name__ == '__main__':
    app.run(debug=True)

Edit-1:8 月 5 日

正如@jbet 所评论的,如果有人想要获得处理类,一个更简洁的选择是使用如下所示的 MyResource

from flask import g

class MyResource(flask_restful.Resource):
    def dispatch_request(self, *args, **kwargs):
        g.processed_by = self
        return super(MyResource,self).dispatch_request(*args, **kwargs)

关于python - flask-restful - 当前请求的资源类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56647911/

相关文章:

python - Heroku 上的 TCP/IP 套接字

python - 如何判断 Pyramid/python 是否加载了正确的 .egg?

python - 使线性回归更紧凑(python)

python - Flask:在网站而不是控制台上显示打印?

python-3.x - 让 Flask 使用 Python3 (Apache/mod_wsgi)

python - 如何使用 python Flask 将修改后的图像直接上传到 s3 存储桶

python - Postman、Python 并将图像和元数据传递到 Web 服务

python - Flask 请求返回 404 未找到

python setup.py sdist 错误 : Operation not permitted

ios - 如何在 Swift 4 中通过 POST 请求发送图像?