Python/Pyramid - 在引发 HTTP 异常时用额外数据包装 Cornice 响应
Python/Pyramid - Wrapping Cornice response with extra data when raising HTTP Exception
我正在使用 Pyramid and Cornice 编写一些 RESTful Python 应用程序,我制作了一个简单的 Cornice resource
:
@resource(collection_path='/users/', path='/users/{id}')
class UsersResource(object):
def __init__(self, request):
self.request = request
@view(renderer='json', content_type=content_type)
@my_wrapper
def get(self):
return {'user_id': self.request.matchdict['id']}
您可能已经注意到,除了 Cornice 的 view
装饰器之外,我还在此处添加了一个额外的装饰器 (my_decorator
),我打算将其用作包装器以添加一些额外信息响应:
def my_wrapper(method):
def wrapper(*args, **kw):
time_start = time()
profiler = sqltap.start()
fn_result = method(*args, **kw)
stats = profiler.collect()
time_end = time()
result = {
'info': {
'api_version': args[0].request.registry.settings.api_version,
'request_path': args[0].request.path_info,
'request_method': args[0].request.method,
'current_time': datetime.datetime.now(pytz.utc).strftime('%Y-%m-%dT%H:%M:%SZ'),
'execution_time': time_end - time_start,
'total_queries': len(stats),
'query_time': stats[0].duration if len(stats) > 0 else 0,
},
}
result.update(fn_result)
return result
return wrapper
除非我在我的 view
装饰器中定义 Cornice validators
,否则这工作正常:
from validators import validate_int
@resource(collection_path='/users/', path='/users/{id}')
class UsersResource(object):
def __init__(self, request):
self.request = request
@view(renderer='json', content_type=content_type, validators=validate_int) # added validators
@my_wrapper
def get(self):
return {'user_id': self.request.matchdict['id']}
validators.py
import responses
def validate_int(request):
should_be_int = request.matchdict['id']
try:
int(should_be_int)
except:
raise responses._400('This doesn\'t look like a valid ID.')
responses.py
class _400(exc.HTTPError):
def __init__(self, desc):
body = {'status': 400, 'message': 'Bad Request', 'description': desc}
Response.__init__(self, json.dumps(body))
使用这样的代码,my_wrapper
仅在验证通过时才包装响应(这是完全可以理解的),但我想知道当默认 HTTPException
被引发(因为在那种情况下代码根本不会达到 my_wrapper
)?
在与出色的 Pyramid IRC 社区的简短讨论中,我决定使用 Pyramid's tweens 而不是使用包装器。
我正在使用 Pyramid and Cornice 编写一些 RESTful Python 应用程序,我制作了一个简单的 Cornice resource
:
@resource(collection_path='/users/', path='/users/{id}')
class UsersResource(object):
def __init__(self, request):
self.request = request
@view(renderer='json', content_type=content_type)
@my_wrapper
def get(self):
return {'user_id': self.request.matchdict['id']}
您可能已经注意到,除了 Cornice 的 view
装饰器之外,我还在此处添加了一个额外的装饰器 (my_decorator
),我打算将其用作包装器以添加一些额外信息响应:
def my_wrapper(method):
def wrapper(*args, **kw):
time_start = time()
profiler = sqltap.start()
fn_result = method(*args, **kw)
stats = profiler.collect()
time_end = time()
result = {
'info': {
'api_version': args[0].request.registry.settings.api_version,
'request_path': args[0].request.path_info,
'request_method': args[0].request.method,
'current_time': datetime.datetime.now(pytz.utc).strftime('%Y-%m-%dT%H:%M:%SZ'),
'execution_time': time_end - time_start,
'total_queries': len(stats),
'query_time': stats[0].duration if len(stats) > 0 else 0,
},
}
result.update(fn_result)
return result
return wrapper
除非我在我的 view
装饰器中定义 Cornice validators
,否则这工作正常:
from validators import validate_int
@resource(collection_path='/users/', path='/users/{id}')
class UsersResource(object):
def __init__(self, request):
self.request = request
@view(renderer='json', content_type=content_type, validators=validate_int) # added validators
@my_wrapper
def get(self):
return {'user_id': self.request.matchdict['id']}
validators.py
import responses
def validate_int(request):
should_be_int = request.matchdict['id']
try:
int(should_be_int)
except:
raise responses._400('This doesn\'t look like a valid ID.')
responses.py
class _400(exc.HTTPError):
def __init__(self, desc):
body = {'status': 400, 'message': 'Bad Request', 'description': desc}
Response.__init__(self, json.dumps(body))
使用这样的代码,my_wrapper
仅在验证通过时才包装响应(这是完全可以理解的),但我想知道当默认 HTTPException
被引发(因为在那种情况下代码根本不会达到 my_wrapper
)?
在与出色的 Pyramid IRC 社区的简短讨论中,我决定使用 Pyramid's tweens 而不是使用包装器。