![](/img/trans.png)
[英]python flask-restful cannot get app access in resource class
[英]flask-restful - resource class for current request
問題
我所有應用程序的路由都是通過flask-restful Resources定義的。 如何找到處理當前請求的資源對象/類?
為什么我想要這個
我想記錄處理請求時引發的所有異常。 我連接到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)
編輯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)
一旦通過信號調用了日志記錄方法,我找不到一種很好的方式來訪問您的對象。
如果您願意處理所有可能的情況,您可以創建自己的自定義異常,在您的類上調用log_data方法。
相反,我選擇在基類中處理自己的日志。 簡單的例子,我剛剛使用了打印功能,但你可以調用app.logging.info。
from flask import Flask, request
import flask_restful
app = Flask(__name__)
api = flask_restful.Api(app)
class MyCustomResource(flask_restful.Resource):
def get(self):
try:
self.my_get()
except Exception as exception:
# Will catch all errors in your subclass my_get method
print("exception caught")
print(request.url)
print(type(exception).__name__)
print(self.log_data())
# Re-raise if you want (or not)
raise exception
def my_get(self):
# Python equivalent of virtual method
raise NotImplementedError()
def log_data(self):
# Python equivalent of virtual method
raise NotImplementedError()
class SomeResource(MyCustomResource):
def my_get(self):
# Example unknown error occurs here
raise Exception("error!")
return "some data"
def log_data(self):
# Called by parent
return "some logging data for the object"
api.add_resource(SomeResource, "/")
如果你想更深入地了解燒瓶的源代碼,你也可以使用任何方法調用get / post來修補補丁(或構建自己的包)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.