我正在尝试使用Swagger端点规范来简化烧瓶应用程序的端点数据验证。我避免使用整个swagger生成的服务器代码,因为我发现connexion太不透明了。相反,我使用Swagger生成的模型对象,但自己编写控制器。例如,这是搜索附近餐馆的端点。用户需要提供zip_code
或组合latitude
和longitude
,并且需要验证这些值:
from flask import jsonify, request, Response
from models import RestaurantSearchRequest, RestaurantSearchResponse
app_blueprint = Blueprint(__name__, __name__, url_prefix='/restaurants')
@app_blueprint.route(
utils.versioned_api_route('/search/'), methods=['GET'])
def find_restaurants_by_zip_or_lat_lng() -> Response:
request_data = utils.multidict_to_dict(request.args)
try:
search_request = RestaurantSearchRequest.from_dict(request_data)
search_response = RestaurantSearchResponse.from_lat_lng_zip(**search_request.to_dict())
return Response(jsonify(search_response.to_dict()), 200)
except ValueError as ex:
return Response(ex.message, 400)
现在使用Voluptuous在模型中完成数据验证,但它需要大量的样板:
from voluptuous.schema_builder import Schema
from lib import validators
from models.swagger import RestaurantSearchRequest as SwaggerRestaurantSearchRequest
# Inherit all swagger utils, such as `to_dict` and `from_dict`
class RestaurantSearchRequest(SwaggerRestaurantSearchRequest):
def __init__(self: 'RestaurantSearchRequest', latitude: float=None, longitude: float=None, zip_code: str=None):
schema = Schema({
'zip_code': validators.validate_zip_code,
'latitude': validators.validate_latitude,
'longitude': validators.validate_longitude,
})
schema({
'zip_code': zip_code,
'latitude': latitude,
'longitude': longitude,
})
super(RestaurantSearchRequest, self).__init__(latitude, longitude, zip_code)
if (self.longitude is None or self.latitude is None) and self.zip_code is None:
raise ValueError('Must provide either zip code or lat/lng')
我还希望从模型中获取逻辑并将其移动到视图函数中的装饰器。所有这一切的关键是必须具有灵活性来验证单个字段,以及验证字段的组合,如上所述。
我是否可以利用现有的库,或者我可以使用通用的验证器吗?