def test_decorate_view(self): def myfunction(): pass meth = "POST" decorated = decorate_view(myfunction, {}, meth) self.assertEqual(decorated.__name__, "{0}__{1}".format(func_name(myfunction), meth))
def register_service_views(config, service): """Register the routes of the given service into the pyramid router. :param config: the pyramid configuration object that will be populated. :param service: the service object containing the definitions """ services = config.registry.setdefault("cornice_services", {}) services[service.path] = service # keep track of the registered routes registered_routes = [] # register the fallback view, which takes care of returning good error # messages to the user-agent for method, view, args in service.definitions: args = dict(args) # make a copy of the dict to not modify it args["request_method"] = method decorated_view = decorate_view(view, dict(args), method) for item in ("filters", "validators", "schema", "klass"): if item in args: del args[item] # if acl is present, then convert it to a "factory" if "acl" in args: args["factory"] = make_route_factory(args.pop("acl")) route_args = {} if "factory" in args: route_args["factory"] = args.pop("factory") # register the route name with the path if it's not already done if service.path not in registered_routes: config.add_route(service.path, service.path, **route_args) config.add_view(view=get_fallback_view(service), route_name=service.path) registered_routes.append(service.path) # loop on the accept fields: we need to build custom predicate if # callables were passed if "accept" in args: for accept in to_list(args.pop("accept", ())): predicates = args.get("custom_predicates", []) if callable(accept): predicate_checker = functools.partial(match_accept_header, accept) predicates.append(predicate_checker) args["custom_predicates"] = predicates else: # otherwise it means that it is a "standard" accept, # so add it as such. args["accept"] = accept # We register multiple times the same view with different # accept / custom_predicates arguments config.add_view(view=decorated_view, route_name=service.path, **args) else: # it is a simple view, we don't need to loop on the definitions # and just add it one time. config.add_view(view=decorated_view, route_name=service.path, **args)
def test_decorate_view(self): def myfunction(): pass meth = 'POST' decorated = decorate_view(myfunction, {}, meth) self.assertEqual(decorated.__name__, "{0}__{1}".format( func_name(myfunction), meth))
def test_decorate_view_acl(self): args = {'acl': 'dummy_permission', 'klass': DummyAPI} decorated_view = decorate_view('collection_get', args, 'GET') dummy_request = DummyRequest() ret = decorated_view(dummy_request) self.assertEqual(ret, ['douggy', 'rusty']) self.assertEqual(dummy_request, DummyAPI.last_request) self.assertIsNone(DummyAPI.last_context)
def test_decorate_view_factory(self): args = {"factory": u"TheFactoryMethodCalledByPyramid", "klass": DummyAPI} decorated_view = decorate_view("collection_get", args, "GET") dummy_request = DummyRequest() ret = decorated_view(dummy_request) self.assertEqual(ret, ["douggy", "rusty"]) self.assertEqual(dummy_request, DummyAPI.last_request) self.assertEqual(dummy_request.context, DummyAPI.last_context)
def test_decorate_view_acl(self): args = {"acl": "dummy_permission", "klass": DummyAPI} decorated_view = decorate_view("collection_get", args, "GET") dummy_request = DummyRequest() ret = decorated_view(dummy_request) self.assertEqual(ret, ["douggy", "rusty"]) self.assertEqual(dummy_request, DummyAPI.last_request) self.assertIsNone(DummyAPI.last_context)
def test_decorate_view_factory(self): args = {'factory': u'TheFactoryMethodCalledByPyramid', 'klass': DummyAPI} decorated_view = decorate_view('collection_get', args, 'GET') dummy_request = DummyRequest() ret = decorated_view(dummy_request) self.assertEqual(ret, ['douggy', 'rusty']) self.assertEqual(dummy_request, DummyAPI.last_request) self.assertEqual(dummy_request.context, DummyAPI.last_context)
def test_decorate_resource_view(self): class MyResource(object): def __init__(self, **kwargs): pass def myview(self): pass meth = "POST" decorated = decorate_view(_UnboundView(MyResource, "myview"), {}, meth) self.assertEqual(decorated.__name__, "{0}__{1}".format(func_name(MyResource.myview), meth))
def test_decorate_resource_view(self): class MyResource(object): def __init__(self, **kwargs): pass def myview(self): pass meth = 'POST' decorated = decorate_view(_UnboundView(MyResource, 'myview'), {}, meth) self.assertEqual(decorated.__name__, "{0}__{1}".format( func_name(MyResource.myview), meth))
def register_service_views(config, service): """Register the routes of the given service into the pyramid router. :param config: the pyramid configuration object that will be populated. :param service: the service object containing the definitions """ route_name = service.name existing_route = service.pyramid_route prefix = config.route_prefix or '' services = config.registry.cornice_services if existing_route: route_name = existing_route services[prefix + '__cornice' + existing_route] = service else: services[prefix + service.path] = service # before doing anything else, register a view for the OPTIONS method # if we need to if service.cors_enabled and 'OPTIONS' not in service.defined_methods: service.add_view('options', view=get_cors_preflight_view(service), permission=NO_PERMISSION_REQUIRED) # register the fallback view, which takes care of returning good error # messages to the user-agent cors_validator = get_cors_validator(service) # Cornice-specific arguments that pyramid does not know about cornice_parameters = ('filters', 'validators', 'schema', 'klass', 'error_handler') + CORS_PARAMETERS # 1. register route route_args = {} if hasattr(service, 'factory'): route_args['factory'] = service.factory routes = config.get_predlist('route') for predicate in routes.sorter.names: # Do not let the custom predicates handle validation of Header Accept, # which will pass it through to pyramid. It is handled by # _fallback_view(), because it allows callable. if predicate == 'accept': continue if hasattr(service, predicate): route_args[predicate] = getattr(service, predicate) # register route when not using exiting pyramid routes if not existing_route: config.add_route(route_name, service.path, **route_args) # 2. register view(s) for method, view, args in service.definitions: args = copy.copy(args) # make a copy of the dict to not modify it # Deepcopy only the params we're possibly passing on to pyramid # (Some of those in cornice_parameters, e.g. ``schema``, may contain # unpickleable values.) for item in args: if item not in cornice_parameters: args[item] = copy.deepcopy(args[item]) args['request_method'] = method if service.cors_enabled: args['validators'].insert(0, cors_validator) decorated_view = decorate_view(view, dict(args), method, route_args) for item in cornice_parameters: if item in args: del args[item] # filter predicates defined on Resource route_predicates = config.get_predlist('route').sorter.names view_predicates = config.get_predlist('view').sorter.names for pred in set(route_predicates).difference(view_predicates): if pred in args: args.pop(pred) # pop and compute predicates which get passed through to Pyramid 1:1 predicate_definitions = _pop_complex_predicates(args) if predicate_definitions: empty_contenttype = [({'kind': 'content_type', 'value': ''},)] for predicate_list in predicate_definitions + empty_contenttype: args = dict(args) # make a copy of the dict to not modify it # prepare view args by evaluating complex predicates _mungle_view_args(args, predicate_list) # We register the same view multiple times with different # accept / content_type / custom_predicates arguments config.add_view(view=decorated_view, route_name=route_name, **args) else: # it is a simple view, we don't need to loop on the definitions # and just add it one time. config.add_view(view=decorated_view, route_name=route_name, **args) if service.definitions: # Add the fallback view last config.add_view(view=get_fallback_view(service), route_name=route_name, permission=NO_PERMISSION_REQUIRED, require_csrf=False)
def register_service_views(config, service): """Register the routes of the given service into the pyramid router. :param config: the pyramid configuration object that will be populated. :param service: the service object containing the definitions """ services = config.registry.setdefault('cornice_services', {}) services[service.path] = service # keep track of the registered routes registered_routes = [] # before doing anything else, register a view for the OPTIONS method # if we need to if service.cors_enabled and 'OPTIONS' not in service.defined_methods: service.add_view('options', view=get_cors_preflight_view(service)) # register the fallback view, which takes care of returning good error # messages to the user-agent cors_validator = get_cors_validator(service) for method, view, args in service.definitions: args = copy.deepcopy(args) # make a copy of the dict to not modify it args['request_method'] = method if service.cors_enabled: args['validators'].insert(0, cors_validator) decorated_view = decorate_view(view, dict(args), method) for item in ('filters', 'validators', 'schema', 'klass', 'error_handler') + CORS_PARAMETERS: if item in args: del args[item] # if acl is present, then convert it to a "factory" if 'acl' in args: args["factory"] = make_route_factory(args.pop('acl')) # 1. register route route_args = {} if 'factory' in args: route_args['factory'] = args.pop('factory') # register the route name with the path if it's not already done if service.path not in registered_routes: config.add_route(service.name, service.path, **route_args) config.add_view(view=get_fallback_view(service), route_name=service.name) registered_routes.append(service.path) config.commit() # 2. register view(s) # pop and compute predicates which get passed through to Pyramid 1:1 predicate_definitions = _pop_complex_predicates(args) if predicate_definitions: for predicate_list in predicate_definitions: args = dict(args) # make a copy of the dict to not modify it # prepare view args by evaluating complex predicates _mungle_view_args(args, predicate_list) # We register the same view multiple times with different # accept / content_type / custom_predicates arguments config.add_view(view=decorated_view, route_name=service.name, **args) else: # it is a simple view, we don't need to loop on the definitions # and just add it one time. config.add_view(view=decorated_view, route_name=service.name, **args) config.commit()
def register_service_views(config, service): """Register the routes of the given service into the pyramid router. :param config: the pyramid configuration object that will be populated. :param service: the service object containing the definitions """ route_name = service.name services = config.registry.cornice_services prefix = config.route_prefix or '' services[prefix + service.path] = service # before doing anything else, register a view for the OPTIONS method # if we need to if service.cors_enabled and 'OPTIONS' not in service.defined_methods: service.add_view('options', view=get_cors_preflight_view(service), permission=NO_PERMISSION_REQUIRED) # register the fallback view, which takes care of returning good error # messages to the user-agent cors_validator = get_cors_validator(service) # Cornice-specific arguments that pyramid does not know about cornice_parameters = ('filters', 'validators', 'schema', 'klass', 'error_handler', 'deserializer') + CORS_PARAMETERS # 1. register route route_args = {} if hasattr(service, 'acl'): route_args['factory'] = make_route_factory(service.acl) elif hasattr(service, 'factory'): route_args['factory'] = service.factory if hasattr(service, 'traverse'): route_args['traverse'] = service.traverse config.add_route(route_name, service.path, **route_args) # 2. register view(s) for method, view, args in service.definitions: args = copy.copy(args) # make a copy of the dict to not modify it # Deepcopy only the params we're possibly passing on to pyramid # (Some of those in cornice_parameters, e.g. ``schema``, may contain # unpickleable values.) for item in args: if item not in cornice_parameters: args[item] = copy.deepcopy(args[item]) args['request_method'] = method if service.cors_enabled: args['validators'].insert(0, cors_validator) decorated_view = decorate_view(view, dict(args), method) for item in cornice_parameters: if item in args: del args[item] # These attributes are used in routes not views deprecated_attrs = ['acl', 'factory', 'traverse'] for attr in deprecated_attrs: if attr in args: args.pop(attr) # pop and compute predicates which get passed through to Pyramid 1:1 predicate_definitions = _pop_complex_predicates(args) if predicate_definitions: for predicate_list in predicate_definitions: args = dict(args) # make a copy of the dict to not modify it # prepare view args by evaluating complex predicates _mungle_view_args(args, predicate_list) # We register the same view multiple times with different # accept / content_type / custom_predicates arguments config.add_view(view=decorated_view, route_name=route_name, **args) else: # it is a simple view, we don't need to loop on the definitions # and just add it one time. config.add_view(view=decorated_view, route_name=route_name, **args) config.commit() if service.definitions: # Add the fallback view last config.add_view(view=get_fallback_view(service), route_name=route_name, permission=NO_PERMISSION_REQUIRED) config.commit()
def register_service_views(config, service): """Register the routes of the given service into the pyramid router. :param config: the pyramid configuration object that will be populated. :param service: the service object containing the definitions """ services = config.registry.setdefault('cornice_services', {}) services[service.path] = service # keep track of the registered routes registered_routes = [] # before doing anything else, register a view for the OPTIONS method # if we need to if service.cors_enabled and 'OPTIONS' not in service.defined_methods: service.add_view('options', view=get_cors_preflight_view(service)) # register the fallback view, which takes care of returning good error # messages to the user-agent cors_validator = get_cors_validator(service) cors_filter = get_cors_filter(service) for method, view, args in service.definitions: args = copy.deepcopy(args) # make a copy of the dict to not modify it args['request_method'] = method if service.cors_enabled: args['validators'].insert(0, cors_validator) args['filters'].append(cors_filter) decorated_view = decorate_view(view, dict(args), method) for item in ('filters', 'validators', 'schema', 'klass', 'error_handler') + CORS_PARAMETERS: if item in args: del args[item] # if acl is present, then convert it to a "factory" if 'acl' in args: args["factory"] = make_route_factory(args.pop('acl')) route_args = {} if 'factory' in args: route_args['factory'] = args.pop('factory') # register the route name with the path if it's not already done if service.path not in registered_routes: config.add_route(service.path, service.path, **route_args) config.add_view(view=get_fallback_view(service), route_name=service.path) registered_routes.append(service.path) # loop on the accept fields: we need to build custom predicate if # callables were passed if 'accept' in args: for accept in to_list(args.pop('accept', ())): predicates = args.get('custom_predicates', []) if callable(accept): predicate_checker = functools.partial(match_accept_header, accept) predicates.append(predicate_checker) args['custom_predicates'] = predicates else: # otherwise it means that it is a "standard" accept, # so add it as such. args['accept'] = accept # We register multiple times the same view with different # accept / custom_predicates arguments config.add_view(view=decorated_view, route_name=service.path, **args) else: # it is a simple view, we don't need to loop on the definitions # and just add it one time. config.add_view(view=decorated_view, route_name=service.path, **args)
def register_service_views(config, service): """Register the routes of the given service into the pyramid router. :param config: the pyramid configuration object that will be populated. :param service: the service object containing the definitions """ services = config.registry.setdefault('cornice_services', {}) services[service.path] = service # keep track of the registered routes registered_routes = [] # register the fallback view, which takes care of returning good error # messages to the user-agent for method, view, args in service.definitions: args = dict(args) # make a copy of the dict to not modify it args['request_method'] = method decorated_view = decorate_view(view, dict(args), method) for item in ('filters', 'validators', 'schema', 'klass', 'error_handler'): if item in args: del args[item] # if acl is present, then convert it to a "factory" if 'acl' in args: args["factory"] = make_route_factory(args.pop('acl')) route_args = {} if 'factory' in args: route_args['factory'] = args.pop('factory') # register the route name with the path if it's not already done if service.path not in registered_routes: config.add_route(service.path, service.path, **route_args) config.add_view(view=get_fallback_view(service), route_name=service.path) registered_routes.append(service.path) # loop on the accept fields: we need to build custom predicate if # callables were passed if 'accept' in args: for accept in to_list(args.pop('accept', ())): predicates = args.get('custom_predicates', []) if callable(accept): predicate_checker = functools.partial(match_accept_header, accept) predicates.append(predicate_checker) args['custom_predicates'] = predicates else: # otherwise it means that it is a "standard" accept, # so add it as such. args['accept'] = accept # We register multiple times the same view with different # accept / custom_predicates arguments config.add_view(view=decorated_view, route_name=service.path, **args) else: # it is a simple view, we don't need to loop on the definitions # and just add it one time. config.add_view(view=decorated_view, route_name=service.path, **args)
def register_service_views(config, service): """Register the routes of the given service into the pyramid router. :param config: the pyramid configuration object that will be populated. :param service: the service object containing the definitions """ services = config.registry.setdefault('cornice_services', {}) prefix = config.route_prefix or '' services[prefix + service.path] = service # keep track of the registered routes registered_routes = [] # before doing anything else, register a view for the OPTIONS method # if we need to if service.cors_enabled and 'OPTIONS' not in service.defined_methods: service.add_view('options', view=get_cors_preflight_view(service)) # register the fallback view, which takes care of returning good error # messages to the user-agent cors_validator = get_cors_validator(service) # Cornice-specific arguments that pyramid does not know about cornice_parameters = ('filters', 'validators', 'schema', 'klass', 'error_handler', 'deserializer') + CORS_PARAMETERS for method, view, args in service.definitions: args = copy.copy(args) # make a copy of the dict to not modify it # Deepcopy only the params we're possibly passing on to pyramid # (Some of those in cornice_parameters, e.g. ``schema``, may contain # unpickleable values.) for item in args: if item not in cornice_parameters: args[item] = copy.deepcopy(args[item]) args['request_method'] = method if service.cors_enabled: args['validators'].insert(0, cors_validator) decorated_view = decorate_view(view, dict(args), method) for item in cornice_parameters: if item in args: del args[item] # if acl is present, then convert it to a "factory" if 'acl' in args: args["factory"] = make_route_factory(args.pop('acl')) # 1. register route route_args = {} if 'factory' in args: route_args['factory'] = args.pop('factory') if 'traverse' in args: route_args['traverse'] = args.pop('traverse') # register the route name with the path if it's not already done if service.path not in registered_routes: config.add_route(service.name, service.path, **route_args) config.add_view(view=get_fallback_view(service), route_name=service.name) registered_routes.append(service.path) config.commit() # 2. register view(s) # pop and compute predicates which get passed through to Pyramid 1:1 predicate_definitions = _pop_complex_predicates(args) if predicate_definitions: for predicate_list in predicate_definitions: args = dict(args) # make a copy of the dict to not modify it # prepare view args by evaluating complex predicates _mungle_view_args(args, predicate_list) # We register the same view multiple times with different # accept / content_type / custom_predicates arguments config.add_view(view=decorated_view, route_name=service.name, **args) else: # it is a simple view, we don't need to loop on the definitions # and just add it one time. config.add_view(view=decorated_view, route_name=service.name, **args) config.commit()
def register_service_views(config, service): """Register the routes of the given service into the pyramid router. :param config: the pyramid configuration object that will be populated. :param service: the service object containing the definitions """ route_name = service.name services = config.registry.cornice_services prefix = config.route_prefix or '' services[prefix + service.path] = service # before doing anything else, register a view for the OPTIONS method # if we need to if service.cors_enabled and 'OPTIONS' not in service.defined_methods: service.add_view('options', view=get_cors_preflight_view(service), permission=NO_PERMISSION_REQUIRED) # register the fallback view, which takes care of returning good error # messages to the user-agent cors_validator = get_cors_validator(service) # Cornice-specific arguments that pyramid does not know about cornice_parameters = ('filters', 'validators', 'schema', 'klass', 'error_handler', 'deserializer') + CORS_PARAMETERS # 1. register route route_args = {} if hasattr(service, 'acl'): route_args['factory'] = make_route_factory(service.acl) elif hasattr(service, 'factory'): route_args['factory'] = service.factory if hasattr(service, 'traverse'): route_args['traverse'] = service.traverse routes = config.get_predlist('route') for predicate in routes.sorter.names: if hasattr(service, predicate): route_args[predicate] = getattr(service, predicate) config.add_route(route_name, service.path, **route_args) # 2. register view(s) for method, view, args in service.definitions: args = copy.copy(args) # make a copy of the dict to not modify it # Deepcopy only the params we're possibly passing on to pyramid # (Some of those in cornice_parameters, e.g. ``schema``, may contain # unpickleable values.) for item in args: if item not in cornice_parameters: args[item] = copy.deepcopy(args[item]) args['request_method'] = method if service.cors_enabled: args['validators'].insert(0, cors_validator) decorated_view = decorate_view(view, dict(args), method) for item in cornice_parameters: if item in args: del args[item] # These attributes are used in routes not views deprecated_attrs = ['acl', 'factory', 'traverse'] for attr in deprecated_attrs: if attr in args: args.pop(attr) # filter predicates defined on Resource route_predicates = config.get_predlist('route').sorter.names view_predicates = config.get_predlist('view').sorter.names for pred in set(route_predicates).difference(view_predicates): if pred in args: args.pop(pred) # pop and compute predicates which get passed through to Pyramid 1:1 predicate_definitions = _pop_complex_predicates(args) if predicate_definitions: for predicate_list in predicate_definitions: args = dict(args) # make a copy of the dict to not modify it # prepare view args by evaluating complex predicates _mungle_view_args(args, predicate_list) # We register the same view multiple times with different # accept / content_type / custom_predicates arguments config.add_view(view=decorated_view, route_name=route_name, **args) else: # it is a simple view, we don't need to loop on the definitions # and just add it one time. config.add_view(view=decorated_view, route_name=route_name, **args) config.commit() if service.definitions: # Add the fallback view last config.add_view(view=get_fallback_view(service), route_name=route_name, permission=NO_PERMISSION_REQUIRED) config.commit()