def test_path_from_view(self, spec, config): def hi_request(request): return Response("Hi") config.add_route("hi", "/hi") config.add_view(hi_request, route_name="hi") add_pyramid_paths( spec, "hi", operations={ "get": { "parameters": [], "responses": { "200": { "description": "Test description", "schema": "file" } }, } }, ) assert "/hi" in spec._paths assert "get" in spec._paths["/hi"] expected = { "parameters": [], "responses": { "200": { "description": "Test description", "schema": { "$ref": "#/definitions/file" }, } }, } assert spec._paths["/hi"]["get"] == expected
def test_path_with_multiple_methods(self, spec): def hi_request(request): return Response("Hi") with Configurator() as config: config.add_route("hi", "/hi") config.add_view(hi_request, route_name="hi", request_method=["get", "post"]) config.make_wsgi_app() with prepare(config.registry): add_pyramid_paths( spec, "hi", operations=dict( get={ "description": "get a greeting", "responses": { "200": "..params.." }, }, post={ "description": "post a greeting", "responses": { "200": "..params.." }, }, ), ) get_op = spec._paths["/hi"]["get"] post_op = spec._paths["/hi"]["post"] assert get_op["description"] == "get a greeting" assert post_op["description"] == "post a greeting"
def api_spec(request): """ Serve the spec to explorer """ spec = APISpec( title="Some API", version="1.0.0", openapi_version="2.0", plugins=[MarshmallowPlugin()], ) # using marshmallow plugin here spec.components.schema("FooBodySchema", schema=validation.FooBodySchema) spec.components.schema("BarBodySchema", schema=validation.BarBodySchema(many=True)) # register API security scheme api_auth_scheme = {"type": "apiKey", "in": "header", "name": "Authorization"} spec.components.security_scheme("APIKeyHeader", api_auth_scheme) # inspect the `foo_route` and generate operations from docstring add_pyramid_paths(spec, "users", request=request) # inspection supports filtering via pyramid add_view predicate arguments add_pyramid_paths(spec, "bar_route", request=request) my_spec = spec.to_dict() # you can further mutate the spec dict to include things like security definitions return my_spec
def test_path_from_view(self, spec): def hi_request(request): return Response("Hi") with Configurator() as config: config.add_route("hi", "/hi") config.add_view(hi_request, route_name="hi") config.make_wsgi_app() with prepare(config.registry): add_pyramid_paths( spec, "hi", operations={ "get": { "parameters": [], "responses": { "200": "..params.." } } }, ) assert "/hi" in spec._paths assert "get" in spec._paths["/hi"] expected = {"parameters": [], "responses": {"200": "..params.."}} assert spec._paths["/hi"]["get"] == expected
def test_path_is_translated_to_swagger_template(self, spec, config): def get_pet(pet_id): return "representation of pet {pet_id}".format(pet_id=pet_id) config.add_route("pet", "/pet/{pet_id}") config.add_view(get_pet, route_name="pet") add_pyramid_paths(spec, "pet") assert "/pet/{pet_id}" in spec._paths
def test_routes_with_regex(self, spec, config): def get_pet(pet_id): return "" config.add_route("pet", r"/pet/{pet_id:\d+}") config.add_view(get_pet, route_name="pet") add_pyramid_paths(spec, "pet") assert "/pet/{pet_id}" in spec._paths
def test_autodoc_off_empty(self, spec, config): def hi_request(request): return Response("Hi") config.add_route("hi", "/hi") config.add_view(hi_request, route_name="hi") add_pyramid_paths(spec, "hi", autodoc=False) assert "/hi" in spec._paths assert not spec._paths["/hi"].keys()
def test_path_from_method_view(self, spec, config): # Class Based Views class HelloApi(object): """Greeting API. --- x-extension: global metadata """ def get(self): """A greeting endpoint. --- description: get a greeting responses: 200: description: said hi """ return "hi" def post(self): return "hi" def mixed(self): """Mixed endpoint. --- description: get a mixed greeting responses: 200: description: said hi """ return "hi" config.add_route("hi", "/hi") # normally this would be added via @view_config decorator config.add_view(HelloApi, attr="get", route_name="hi", request_method="get") config.add_view(HelloApi, attr="post", route_name="hi", request_method="post") config.add_view( HelloApi, attr="mixed", route_name="hi", request_method=["put", "delete"], xhr=True, ) add_pyramid_paths(spec, "hi") expected = { "description": "get a greeting", "responses": {"200": {"description": "said hi"}}, } assert spec._paths["/hi"]["get"] == expected assert "post" in spec._paths["/hi"] assert spec._paths["/hi"]["x-extension"] == "global metadata" assert "mixed" in spec._paths["/hi"]["put"]["description"]
def test_api_prefix(self, spec, config): def api_routes(config): config.add_route("pet", "/pet/{pet_id}") def get_pet(pet_id): return "representation of pet {pet_id}".format(pet_id=pet_id) config.include(api_routes, route_prefix="/api/v1/") config.add_view(get_pet, route_name="pet") add_pyramid_paths(spec, "pet") assert "/api/v1/pet/{pet_id}" in spec._paths
def test_routes_with_regex(self, spec): def get_pet(pet_id): return "" with Configurator() as config: config.add_route("pet", "/pet/{pet_id:\d+}") config.add_view(get_pet, route_name="pet") config.make_wsgi_app() with prepare(config.registry): add_pyramid_paths(spec, "pet") assert "/pet/{pet_id}" in spec._paths
def test_path_is_translated_to_swagger_template(self, spec): def get_pet(pet_id): return "representation of pet {pet_id}".format(pet_id=pet_id) with Configurator() as config: config.add_route("pet", "/pet/{pet_id}") config.add_view(get_pet, route_name="pet") config.make_wsgi_app() with prepare(config.registry): add_pyramid_paths(spec, "pet") assert "/pet/{pet_id}" in spec._paths
def test_autodoc_off_empty(self, spec): def hi_request(request): return Response("Hi") with Configurator() as config: config.add_route("hi", "/hi") config.add_view(hi_request, route_name="hi") config.make_wsgi_app() with prepare(config.registry): add_pyramid_paths(spec, "hi", autodoc=False) assert "/hi" in spec._paths assert not spec._paths["/hi"].keys()
def test_autodoc_on_method(self, spec, config): def hi_request(request): return Response("Hi") config.add_route("hi", "/hi") config.add_view(hi_request, route_name="hi", request_method="GET") add_pyramid_paths(spec, "hi") assert "/hi" in spec._paths assert "get" in spec._paths["/hi"] assert list(spec._paths["/hi"].keys()) == ["get"] expected = {"responses": {}} assert spec._paths["/hi"]["get"] == expected
def api_spec(request): spec = APISpec( title='Some API', version='1.0.0', openapi_version='2.0', plugins=[ MarshmallowPlugin() ], ) # inspect the `foo_route` and generate operations from docstring add_pyramid_paths(spec, 'api_object', request=request) add_pyramid_paths(spec, 'api_object_relation', request=request) return spec.to_dict()
def test_api_prefix(self, spec): def api_routes(config): config.add_route("pet", "/pet/{pet_id}") def get_pet(pet_id): return "representation of pet {pet_id}".format(pet_id=pet_id) with Configurator() as config: config.include(api_routes, route_prefix="/api/v1/") config.add_view(get_pet, route_name="pet") config.make_wsgi_app() with prepare(config.registry): add_pyramid_paths(spec, "pet") assert "/api/v1/pet/{pet_id}" in spec._paths
def test_autodoc_on_method(self, spec): def hi_request(request): return Response("Hi") with Configurator() as config: config.add_route("hi", "/hi") config.add_view(hi_request, route_name="hi", request_method="GET") config.make_wsgi_app() with prepare(config.registry): add_pyramid_paths(spec, "hi") assert "/hi" in spec._paths assert "get" in spec._paths["/hi"] assert list(spec._paths["/hi"].keys()) == ["get"] expected = {"responses": {}} assert spec._paths["/hi"]["get"] == expected
def test_integration_with_docstring_introspection(self, spec): def hello(): """A greeting endpoint. --- x-extension: value get: description: get a greeting responses: 200: description: a pet to be returned schema: $ref: #/definitions/Pet post: description: post a greeting responses: 200: description:some data foo: description: not a valid operation responses: 200: description: more junk """ return "hi" with Configurator() as config: config.add_route("hello", "/hello") config.add_view(hello, route_name="hello") config.make_wsgi_app() with prepare(config.registry): add_pyramid_paths(spec, "hello") get_op = spec._paths["/hello"]["get"] post_op = spec._paths["/hello"]["post"] extension = spec._paths["/hello"]["x-extension"] assert get_op["description"] == "get a greeting" assert post_op["description"] == "post a greeting" assert "foo" not in spec._paths["/hello"] assert extension == "value"
def test_autodoc_on(self, spec, config): def hi_request(request): return Response("Hi") config.add_route("hi", "/hi") config.add_view(hi_request, route_name="hi") config.make_wsgi_app() add_pyramid_paths(spec, "hi") assert "/hi" in spec._paths assert "get" in spec._paths["/hi"] assert "head" in spec._paths["/hi"] assert "post" in spec._paths["/hi"] assert "put" in spec._paths["/hi"] assert "patch" in spec._paths["/hi"] assert "delete" in spec._paths["/hi"] assert "options" in spec._paths["/hi"] expected = {"responses": {}} assert spec._paths["/hi"]["get"] == expected
def api_spec(request): """ Serve the spec to explorer """ spec = APISpec(title="Some API", version="1.0.0", plugins=["apispec.ext.marshmallow"]) # using marshmallow plugin here spec.definition("FooBodySchema", schema=validation.FooBodySchema) spec.definition("BarBodySchema", schema=validation.BarBodySchema(many=True)) # inspect the `foo_route` and generate operations from docstring add_pyramid_paths(spec, "users", request=request) # inspection supports filtering via pyramid add_view predicate arguments add_pyramid_paths(spec, "bar_route", request=request) my_spec = spec.to_dict() # you can further mutate the spec dict to include things like security definitions return my_spec
def test_path_with_match_param(self, spec, config): # this is not intended as an example of how to do i18n def hello(request): """Greet in English. --- description: English greeting responses: 200: description: Success """ return Response("Hello") def hola(request): """Greet in Spanish. --- description: Spanish greeting responses: 200: description: Success """ return Response("Hola") config.add_route("greeting", "/greet/{language}") config.add_view(hello, route_name="greeting", match_param="language=en") config.add_view(hola, route_name="greeting", match_param="language=es") config.make_wsgi_app() add_pyramid_paths(spec, "greeting") assert "/greet/en" in spec._paths assert spec._paths["/greet/en"]["get"][ "description"] == "English greeting" assert "/greet/es" in spec._paths assert spec._paths["/greet/es"]["get"][ "description"] == "Spanish greeting"
def api_spec(request): """ Return something. --- get: description: "Outputs the Open-API specification with version 2.0.0. More information can be found on https://swagger.io/docs/specification/2-0/basic-structure/" operationId: "openapi_spec_get" tags: - "Open API" produces: - "application/json" """ spec = APISpec(title='MÜSLI-API', version='0.0.1', openapi_version='2.0.0', securityDefinitions={ "Bearer": { "type": "apiKey", "in": "header", "name": "Authorization", "description": "JWT Tokens" }, "Basic": { "type": "basic", "description": "Die regulären Zugangsdaten zum Müsli :)" } }, plugins=[MarshmallowPlugin()]) # Paths for API v1 add_pyramid_paths(spec, 'collection_lecture', request=request) add_pyramid_paths(spec, 'lecture', request=request) add_pyramid_paths(spec, 'collection_tutorial', request=request) add_pyramid_paths(spec, 'tutorial', request=request) add_pyramid_paths(spec, 'collection_exercise', request=request) add_pyramid_paths(spec, 'exercise', request=request) add_pyramid_paths(spec, 'exam', request=request) add_pyramid_paths(spec, 'openapi_spec', request=request) add_pyramid_paths(spec, 'whoami', request=request) # Be careful how the schemes are defined: # # If one (or its member) are instantiated as object and some are as class # they can cause weird behavior with double definitions of schemes in the # spec. spec.components.schema( 'User', schema=models.UserSchema(only=allowed_attributes.user())) spec.components.schema( 'Tutorial', schema=models.TutorialSchema(only=allowed_attributes.tutorial())) spec.components.schema('CollectionTutorial', schema=models.TutorialSchema( only=allowed_attributes.collection_tutorial())) spec.components.schema( 'Lecture', schema=models.LectureSchema(only=allowed_attributes.lecture())) spec.components.schema('CollectionLecture', schema=models.LectureSchema( only=allowed_attributes.collection_lecture())) spec.components.schema('ExerciseStudent', schema=models.ExerciseStudentSchema) spec.components.schema('Exercise', schema=models.ExerciseSchema) openapi_json = spec.to_dict() return remove_regex(openapi_json)
def api_spec(self): """ OpenApi 2.0 spec --- get: tags: - "OpenApi 2.0 spec" summary: "Return openapi spec purposes" description: "" operationId: "api_spec" consumes: - "application/json" produces: - "application/json" parameters: responses: 200: description: "Success" """ spec = APISpec(title="Channelstream API", version="0.7.0", plugins=(MarshmallowPlugin(), )) spec.definition("ConnectBody", schema=schemas.ConnectBodySchema) spec.definition("SubscribeBody", schema=schemas.SubscribeBodySchema) spec.definition("UnsubscribeBody", schema=schemas.UnsubscribeBodySchema) spec.definition("UserStateBody", schema=schemas.UserStateBodySchema) spec.definition("MessagesBody", schema=schemas.MessageBodySchema(many=True)) spec.definition("MessageBody", schema=schemas.MessageBodySchema()) spec.definition("MessageEditBody", schema=schemas.MessageEditBodySchema(many=True)) spec.definition("MessagesDeleteBody", schema=schemas.MessagesDeleteBodySchema(many=True)) spec.definition("DisconnectBody", schema=schemas.DisconnectBodySchema) spec.definition("ChannelConfigBody", schema=schemas.ChannelConfigSchema) spec.definition("ChannelInfoBody", schema=schemas.ChannelInfoBodySchema) # legacy api add_pyramid_paths(spec, "legacy_connect", request=self.request) add_pyramid_paths(spec, "legacy_subscribe", request=self.request) add_pyramid_paths(spec, "legacy_unsubscribe", request=self.request) add_pyramid_paths(spec, "legacy_user_state", request=self.request) add_pyramid_paths(spec, "legacy_message", request=self.request) add_pyramid_paths(spec, "legacy_channel_config", request=self.request) add_pyramid_paths(spec, "legacy_info", request=self.request) add_pyramid_paths(spec, "api_listen", request=self.request) add_pyramid_paths(spec, "api_listen_ws", request=self.request) add_pyramid_paths(spec, "api_disconnect", request=self.request) # v1 api # do not expose this yet # add_pyramid_paths(spec, "api_v1_messages", request=self.request) add_pyramid_paths(spec, "admin_json", request=self.request) spec_dict = spec.to_dict() spec_dict["securityDefinitions"] = { "APIKeyHeader": { "type": "apiKey", "name": "X-Channelstream-Secret", "in": "header", } } return spec_dict
def api_spec(self): """ OpenApi 2.0 spec --- get: tags: - "OpenApi 2.0 spec" summary: "Return openapi spec purposes" description: "" operationId: "api_spec" consumes: - "application/json" produces: - "application/json" parameters: responses: 200: description: "Success" """ spec = APISpec( title="Channelstream API", version="0.7.0", openapi_version="2.0.0", plugins=(MarshmallowPlugin(),), ) spec.components.schema("ConnectBody", schema=schemas.ConnectBodySchema) spec.components.schema("SubscribeBody", schema=schemas.SubscribeBodySchema) spec.components.schema("UnsubscribeBody", schema=schemas.UnsubscribeBodySchema) spec.components.schema("UserStateBody", schema=schemas.UserStateBodySchema) spec.components.schema( "MessagesBody", schema=schemas.MessageBodySchema(many=True) ) spec.components.schema("MessageBody", schema=schemas.MessageBodySchema()) spec.components.schema( "MessageEditBody", schema=schemas.MessageEditBodySchema(many=True) ) spec.components.schema( "MessagesDeleteBody", schema=schemas.MessagesDeleteBodySchema(many=True) ) spec.components.schema("DisconnectBody", schema=schemas.DisconnectBodySchema) spec.components.schema("ChannelConfigBody", schema=schemas.ChannelConfigSchema) spec.components.schema("ChannelInfoBody", schema=schemas.ChannelInfoBodySchema) # api add_pyramid_paths(spec, "connect", request=self.request) add_pyramid_paths(spec, "subscribe", request=self.request) add_pyramid_paths(spec, "unsubscribe", request=self.request) add_pyramid_paths(spec, "user_state", request=self.request) add_pyramid_paths(spec, "message", request=self.request) add_pyramid_paths(spec, "channel_config", request=self.request) add_pyramid_paths(spec, "info", request=self.request) add_pyramid_paths(spec, "api_listen", request=self.request) add_pyramid_paths(spec, "api_listen_ws", request=self.request) add_pyramid_paths(spec, "api_disconnect", request=self.request) add_pyramid_paths(spec, "admin_json", request=self.request) spec_dict = spec.to_dict() spec_dict["securityDefinitions"] = { "APIKeyHeader": { "type": "apiKey", "name": "X-Channelstream-Secret", "in": "header", } } return spec_dict