def configure_follower_relationship_routes(graph): controller = graph.follower_relationship_controller mappings = { Operation.Create: EndpointDefinition( func=transactional(controller.create), request_schema=NewFollowerRelationshipSchema(), response_schema=FollowerRelationshipSchema(), ), Operation.Delete: EndpointDefinition(func=transactional(controller.delete), ), Operation.Retrieve: EndpointDefinition( func=controller.retrieve, response_schema=FollowerRelationshipSchema(), ), Operation.Search: EndpointDefinition( func=controller.search, request_schema=SearchFollowerRelationshipSchema(), response_schema=FollowerRelationshipSchema(), ), } configure_crud(graph, controller.ns, mappings) return controller.ns
def setup(self): self.graph = create_object_graph(name="example", testing=True) person_ns = Namespace(subject=Person) address_ns = Namespace(subject=Address) configure_crud(self.graph, person_ns, PERSON_MAPPINGS) configure_crud(self.graph, address_ns, ADDRESS_MAPPINGS) self.client = self.graph.flask.test_client()
def test_build_integer_valued_param(): graph = create_object_graph(name="example", testing=True) ns = Namespace( subject=Person, version="v1", identifier_type="int", ) configure_crud(graph, ns, PERSON_MAPPINGS) with graph.flask.test_request_context(): operations = list(iter_endpoints(graph, match_function)) swagger_schema = build_swagger(graph, ns, operations) assert_that( build_path_for_integer_param(ns, Operation.Update, set(["person_id"])), equal_to("/api/v1/person/{person_id}"), ) assert_that( swagger_schema, has_entries(paths=has_entries( **{ "/person/{person_id}": has_entries(patch=has_entries(parameters=has_items({ "required": True, "type": "integer", "name": "person_id", "in": "path", }), ), ), }, ), ))
def configure_user_routes(graph): controller = graph.user_controller mappings = { Operation.Create: EndpointDefinition( func=transactional(controller.create), request_schema=NewUserSchema(), response_schema=UserSchema(), ), Operation.Delete: EndpointDefinition( func=transactional(controller.delete), ), Operation.Retrieve: EndpointDefinition( func=controller.retrieve, response_schema=UserSchema(), ), Operation.Search: EndpointDefinition( func=controller.search, request_schema=SearchUserSchema(), response_schema=UserSchema(), ), Operation.Update: EndpointDefinition( func=transactional(controller.update), request_schema=UpdateUserSchema(), response_schema=UserSchema(), ), } configure_crud(graph, controller.ns, mappings) return controller.ns
def configure_account_routes(graph): controller = graph.account_controller mappings = { Operation.Create: EndpointDefinition( func=transactional(controller.create), request_schema=NewAccountSchema(), response_schema=AccountSchema(), ), Operation.Delete: EndpointDefinition(func=transactional(controller.delete), ), Operation.Retrieve: EndpointDefinition( func=auth_group("app-users-group")(controller.retrieve), response_schema=AccountSchema(), ), Operation.Search: EndpointDefinition( func=auth_group("app-admins-group")(controller.search), request_schema=SearchAccountSchema(), response_schema=AccountSchema(), ), } configure_crud(graph, controller.ns, mappings) return controller.ns
def configure_order_routes(graph): controller = graph.order_controller mappings = { Operation.Create: EndpointDefinition( func=transactional(controller.create), request_schema=NewOrderSchema(), response_schema=OrderSchema(), ), Operation.Delete: EndpointDefinition(func=transactional(controller.delete), ), Operation.Replace: EndpointDefinition( func=transactional(controller.replace), request_schema=NewOrderSchema(), response_schema=OrderSchema(), ), Operation.Retrieve: EndpointDefinition( func=controller.retrieve, response_schema=OrderSchema(), ), } configure_crud(graph, controller.ns, mappings) return controller.ns
def configure_example_routes(graph): controller = graph.example_controller mappings = { Operation.Create: EndpointDefinition( func=transactional(controller.create), request_schema=NewExampleSchema(), response_schema=ExampleSchema(), ), Operation.Delete: EndpointDefinition( func=transactional(controller.delete), ), Operation.Replace: EndpointDefinition( func=transactional(controller.replace), request_schema=NewExampleSchema(), response_schema=ExampleSchema(), ), Operation.Retrieve: EndpointDefinition( func=controller.retrieve, response_schema=ExampleSchema(), ), Operation.Search: EndpointDefinition( func=controller.search, request_schema=SearchExampleSchema(), response_schema=ExampleSchema(), ), } configure_crud(graph, controller.ns, mappings) return controller.ns
def configure_topping_routes(graph): controller = graph.topping_controller mappings = { Operation.Create: EndpointDefinition( func=transactional(controller.create), request_schema=NewToppingSchema(), response_schema=ToppingSchema(), ), Operation.Delete: EndpointDefinition(func=transactional(controller.delete), ), Operation.Replace: EndpointDefinition( func=transactional(controller.replace), request_schema=NewToppingSchema(), response_schema=ToppingSchema(), ), Operation.Retrieve: EndpointDefinition( func=controller.retrieve, response_schema=ToppingSchema(), ), Operation.Search: EndpointDefinition( func=controller.search, request_schema=SearchToppingSchema(), response_schema=ToppingSchema(), ), } configure_crud(graph, controller.ns, mappings) return controller.ns
def setup(self): self.graph = create_object_graph(name="example", testing=True) self.ns = Namespace(subject=Person) configure_crud(self.graph, self.ns, PERSON_MAPPINGS) configure_alias(self.graph, self.ns, PERSON_MAPPINGS) self.client = self.graph.flask.test_client()
def setup(self): self.graph = create_object_graph(name="example", testing=True) self.ns = Namespace(subject="foo") configure_crud(self.graph, self.ns, FOO_MAPPINGS) configure_swagger(self.graph) self.client = self.graph.flask.test_client()
def setup(self): self.graph = create_object_graph(name="example", testing=True) self.ns = Namespace(subject="foo") configure_crud(self.graph, self.ns, FOO_MAPPINGS) configure_swagger(self.graph) self.client = self.graph.flask.test_client()
def setup(self): self.graph = create_object_graph(name="example", testing=True) self.ns = Namespace(subject=Person, ) configure_crud(self.graph, self.ns, PERSON_MAPPINGS) configure_alias(self.graph, self.ns, PERSON_MAPPINGS) self.graph.config.swagger_convention.operations.append("alias") configure_swagger(self.graph) self.client = self.graph.flask.test_client()
def setup(self): self.graph = create_object_graph(name="example", testing=True) self.ns = Namespace( subject=Person, ) configure_crud(self.graph, self.ns, PERSON_MAPPINGS) configure_alias(self.graph, self.ns, PERSON_MAPPINGS) self.graph.config.swagger_convention.operations.append("alias") configure_swagger(self.graph) self.client = self.graph.flask.test_client()
def add_crud(graph): controller = graph.encryptable_controller mappings = { Operation.Update: EndpointDefinition( func=controller.update_and_reencrypt, request_schema=UpdateEncryptableSchema(), response_schema=EncryptableSchema(), ), } configure_crud(graph, controller.ns, mappings) return controller.ns
def setup(self): self.graph = create_object_graph(name="example", testing=True) self.person_ns = Namespace(subject=Person) self.ns = Namespace(subject=PersonSearch) # ensure that link hrefs work configure_crud(self.graph, self.person_ns, { Operation.Retrieve: (person_retrieve, PersonLookupSchema(), PersonSchema()), }) # enable saved search configure_saved_search(self.graph, self.ns, { Operation.SavedSearch: (person_search, OffsetLimitPageSchema(), PersonSchema()), }) self.client = self.graph.flask.test_client()
def setup(self): self.graph = create_object_graph(name="example", testing=True) self.person_ns = Namespace(subject=Person) self.ns = Namespace(subject=PersonSearch) # ensure that link hrefs work configure_crud(self.graph, self.person_ns, { Operation.Retrieve: (person_retrieve, PersonLookupSchema(), PersonSchema()), }) # enable saved search configure_saved_search(self.graph, self.ns, { Operation.SavedSearch: (person_search, OffsetLimitPageSchema(), PersonSchema()), }) self.client = self.graph.flask.test_client()
def setup(self): loader = load_from_dict(route=dict(converters=["cba"], ), ) self.graph = create_object_graph(name="example", testing=True, loader=loader) assert_that(self.graph.config.route.converters, contains_inanyorder("uuid", "cba")) self.person_ns = Namespace( subject=Person, # use custom identifier type identifier_type="cba", ) configure_crud(self.graph, self.person_ns, PERSON_MAPPINGS) self.client = self.graph.flask.test_client()
def setup(self): loader = load_from_dict( route=dict( converters=[ "cba" ], ), ) self.graph = create_object_graph(name="example", testing=True, loader=loader) assert_that(self.graph.config.route.converters, contains_inanyorder("uuid", "cba")) self.person_ns = Namespace( subject=Person, # use custom identifier type identifier_type="cba", ) configure_crud(self.graph, self.person_ns, PERSON_MAPPINGS) self.client = self.graph.flask.test_client()
def configure_publish_info(graph): ns = Namespace( subject="introspection/publish_info", ) def search(**kwargs): publish_info = list(graph.sns_producer.get_publish_info()) return publish_info, len(publish_info) mappings = { Operation.Search: EndpointDefinition( func=search, request_schema=Schema(), response_schema=PublishInfoSchema(), ), } configure_crud(graph, ns, mappings) return ns
def configure_event_crud( graph, controller, event_schema, new_event_schema, search_event_schema, use_deferred_batch=False, ): if use_deferred_batch: create_func = transactional( deferred_batch(controller)(controller.create)) else: create_func = transactional(controller.create) mappings = { Operation.Create: EndpointDefinition( func=create_func, request_schema=new_event_schema, response_schema=event_schema, ), Operation.Delete: EndpointDefinition(func=transactional(controller.delete), ), Operation.Replace: EndpointDefinition( func=transactional(controller.replace), request_schema=new_event_schema, response_schema=event_schema, ), Operation.Retrieve: EndpointDefinition( func=controller.retrieve, response_schema=event_schema, ), Operation.Search: EndpointDefinition( func=controller.search, request_schema=search_event_schema, response_schema=event_schema, ), } configure_crud(graph, controller.ns, mappings) return controller.ns
def test_no_prefix_no_version_path(): loader = load_from_dict( dict( # We want our routes to come directly after the root / build_route_path=dict(prefix=""), )) graph = create_object_graph(name="example", testing=True, loader=loader) ns = Namespace( subject=Person, version="", ) configure_crud(graph, ns, PERSON_MAPPINGS) with graph.flask.test_request_context(): operations = list(iter_endpoints(graph, match_function)) swagger_schema = build_swagger(graph, ns, operations) # Test that in a no prefix, no version case we still get a leading slash in our paths assert_that("/person" in swagger_schema["paths"]) assert_that(swagger_schema["basePath"], equal_to("/"))
def configure_status_convention(graph): store = IndexStatusStore(graph) ns = Namespace(subject="index_status", ) def search(**kwargs): status = store.get_status() return status, len(status) mappings = { Operation.Search: EndpointDefinition( func=search, request_schema=Schema(), response_schema=IndexStatusSchema(), ), } configure_crud(graph, ns, mappings) return ns
def configure_status_convention(graph): store = IndexStatusStore(graph) ns = Namespace( subject="index_status", ) def search(**kwargs): status = store.get_status() return status, len(status) mappings = { Operation.Search: EndpointDefinition( func=search, request_schema=Schema(), response_schema=IndexStatusSchema(), ), } configure_crud(graph, ns, mappings) return ns
def test_no_prefix_no_version_path(): loader = load_from_dict(dict( # We want our routes to come directly after the root / build_route_path=dict( prefix="" ), )) graph = create_object_graph(name="example", testing=True, loader=loader) ns = Namespace( subject=Person, version="", ) configure_crud(graph, ns, PERSON_MAPPINGS) with graph.flask.test_request_context(): operations = list(iter_endpoints(graph, match_function)) swagger_schema = build_swagger(graph, ns, operations) # Test that in a no prefix, no version case we still get a leading slash in our paths assert_that("/person" in swagger_schema["paths"]) assert_that(swagger_schema["basePath"], equal_to("/"))
def configure_order_event_routes(graph): controller = graph.order_event_controller mappings = { Operation.Create: EndpointDefinition( func=transactional(controller.create), request_schema=NewOrderEventSchema(), response_schema=OrderEventSchema(), ), Operation.Retrieve: EndpointDefinition( func=controller.retrieve, response_schema=OrderEventSchema(), ), Operation.Search: EndpointDefinition( func=controller.search, request_schema=SearchOrderEventSchema(), response_schema=OrderEventSchema(), ), } configure_crud(graph, controller.ns, mappings) return controller.ns
def test_build_swagger(): graph = create_object_graph(name="example", testing=True) ns = Namespace( subject=Person, version="v1", ) configure_crud(graph, ns, PERSON_MAPPINGS) with graph.flask.test_request_context(): operations = list(iter_endpoints(graph, match_function)) swagger_schema = build_swagger(graph, ns, operations) assert_that( swagger_schema, has_entries( info={ "version": "v1", "title": "example", }, paths={ "/person": { "post": { "tags": ["person"], "responses": { "default": { "description": "An error occurred", "schema": { "$ref": "#/definitions/Error", } }, "201": { "description": "Create a new person", "schema": { "$ref": "#/definitions/Person", }, }, }, "parameters": [ { "in": "header", "name": "X-Response-Skip-Null", "required": False, "type": "string", }, { "in": "body", "name": "body", "schema": { "$ref": "#/definitions/NewPerson", }, }, ], "operationId": "create", }, }, "/person/{person_id}": { "patch": { "tags": ["person"], "responses": { "default": { "description": "An error occurred", "schema": { "$ref": "#/definitions/Error", }, }, "200": { "description": "Update some or all of a person by id", "schema": { "$ref": "#/definitions/Person", }, }, }, "parameters": [ { "required": False, "type": "string", "name": "X-Response-Skip-Null", "in": "header", }, { "in": "body", "name": "body", "schema": { "$ref": "#/definitions/UpdatePerson", }, }, { "required": True, "type": "string", "name": "person_id", "in": "path", "format": "uuid", }, ], "operationId": "update", }, }, }, produces=[ "application/json", ], definitions=has_entries( NewPerson=has_entries(required=[ "firstName", "lastName", ], type="object", properties={ "email": { "type": "string", "format": "email", }, "eyeColor": { "enum": [ "PURPLE", "TEAL", "RUBY", ], "format": "enum", "type": "string", }, "lastName": { "type": "string", }, "firstName": { "type": "string", } }), Person=has_entries( required=[ "firstName", "id", "lastName", ], type="object", properties={ "email": { "type": "string", "format": "email", }, # Response-side enums are declared as strings "eyeColor": { "type": "string", }, "lastName": { "type": "string", }, "_links": { "type": "object" }, "id": { "type": "string", "format": "uuid", }, "firstName": { "type": "string", }, }, ), PersonPubsubMessage=has_entries( type="object", properties={ "email": { "format": "email", "type": "string", }, "firstName": { "type": "string", }, }, required=[ "firstName", ], ), PersonFoo=has_entries( type="object", properties={ "email": { "format": "email", "type": "string", }, "firstName": { "type": "string", }, }, required=[ "email", ], ), UpdatePerson=dict(type="object", properties={ "lastName": { "type": "string", }, "firstName": { "type": "string", } }), ErrorContext=has_entries( required=["errors"], type="object", properties={ "errors": { "items": { "$ref": "#/definitions/SubError", }, "type": "array", }, }, ), SubError=has_entries( required=["message"], type="object", properties={ "message": { "type": "string", }, }, ), Error=has_entries( required=[ "code", "message", "retryable", ], type="object", properties={ "message": { "type": "string", "default": "Unknown Error", }, "code": { "type": "integer", "format": "int32", "default": 500, }, "context": { "$ref": "#/definitions/ErrorContext", }, "retryable": { "type": "boolean", }, }, ), ), basePath="/api/v1", swagger="2.0", consumes=[ "application/json", ], ))
def test_build_swagger(): graph = create_object_graph(name="example", testing=True) ns = Namespace( subject=Person, version="v1", ) configure_crud(graph, ns, PERSON_MAPPINGS) with graph.flask.test_request_context(): operations = list(iter_endpoints(graph, match_function)) swagger_schema = build_swagger(graph, ns, operations) assert_that(swagger_schema, is_(equal_to({ "info": { "version": "v1", "title": "example", }, "paths": { "/person": { "post": { "tags": ["person"], "responses": { "default": { "description": "An error occurred", "schema": { "$ref": "#/definitions/Error", } }, "201": { "description": "Create a new person", "schema": { "$ref": "#/definitions/Person", }, }, }, "parameters": [ { "in": "header", "name": "X-Response-Skip-Null", "required": False, "type": "string", }, { "in": "body", "name": "body", "schema": { "$ref": "#/definitions/NewPerson", }, }, ], "operationId": "create", }, }, "/person/{person_id}": { "patch": { "tags": ["person"], "responses": { "default": { "description": "An error occurred", "schema": { "$ref": "#/definitions/Error", }, }, "200": { "description": "Update some or all of a person by id", "schema": { "$ref": "#/definitions/Person", }, }, }, "parameters": [ { "required": False, "type": "string", "name": "X-Response-Skip-Null", "in": "header", }, { "in": "body", "name": "body", "schema": { "$ref": "#/definitions/UpdatePerson", }, }, { "required": True, "type": "string", "name": "person_id", "in": "path", "format": "uuid", }, ], "operationId": "update", }, }, }, "produces": [ "application/json", ], "definitions": { "NewPerson": { "required": [ "firstName", "lastName", ], "type": "object", "properties": { "lastName": { "type": "string", }, "firstName": { "type": "string", } } }, "Person": { "required": [ "firstName", "id", "lastName", ], "type": "object", "properties": { "lastName": { "type": "string", }, "_links": { "type": "object" }, "id": { "type": "string", "format": "uuid", }, "firstName": { "type": "string", }, }, }, "UpdatePerson": { "type": "object", "properties": { "lastName": { "type": "string", }, "firstName": { "type": "string", } } }, "ErrorContext": { "required": ["errors"], "type": "object", "properties": { "errors": { "items": { "$ref": "#/definitions/SubError", }, "type": "array", }, }, }, "SubError": { "required": ["message"], "type": "object", "properties": { "message": { "type": "string", }, }, }, "Error": { "required": [ "code", "message", "retryable", ], "type": "object", "properties": { "message": { "type": "string", "default": "Unknown Error", }, "code": { "type": "integer", "format": "int32", "default": 500, }, "context": { "$ref": "#/definitions/ErrorContext", }, "retryable": { "type": "boolean", }, }, }, }, "basePath": "/api/v1", "swagger": "2.0", "consumes": [ "application/json", ], })))