Beispiel #1
0
def build_openapi_spec(publish):
    """Creates an OpenAPI definition of Flask application,
    check conformity of generated definition against OpenAPI 2.0 specification
    and writes it into a file."""

    package = __title__
    desc = __api_description__
    ver = __version__

    # Create OpenAPI specification object
    spec = APISpec(title=package,
                   version=ver,
                   info=dict(description=desc),
                   plugins=('apispec.ext.flask', 'apispec.ext.marshmallow'))

    # Add marshmallow schemas to the specification here
    # spec.definition('Example', schema=Example_schema)

    # Collect OpenAPI docstrings from Flask endpoints
    for key in current_app.view_functions:
        if key != 'static' and key != 'get_openapi_spec':
            spec.add_path(view=current_app.view_functions[key])

    spec_json = json.dumps(spec.to_dict(),
                           indent=2,
                           separators=(',', ': '),
                           sort_keys=True)

    # Output spec to JSON file
    with click.open_file(__output_path__,
                         mode='w+',
                         encoding=None,
                         errors='strict',
                         lazy=False,
                         atomic=False) as output_file:

        output_file.write(spec_json)

        click.echo(
            click.style('OpenAPI specification written to {}'.format(
                output_file.name),
                        fg='green'))

    # Check that generated spec passes validation. Done after writing to file
    # in order to give user easy way to access the possible erroneous spec.
    with open(os.path.join(os.getcwd(), __output_path__)) as output_file:

        validate_json(json.load(output_file), 'schemas/v2.0/schema.json')

        click.echo(
            click.style('OpenAPI specification validated successfully',
                        fg='green'))
        if publish:
            copy_openapi_specs(__output_path__, 'reana-workflow-controller')

    return spec.to_dict()
def get_json(app: Chalice,
             route_functions: dict,
             route_prefix: str,
             version="1.0.0"):
    spec = APISpec(
        title=app.app_name,
        version=version,
        openapi_version="3.0.2",
        plugins=[generate_plugin(app)(),
                 MarshmallowPlugin()],
        servers=[{
            "url": f"/{route_prefix}",
            "description": f"Host on /"
        }],
    )

    fn_list = {[fn_name.view_name for fn_name in r.values()][0]
               for path, r in app.routes.items()}
    for fn_name in [
            fn_name for fn_name in fn_list if fn_name in route_functions
    ]:
        try:
            spec.path(view=route_functions[fn_name])
        except (TypeError, KeyError, ValueError) as e:
            logging.warning(f"Error parsing docstring: {e}")
    return json.dumps(spec.to_dict())
    def get_specification(self):
        spec = APISpec(
            title=self.__class__.__name__,
            version='1.0.0',
            plugins=(
                'apispec.ext.flask',
                'apispec.ext.marshmallow',
            ),
        )

        class PetSchema(Schema):
            id = fields.Int()
            name = fields.Str()

        app = Flask(__name__)

        @app.route('/random')
        def random_pet():
            """A cute furry animal endpoint.
            ---
            get:
                description: Get a random pet
                responses:
                    200:
                        description: A pet to be returned
                        schema: PetSchema
            """
            return jsonify({})

        # Register entities and paths
        spec.definition('Pet', schema=PetSchema)
        with app.test_request_context():
            spec.add_path(view=random_pet)

        return json.dumps(spec.to_dict(), indent=4)
Beispiel #4
0
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 get_specification(self):
        spec = APISpec(
            title=self.__class__.__name__,
            version='1.0.0',
            plugins=(
                'apispec.ext.flask',
                'apispec.ext.marshmallow',
            ),
        )

        class PetSchema(Schema):
            id = fields.Int()
            name = fields.Str()

        app = Flask(__name__)

        @app.route('/random')
        def random_pet():
            """A cute furry animal endpoint.
            ---
            get:
                description: Get a random pet
                responses:
                    200:
                        description: A pet to be returned
                        schema: PetSchema
            """
            return jsonify({})

        # Register entities and paths
        spec.definition('Pet', schema=PetSchema)
        with app.test_request_context():
            spec.add_path(view=random_pet)

        return json.dumps(spec.to_dict(), indent=4)
Beispiel #6
0
def test_oauth2_authentication_documentation():
    app = Starlette()
    plugin = StarlettePlugin(app)
    spec = APISpec(
        title="Test API", version="0.0.1", openapi_version="2.0", plugins=[plugin]
    )
    document_oauth2_authentication(
        spec,
        authorization_url="http://test",
        flow="implicit",
        scopes={"scope1": "Description of scope1", "scope2": "Description of scope2"},
    )

    assert spec.to_dict() == {
        "info": {"title": "Test API", "version": "0.0.1"},
        "paths": {},
        "securityDefinitions": {
            "oauth2": {
                "authorizationUrl": "http://test",
                "flow": "implicit",
                "scopes": {
                    "scope1": "Description of " "scope1",
                    "scope2": "Description of " "scope2",
                },
                "type": "oauth2",
            }
        },
        "swagger": "2.0",
    }
Beispiel #7
0
def update_api_docs() -> None:
    """Regenerate the openapi.json file in docs"""
    superset_dir = os.path.abspath(os.path.dirname(__file__))
    openapi_json = os.path.join(
        superset_dir, "..", "docs", "src", "resources", "openapi.json"
    )
    api_version = "v1"

    version_found = False
    api_spec = APISpec(
        title=current_app.appbuilder.app_name,
        version=api_version,
        openapi_version="3.0.2",
        info=dict(description=current_app.appbuilder.app_name),
        plugins=[MarshmallowPlugin(schema_name_resolver=resolver)],
        servers=[{"url": "http://localhost:8088"}],
    )
    for base_api in current_app.appbuilder.baseviews:
        if isinstance(base_api, BaseApi) and base_api.version == api_version:
            base_api.add_api_spec(api_spec)
            version_found = True
    if version_found:
        click.secho("Generating openapi.json", fg="green")
        with open(openapi_json, "w") as outfile:
            json.dump(api_spec.to_dict(), outfile, sort_keys=True, indent=2)
    else:
        click.secho("API version not found", err=True)
Beispiel #8
0
class Spec:
    def __init__(self, api, title, version):
        self.obj = API_Spec(title=title, version=version, openapi_version='2.0',
                            produces=['application/json'], consumes=['application/json'],
                            tags=rc_tags,
                            plugins=[Falcon_Plugin(api), Marshmallow_Plugin(schema_name_resolver=self.__schema_name_resolver)])

    def get(self):
        return self.obj

    def write(self):
        path = Path(__file__).parent / '../swagger/schema.yaml'
        with path.open('w') as file:
            file.write(self.obj.to_yaml())
        path = Path(__file__).parent / '../swagger/schema.json'
        with path.open('w') as file:
            file.write(dumps(self.obj.to_dict(), indent=2))

    @staticmethod
    def __schema_name_resolver(schema):
        if is_str(schema):
            ref = schema
        else:
            ref = schema.__class__.__name__
        return ref.replace('_Schema', '')
def test_with_exception_handlers_in_app_without_status_code_but_yaml_docstring(
):
    async def handle_exception(request: Request, exc: HTTPException):
        """
        required:
            - message
        properties:
            message:
                type: string
                description: Description of the error.
                example: This is a description of the error.
        type: object
        """
        pass  # pragma: no cover

    app = Starlette(exception_handlers={HTTPException: handle_exception})
    spec = APISpec(
        title="Test API",
        version="0.0.1",
        openapi_version="2.0",
        plugins=[StarlettePlugin(app)],
    )
    assert spec.to_dict() == {
        "info": {
            "title": "Test API",
            "version": "0.0.1"
        },
        "paths": {},
        "swagger": "2.0",
    }
Beispiel #10
0
def update_api_docs() -> None:
    """Regenerate the openapi.json file in docs"""
    from apispec import APISpec
    from apispec.ext.marshmallow import MarshmallowPlugin
    from flask_appbuilder.api import BaseApi
    from os import path

    superset_dir = path.abspath(path.dirname(__file__))
    openapi_json = path.join(superset_dir, "..", "docs", "src", "resources",
                             "openapi.json")
    api_version = "v1"

    version_found = False
    api_spec = APISpec(
        title=current_app.appbuilder.app_name,
        version=api_version,
        openapi_version="3.0.2",
        info=dict(description=current_app.appbuilder.app_name),
        plugins=[MarshmallowPlugin()],
        servers=[{
            "url": "/api/{}".format(api_version)
        }],
    )
    for base_api in current_app.appbuilder.baseviews:
        if isinstance(base_api, BaseApi) and base_api.version == api_version:
            base_api.add_api_spec(api_spec)
            version_found = True
    if version_found:
        click.secho("Generating openapi.json", fg="green")
        with open(openapi_json, "w") as outfile:
            json.dump(api_spec.to_dict(), outfile, sort_keys=True, indent=2)
    else:
        click.secho("API version not found", err=True)
def generate_swagger_file(handlers, file_location):
    """Automatically generates Swagger spec file based on RequestHandler
    docstrings and saves it to the specified file_location.
    """

    # Starting to generate Swagger spec file. All the relevant
    # information can be found from here https://apispec.readthedocs.io/
    spec = APISpec(
        title="Car Brand API",
        version="1.0.0",
        openapi_version="3.0.2",
        info=dict(description="Documentation for the Car Brand API"),
        plugins=[TornadoPlugin(), MarshmallowPlugin()],
        servers=[
            {
                "url": "http://localhost:8888/",
                "description": "Local environment",
            },
        ],
    )
    # Looping through all the handlers and trying to register them.
    # Handlers without docstring will raise errors. That's why we
    # are catching them silently.
    for handler in handlers:
        try:
            spec.path(urlspec=handler)
        except APISpecError:
            pass

    # Write the Swagger file into specified location.
    with open(file_location, "w", encoding="utf-8") as file:
        json.dump(spec.to_dict(), file, ensure_ascii=False, indent=4)
Beispiel #12
0
def get_spec():
    """
    Produce the OpenAPIv3 spec document.

    :rtype: dict
    """
    spec = APISpec(
        title="rest-demo-api",
        version=__version__,
        openapi_version="3.0.2",
        plugins=[FlaskPlugin(), MarshmallowPlugin()],
    )

    app = get_app()
    # Useful for debugging
    # print(app.view_functions)
    spec.path("/authors", view=app.view_functions["authors"], app=app)
    spec.path("/authors/{author_id}",
              view=app.view_functions["author"],
              app=app)
    spec.path("/authors/{author_id}/quotes",
              view=app.view_functions["authorquotes"],
              app=app)
    spec.path("/quotes", view=app.view_functions["quotes"], app=app)
    spec.path("/quotes/{quote_id}", view=app.view_functions["quote"], app=app)
    return spec.to_dict()
Beispiel #13
0
class SwaggerResource:
    def __init__(self):
        from meerkat.configurations.app.settings import Props
        from meerkat.configurations.app.main import app
        from meerkat.configurations.app.main import container
        # todo: should be moved to env vars
        self.spec = APISpec(title='meerkat',
                            version='1.0.0',
                            openapi_version='2.0',
                            plugins=[
                                FalconPlugin(app),
                                MarshmallowPlugin(),
                            ])
        injector = container.get(Props.DI_PROVIDER).get_injector()

        self.spec.components.schema('Health',
                                    schema=injector.get(HealthSchema))
        self.spec.path(resource=injector.get(HealthCheck))

        self.spec.components.schema('Post', schema=injector.get(PostSchema))

        self.spec.path(resource=injector.get(PostCollection))
        self.spec.path(resource=injector.get(Post))

    def on_get(self, req: Request, resp: Response):
        resp.status = falcon.HTTP_200
        resp.body = json.dumps(self.spec.to_dict(), ensure_ascii=False)
Beispiel #14
0
def generate_swagger(
    app: web.Application,
    title=DEFAULT_TITLE,
    version=DEFAULT_VERSION,
    host=DEFAULT_HOST,
    schemes=DEFAULT_SCHEMES,
    definitions_path=DEFAULT_DEFINITIONS_PATH,
    **options
):
    if host is not None:
        options["host"] = host
    if schemes is not None:
        options["schemes"] = schemes

    spec = APISpec(
        title=title, version=version, plugins=("apispec.ext.marshmallow",), **options
    )
    if definitions_path is not None:
        definitions = importlib.import_module(definitions_path)

        for name, schema in definitions.__dict__.items():  # type: str, Schema
            if name.endswith("Schema") and len(name) > len("Schema"):
                spec.definition(name, schema=schema)

    resources = app.router._resources
    for resource in resources:
        url = resource.canonical
        name = resource.name
        for route in resource._routes:
            method = route.method
            if method == "HEAD":
                continue

            handler = route._handler

            try:
                handler_spec = handler.swagger_spec
            except AttributeError:
                handler_spec = {}

            if "excluded" in handler_spec:
                continue

            try:
                handler_spec["summary"] = get_summary(handler.__doc__)
                handler_spec["description"] = handler.__doc__
            except KeyError:
                pass

            parameters = get_parameters(url, handler, spec)
            if parameters:
                handler_spec["parameters"] = parameters

            handler_spec["operationId"] = name

            spec.add_path(url, operations={method.lower(): handler_spec})

    return spec.to_dict()
Beispiel #15
0
    def oas_schema(self, pkg):
        spec = APISpec(
            title=pkg.meta["name"].capitalize(),
            version=pkg.meta["version"],
            openapi_version=self.config["oas_version"],
            plugins=[MarshmallowPlugin()],
        )

        for ctrl in pkg.controllers:
            if not isinstance(ctrl, BaseHttpController):
                continue

            routes = {}

            for func, handler in ctrl.handlers:
                if not handler.status:
                    warnings.warn(f"No @returns for {func}, cannot generate OAS3 schema for this handler")
                    break

                abspath = handler.path_full
                method = handler.method.lower()

                if abspath not in routes:
                    routes[abspath] = {}

                if method not in routes[abspath]:
                    routes[abspath][method] = dict(
                        responses={},
                        parameters=[]
                    )

                route = routes[abspath][method]
                responses = route["responses"]
                parameters = route["parameters"]

                for location, schema_cls in handler.schemas:
                    if location == "response":
                        if not schema_cls:
                            content = {}
                        else:
                            content = {"application/json": {"schema": schema_cls}}

                        responses[handler.status] = dict(
                            description=None,
                            content=content
                        )
                    elif location in ["path", "query", "header"]:
                        if not schema_cls:
                            continue

                        parameters.append({
                            "in": location,
                            "schema": schema_cls
                        })

                spec.path(handler.path_full, operations=routes[abspath])

        return spec.to_dict()
Beispiel #16
0
def test_definition_autogeneration(app, routes):
    spec = APISpec(
        title='test api',
        version='0.1.0',
        plugins=('apispec.ext.marshmallow', 'flask_resty.spec'))

    spec.add_path(view=routes['fooList'])

    assert 'FooSchema' in spec.to_dict()['definitions']
Beispiel #17
0
def test_tagging(app, routes):
    spec = APISpec(
        title='test api',
        version='0.1.0',
        plugins=('apispec.ext.marshmallow', 'flask_resty.spec'))

    spec.add_path(view=routes['fooList'])

    assert 'FooSchema' in spec.to_dict()['paths']['/foos']['get']['tags']
def test_with_exception_handlers_in_app_with_status_code_in_yaml_docstring():
    async def handle_exception(request: Request, exc: HTTPException):
        """
        400:
            required:
                - message
            properties:
                message:
                    type: string
                    description: Description of the error.
                    example: This is a description of the error.
            type: object
        """
        pass  # pragma: no cover

    app = Starlette(exception_handlers={HTTPException: handle_exception})
    spec = APISpec(
        title="Test API",
        version="0.0.1",
        openapi_version="2.0",
        plugins=[StarlettePlugin(app)],
    )
    assert spec.to_dict() == {
        "definitions": {
            "Error400": {
                "properties": {
                    "message": {
                        "description": "Description "
                        "of "
                        "the "
                        "error.",
                        "example": "This is a "
                        "description "
                        "of the "
                        "error.",
                        "type": "string",
                    }
                },
                "required": ["message"],
                "type": "object",
            }
        },
        "info": {
            "title": "Test API",
            "version": "0.0.1"
        },
        "paths": {},
        "responses": {
            400: {
                "schema": {
                    "$ref": "#/definitions/Error400"
                }
            }
        },
        "swagger": "2.0",
    }
Beispiel #19
0
def test_definition_autogeneration(views):
    spec = APISpec(
        title='test api',
        version='0.1.0',
        plugins=(FlaskRestyPlugin(), ),
    )

    spec.add_path(view=views['foo_list'])

    assert 'FooSchema' in spec.to_dict()['definitions']
Beispiel #20
0
def test_definition_autogeneration(views):
    spec = APISpec(
        title='test api',
        version='0.1.0',
        plugins=('apispec.ext.marshmallow', 'flask_resty.spec'),
    )

    spec.add_path(view=views['foo_list'])

    assert 'FooSchema' in spec.to_dict()['definitions']
Beispiel #21
0
def test_tagging(views):
    spec = APISpec(
        title='test api',
        version='0.1.0',
        plugins=('apispec.ext.marshmallow', 'flask_resty.spec'),
    )

    spec.add_path(view=views['foo_list'])

    assert 'FooSchema' in spec.to_dict()['paths']['/foos']['get']['tags']
Beispiel #22
0
def test_tagging(views):
    spec = APISpec(
        title='test api',
        version='0.1.0',
        plugins=(FlaskRestyPlugin(), ),
    )

    spec.add_path(view=views['foo_list'])

    assert 'FooSchema' in spec.to_dict()['paths']['/foos']['get']['tags']
class AiohttpApiSpec:
    def __init__(self, url='/api/docs/api-docs', **kwargs):
        self.spec = APISpec(**kwargs)
        if 'apispec.ext.marshmallow' not in self.spec.plugins:
            self.spec.setup_plugin('apispec.ext.marshmallow')
        self.url = url

    def swagger_dict(self):
        return self.spec.to_dict()

    def register(self, app: web.Application):
        for route in app.router.routes():
            view = route.handler
            method = route.method.lower()
            if hasattr(view, '__apispec__') and view.__apispec__['docked'].get(
                    method) is not True:
                url_path = get_path(route)
                if url_path:
                    if not view.__apispec__['docked'].get('parameters'):
                        view.__apispec__['parameters'].extend({
                            "in": "path",
                            "name": path_key,
                            "required": True,
                            "type": "string"
                        } for path_key in get_path_keys(url_path) if path_key)
                        view.__apispec__['docked']['parameters'] = True
                    self._update_paths(view.__apispec__, method, url_path)
                view.__apispec__['docked'][method] = True
        app['swagger_dict'] = self.spec.to_dict()

        def swagger_handler(request):
            return web.json_response(request.app['swagger_dict'])

        app.router.add_routes([web.get(self.url, swagger_handler)])

    def _update_paths(self, data: dict, method, url_path):
        operations = copy.deepcopy(data)
        operations.pop('docked', None)

        if method in PATHS:
            self.spec.add_path(
                Path(path=url_path, operations={method: operations}))
Beispiel #24
0
class APISpecExt:
    """Very simple and small extension to use apispec with this API as a flask extension
    """

    def __init__(self, app=None, **kwargs):
        self.spec = None

        if app is not None:
            self.init_app(app, **kwargs)

    def init_app(self, app, **kwargs):
        app.config.setdefault("APISPEC_TITLE", "enki_api")
        app.config.setdefault("APISPEC_VERSION", "4.0.0")
        app.config.setdefault("OPENAPI_VERSION", "3.0.3")
        app.config.setdefault("SWAGGER_JSON_URL", "/swagger.json")
        app.config.setdefault("SWAGGER_UI_URL", "/documentation")
        app.config.setdefault("SWAGGER_URL_PREFIX", None)

        self.spec = APISpec(
            title=app.config["APISPEC_TITLE"],
            version=app.config["APISPEC_VERSION"],
            openapi_version=app.config["OPENAPI_VERSION"],
            plugins=[FlaskRestfulPlugin(), MarshmallowPlugin(), DisableOptionsOperationPlugin()],
            **kwargs
        )

        blueprint = Blueprint(
            "swagger",
            __name__,
            template_folder="./templates",
            url_prefix=app.config["SWAGGER_URL_PREFIX"],
        )

        blueprint.add_url_rule(
            app.config["SWAGGER_JSON_URL"], "swagger_json", self.swagger_json
        )
        blueprint.add_url_rule(
            app.config["SWAGGER_UI_URL"], "swagger_ui", self.swagger_ui
        )

        blueprint.add_url_rule(
            "/redoc", "redoc_ui", self.redoc_ui
        )

        app.register_blueprint(blueprint)

    def swagger_json(self):
        return jsonify(self.spec.to_dict())

    def swagger_ui(self):
        return render_template("swagger.j2")

    def redoc_ui(self):
        return render_template("redoc.html")
Beispiel #25
0
 def parameters_json_schema(cls) -> Any:
     """
     Return configuration parameters as OpenAPI.
     """
     spec = APISpec(
         title="Database Parameters",
         version="1.0.0",
         openapi_version="3.0.2",
         plugins=[MarshmallowPlugin()],
     )
     spec.components.schema(cls.__name__, schema=cls.parameters_schema)
     return spec.to_dict()["components"]["schemas"][cls.__name__]
Beispiel #26
0
def swagger_json(hug_api):
    spec = APISpec(title=settings.TITLE,
                   description=settings.DESCRIPTION,
                   version=settings.VERSION,
                   plugins=('apispec.ext.marshmallow', ),
                   schemes=settings.SCHEMES,
                   host=settings.HOST)

    if settings.DEFINITIONS_PATH is not None:
        definitions = importlib.import_module(settings.DEFINITIONS_PATH)

        for name, schema in definitions.__dict__.items():  # type: str, Schema
            if name.endswith('Schema') and len(name) > len('Schema'):
                spec.definition(name, schema=schema)

    routes = hug_api.http.routes['']

    for url, route in routes.items():
        for method, versioned_interfaces in route.items():
            for versions, interface in versioned_interfaces.items():
                methods_data = {}

                documentation = interface.documentation()
                methods_data['content_type'] = documentation['outputs'][
                    'content_type']

                try:
                    methods_data['summary'] = get_summary(
                        documentation['usage'])
                    methods_data['description'] = documentation['usage']
                except KeyError:
                    pass

                parameters = get_parameters(url, interface, spec)
                if parameters:
                    methods_data['parameters'] = parameters

                responses = get_operation(interface, spec,
                                          settings.USE_DEFAULT_RESPONSE)
                if responses:
                    methods_data['responses'] = responses

                if not isinstance(versions, collections.Iterable):
                    versions = [versions]

                for version in versions:
                    versioned_url = '/v{}{}'.format(version,
                                                    url) if version else url

                    spec.add_path(versioned_url,
                                  operations={method.lower(): methods_data})

    return spec.to_dict()
Beispiel #27
0
    def convert(self, yaml=False, references=True, ignorespec=None, **options):
        spec = APISpec(title=self.info.get('title'),
                       version=self.info.get('version'),
                       openapi_version=self.openapi,
                       plugins=[MultiOperationBuilderPlugin(references)],
                       **options)

        for requestitem in self.postman_collection.get_requestitems():
            spec.path(path=requestitem.get_request().path,
                      operations=Operation(requestitem,
                                           ignorespec=ignorespec).get())
        return spec.to_yaml() if yaml else spec.to_dict()
def test_path_summary():
    app = Starlette()
    plugin = StarlettePlugin(app)
    spec = APISpec(title="Test API",
                   version="0.0.1",
                   openapi_version="2.0",
                   plugins=[plugin])

    @app.route("/test")
    def test_endpoint(request):
        """This is the expected summary"""
        pass  # pragma: no cover

    @app.route("/test_with_doc")
    def test_endpoint_with_doc(request):
        """
        This is the expected summary 2
        ---
        responses:
            200:
                description: "ok"
        """
        pass  # pragma: no cover

    for endpoint in plugin.endpoints():
        spec.path(endpoint.path, endpoint=endpoint)

    assert spec.to_dict() == {
        "info": {
            "title": "Test API",
            "version": "0.0.1"
        },
        "paths": {
            "/test": {
                "get": {
                    "operationId": "get_test_endpoint",
                    "summary": "This is the expected summary",
                }
            },
            "/test_with_doc": {
                "get": {
                    "summary": "This is the expected summary 2",
                    "operationId": "get_test_endpoint_with_doc",
                    "responses": {
                        "200": {
                            "description": "ok"
                        }
                    },
                }
            },
        },
        "swagger": "2.0",
    }
Beispiel #29
0
def spec(app, schemas, routes):
    spec = APISpec(
        title='test api',
        version='0.1.0',
        plugins=('apispec.ext.marshmallow', 'flask_resty.spec'))

    spec.definition('Foo', schema=schemas['foo'])

    spec.add_path(view=routes['fooList'])
    spec.add_path(view=routes['foo'])
    spec.add_path(view=routes['bar'])

    return spec.to_dict()
Beispiel #30
0
def create_spec(registry, zone=None, merge=None):
    title = registry.settings.get("openapi.title", "Untitled")
    version = registry.settings.get("openapi.version", "0.0.0")
    name_resolver = DottedNameResolver()
    MarshmallowPlugin = name_resolver.maybe_resolve(
        registry.settings.get("openapi.plugin",
                              "apispec.ext.marshmallow.MarshmallowPlugin"))
    marshmallow_plugin = MarshmallowPlugin(
        schema_name_resolver=schema_name_resolver)
    spec = APISpec(
        title=title,
        version=version,
        openapi_version="3.0.2",
        plugins=[marshmallow_plugin],
    )
    for path, operations in list_paths(registry.introspector):
        final_ops = dict()
        for method, view in operations.items():
            if zone is not None and zone != view.get("api_zone"):
                continue
            summary, descr, user_op = split_docstring(view["callable"].__doc__)
            op = {
                "responses": dict(),
                "parameters": [],
            }
            if summary:
                op["summary"] = summary
            if descr:
                op["description"] = descr
            set_url_params(spec, op, view)
            if "validate" in view:
                if method == "get":
                    set_query_params(spec, op, view)
                else:
                    set_request_body(spec, op, view)
            if "marshal" in view:
                set_response_body(spec, op, view)
            set_tag(spec, op, view)
            final_op = utils.deepupdate(op, user_op)
            final_op = utils.deepupdate(final_op, view.get("api_spec", dict()))

            # We are required to have some response, so make one up.
            if not final_op["responses"]:
                final_op["responses"]["200"] = {
                    "description": "",
                }
            final_ops[method] = final_op
        spec.path(path, operations=final_ops)

    json = spec.to_dict()
    return _perform_merges(json, merge, registry.settings.get("openapi.merge"))
Beispiel #31
0
    def test_resolve_schema_dict_auto_reference_return_none(
            self, schema, deprecated_interface):
        # this resolver return None
        def resolver(schema):
            return None

        if deprecated_interface:
            spec = APISpec(
                title='Test auto-reference',
                version='0.1',
                description='Test auto-reference',
                plugins=('apispec.ext.marshmallow', ),
                schema_name_resolver=resolver,
            )
        else:
            spec = APISpec(
                title='Test auto-reference',
                version='0.1',
                description='Test auto-reference',
                plugins=(MarshmallowPlugin(schema_name_resolver=resolver, ), ),
            )
        assert {} == spec._definitions

        spec.definition('analysis', schema=schema)
        spec.add_path(
            '/test',
            operations={
                'get': {
                    'responses': {
                        '200': {
                            'schema': {
                                '$ref': '#/definitions/analysis',
                            },
                        },
                    },
                },
            },
        )

        # Other shemas not yet referenced
        assert 1 == len(spec._definitions)

        spec_dict = spec.to_dict()
        assert spec_dict.get('definitions')
        assert 'analysis' in spec_dict['definitions']
        # Inspect/Read objects will not auto reference because resolver func
        # return None
        json.dumps(spec_dict)
        # Other shema still not referenced
        assert 1 == len(spec._definitions)
Beispiel #32
0
    def specs_view(self, *args, **kwargs):
        specs = APISpec(title=self.name,
                        version=self.version,
                        basePath=self.url_prefix,
                        host=request.host,
                        plugins=[MarshmallowPlugin()])

        for resource in self.resources:
            resource.update_specs(specs)

        specs = specs.to_dict()
        if isinstance(self.specs, dict):
            specs.update(self.specs)
        return specs
Beispiel #33
0
def spec(schemas, views):
    spec = APISpec(
        title='test api',
        version='0.1.0',
        plugins=('apispec.ext.marshmallow', 'flask_resty.spec'),
    )

    spec.definition('Foo', schema=schemas['foo'])

    spec.add_path(view=views['foo_list'])
    spec.add_path(view=views['foo'])
    spec.add_path(view=views['bar'])

    return spec.to_dict()
Beispiel #34
0
def spec(schemas, views):
    spec = APISpec(
        title='test api',
        version='0.1.0',
        plugins=(FlaskRestyPlugin(), ),
    )

    spec.definition('Foo', schema=schemas['foo'])

    spec.add_path(view=views['foo_list'])
    spec.add_path(view=views['foo'])
    spec.add_path(view=views['foo_baz'])
    spec.add_path(view=views['bar'])

    return spec.to_dict()
Beispiel #35
0
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 get_specification(self):
        spec = APISpec(
            title=self.__class__.__name__,
            version='1.0.0',
            plugins=(
                'apispec.ext.flask',
                'apispec.ext.marshmallow',
            ),
        )

        class PetParameter(Schema):
            pet_id = fields.Int()

        class PetSchema(Schema):
            id = fields.Int()
            name = fields.Str()

        app = Flask(__name__)

        @app.route('/pets/<int:pet_id>')
        def get_pet(pet_id):
            """A cute furry animal endpoint.
            ---
            get:
                description: Get a random pet
                parameters:
                    - in: path
                      schema: PetParameter
                responses:
                    200:
                        description: A pet to be returned
                        schema: PetSchema
            """
            return jsonify({})

        # Register entities and paths
        spec.definition('Pet', schema=PetSchema)
        spec.definition('PetParameter', schema=PetParameter, required=True)
        with app.test_request_context():
            spec.add_path(view=get_pet)

        specification_as_string = json.dumps(spec.to_dict(), indent=4)

        # Kludge! I was unable to do this via `apispec`
        specification_as_string = specification_as_string.replace('"required": false,',
                                                                  '"required": true,')

        return specification_as_string
def generate_specs(module_name):
    module = import_service_module(module_name)
    service_name = ''.split('.')[-1]

    ctx = module.app.test_request_context()
    ctx.push()
    spec = APISpec(
        title=service_name,
        version='1.0.0',
        plugins=('apispec.ext.marshmallow', 'flask_resty.spec'))

    schemas = get_subclasses(module.schemas, Schema)
    for schema in schemas:
        spec.definition(prettify_schema_name(schema), schema=schema)

    for view in get_subclasses(module.views, ApiView):
        try:
            spec.add_path(view=view, tag=True)
        except KeyError:
            pass  # means that the view is not registered. move along

    return json.dumps(spec.to_dict(), indent=2)
Beispiel #38
0
    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