Skip to main content

Extract swagger specs from your flask-restful project. Project based on flask-restful-swagger-2 by Soeren Wegener.

Project description

What is flask-restful-swagger-3?

flask-restful-swagger-3 is a wrapper for flask-restful which enables swagger3 support according to the openapi 3.0.0 specification.

This project is based on flask-restful-swagger-2, but it only supported swagger 2.0.

Getting started

Install:

pip install flask-restful-swagger-3

To use it, change your import from from flask_restful import Api to from flask_restful_swagger_3 import Api.

from flask import Flask
# Instead of using this: from flask_restful import Api
# Use this:
from flask_restful_swagger_3 import Api

app = Flask(__name__)

# Use the swagger Api class as you would use the flask restful class.
# It supports several (optional) parameters, these are the defaults:
api = Api(app)

The Api class supports the following parameters:

Parameter

Description

add_api_spec_resource

Set to True to add an endpoint to serve the swagger specification (defaults to True).

version

The API version string (defaults to ‘0.0’). Maps to the version field of the info object.

swagger_prefix_url

The URL prefix for swagger (defaults to /api/doc)

swagger_url

The URL path that serves the swagger specification document (defaults to swagger.json).

servers

The server on which the API is served, it replaces schemes, host and base_path. Maps to the server object.

components

A list reusable objects for different aspects of the OAS. All objects defined within the components object will have no effect on the API unless they are explicitly referenced from properties outside the components object. Maps to the [components](http://swagger.io/specification/#componentsObject).

contact

The contact information for the API. Maps to the contact field of the info object.

description

A short description of the application. Maps to the description field of the info object.

external_docs

Additional external documentation. Maps to the externalDocs field of the operation object.

license

The license information for the API. Maps to the license field of the info object.

parameters

The parameters that can be used across operations. Maps to the parameters field of the operation object.

responses

The responses that can be used across operations. Maps to the responses field of the operation object.

security

A declaration of which security mechanisms can be used across the API. The list of values includes alternative security requirement objects that can be used. Only one of the security requirement objects need to be satisfied to authorize a request. Individual operations can override this definition. Maps to the security field of the OpenAPI Object.

authorizations

Defines a security scheme that can be used by the operations. Maps to the securitySchemes field of components Object

tags

A list of tags used by the specification with additional metadata. Maps to the tags field fo the OpenAPI Object.

terms

The terms of service for the API. Maps to the termsOfService field of the info object.

title

The title of the application (defaults to the flask app module name). Maps to the title field of the info object.

Documenting API endpoints

You can decorate your Api endpoiints with several decorators to build to swagger object:

List of decorators

You need to import swagger from flask_restful_swagger_3

  • swagger.tags: Allow to group operations with a list of tags (argument accepted: a list of strings)

  • swagger.reorder_with: Apply a schema and a response to a method, default response code is 200 (argument accepted: schema: the schema to apply, as_list: Apply the schema as list (default is False), response_code: The response code to apply the example schema (default is 200), description: Description of the method (default is the function doc), summary: Summary of the method (if setted in response, you don’t need it here))

  • swagger.reorder_list_with: Same as swagger.reorder_with with as_list at True

  • swagger.response: Add a response to the method (argument accepted: response_code: The response to add to the method, description: The description of the response, schema: The schema to apply to the method, no_content: if True: content is not added to response, default: False, summary: Summary of the method (if setted in reorder_with or reorder_list_with, you don’t need it here))

  • swagger.parameter: Add a parameter to the method (Don’t use the pathparameter, it will be added automatically with a url with variable: /users:<int:user_id>) (argument accepted: _in, name, schema, description or a `dictionnary)

  • swagger.parameters: Add several parameters to the method, it can add the args to the _parser of the method if exist (argument accepted: a list of parameter)

  • swagger.expected: Add a request body to the method (argument accepted: schema: The schema expected, required)

  • swagger.reqparser: Add request body to the method using RequestParser (argument accepted: name: Name use to generate the model, parser: The RequestParser() object)

  • swagger.security: Add security to a method or a resource. Each argument MUST correspond to a security scheme which is declared in the Security Schemes under the Components Object (declared by authorizations in Api instance)

from flask_restful_swagger_3 import swagger, Resource


class UserItemResource(Resource):
    @swagger.tags(['user'])
    @swagger.reorder_with(UserModel, description="Returns a user", summary="Get User")
    def get(self, user_id):
        # Do some processing
        return UserModel(**{'id': 1, 'name': 'somebody'}), 200  # generates json response {"id": 1, "name": "somebody"}

Use add_resource as usual.

api.add_resource(UserItemResource, '/api/users/<int:user_id>')

Parsing query parameters

If a resource has decorator swagger.parameters or swagger.parameter with in or _in equal query, the documentation will be automatically added to a reqparse parser and assigned to the _parser argument.

Using models

Create a model by inheriting from flask_restful_swagger_3.Schema

from flask_restful_swagger_3 import Schema


class EmailModel(Schema):
    type = 'string'
    format = 'email'


class KeysModel(Schema):
    type = 'object'
    properties = {
        'name': {
            'type': 'string'
        }
    }


class UserModel(Schema):
    properties = {
        'id': {
            'type': 'integer',
            'format': 'int64',
        },
        'name': {
            'type': 'string'
        },
        'mail': EmailModel,
        'keys': KeysModel.array(),
        'user_type': {
            'type': 'string',
            'enum': ['admin', 'regular'],
            'nullable': True
        },
        'password': {
            'type': 'string',
            'format': 'password',
            'load_only': True
        }
    }
    required = ['name']

SuperModel

You can create super model:

WARNING :

  • You can create only super model with type object

  • The inherited model must same type of super model (The best use is to not add type to inherited Schema)

from flask_restful_swagger_3 import Schema

class PersonModel(Schema):
    type = 'object'
    properties = {
        'id': {
            'type': 'integer',
            'format': 'int64'
        },
        'name': {
            'type': 'string'
        }
    }

class EmployeeModel(PersonModel):
    properties = {
        'role': {
            'type': 'string'
        }
    }

employee_1 = {
    'id': 1,
    'name': 'john',
    'role': 'admin'
}

EmployeeModel(**employee_1) # will validate the object

You can build your models according to the swagger schema object specification

It is recommended that you always return a model in your views so that your code and documentation are in sync.

RequestParser support

You can specify RequestParser object if you want to pass its arguments to spec. In such case, there is not need to define model manually

from flask_restful.reqparse import RequestParser

from flask_restful_swagger_3 import swagger, Resource


class GroupResource(Resource):
    post_parser = RequestParser()
    post_parser.add_argument('name', type=str, required=True)
    post_parser.add_argument('id', type=int, help='Id of new group')

    @swagger.tags(['groups'])
    @swagger.response(response_code=201, description='created group')
    @swagger.reqparser(name='GroupsModel', parser=post_parser)
    def post(self):
    ...

Swagger schema (among other things):

{"GroupsModel": {
    "properties": {
        "id": {
            "default": null,
            "description": "Id of new group",
            "name": "id",
            "required": false,
            "type": "integer"
            },
        "name": {
            "default": null,
            "description": null,
            "name": "name",
            "required": true,
            "type": "string"
        }
    },
    "type": "object"
}

Using authentication

In the example above, the view UserItemResource is a subclass of Resource, which is provided by flask_restful. However, flask_restful_swagger_3 provides a thin wrapper around Resource to provide authentication. By using this, you can not only prevent access to resources, but also hide the documentation depending on the provided api_key.

Example:

# Import Api and Resource instead from flask_restful_swagger_2
from flask_restful_swagger_3 import Api, swagger, Resource

api = Api(app)
def auth(api_key, endpoint, method):
    # Space for your fancy authentication. Return True if access is granted, otherwise False
    # api_key is extracted from the url parameters (?api_key=foo)
    # endpoint is the full swagger url (e.g. /some/{value}/endpoint)
    # method is the HTTP method
    return True

swagger.auth = auth

class MyView(Resource):
    @swagger.tags(...)
    # documentation..
    def get(self):
        return SomeModel(value=5)

api.add_resource(MyView, '/some/endpoint')

Specification document

The open_api_json method of the Api instance returns the specification document object, which may be useful for integration with other tools for generating formatted output or client code.

Using Flask Blueprints

To use Flask Blueprints, create a function in your views module that creates the blueprint, registers the resources and returns it wrapped in an Api instance:

from flask import Blueprint, request
from flask_restful_swagger_3 import Api, swagger, Resource

class UserResource(Resource):
...

class UserItemResource(Resource):
...

def get_user_resources():
    """
    Returns user resources.
    :param app: The Flask instance
    :return: User resources
    """
    blueprint = Blueprint('user', __name__)

    api = Api(blueprint, add_api_spec_resource=False)

    api.add_resource(UserResource, '/api/users')
    api.add_resource(UserItemResource, '/api/users/<int:user_id>')

    return api

In your initialization module, collect the swagger document objects for each set of resources, then use the get_swagger_blueprint function to combine the documents and specify the URL to serve them at (default is ‘/api/doc/swagger’). Note that the get_swagger_blueprint function accepts the same keyword parameters as the Api class to populate the fields of the combined swagger document. Finally, register the swagger blueprint along with the blueprints for your resources.

from flask_restful_swagger_3 import get_swagger_blueprint

...

# A list of swagger document objects
docs = []

# Get user resources
user_resources = get_user_resources()

SWAGGER_URL = '/api/doc'  # URL for exposing Swagger UI (without trailing '/')
API_URL = 'swagger.json'  # Our API url (can of course be a local resource)

swagger_blueprint = get_swagger_blueprint(
    user_resources.open_api_json,
    swagger_prefix_url=SWAGGER_URL,
    swagger_url=API_URL,
    title='Example', version='1', servers=servers)


app.register_blueprint(swagger_blueprint)

If you want to add a url_prefix to your swagger Blueprint, you must add SWAGGER_BLUEPRINT_URL_PREFIX to the config of flask object and call get_swagger_blueprint in app_context

from flask_restful_swagger_3 import get_swagger_blueprint

...

app.config.setdefault('SWAGGER_BLUEPRINT_URL_PREFIX', '/swagger')

with app.app_context():
    swagger_blueprint = get_swagger_blueprint(
        user_resources.open_api_json,
        swagger_prefix_url=SWAGGER_URL,
        swagger_url=API_URL,
        title='Example', version='1', servers=servers)


app.register_blueprint(swagger_blueprint, url_prefix='/swagger')

Refer to the files in the example folder for the complete code.

Running and testing

To run the example project in the example folder:

pip install flask-restful-swagger-3
python app.py

To run the example which uses Flask Blueprints:

python app_blueprint.py

The swagger spec will by default be at http://localhost:5000/api/doc/swagger.json. You can change the URL by passing SWAGGER_URL='/my/path' and API_URL='myurl' to the Api constructor.

You can explore your api by running : http://localhost:5000/api/doc

To run tests:

pip install tox # needed to run pytest
tox

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

flask-restful-swagger-3-0.5.1.tar.gz (554.1 kB view details)

Uploaded Source

File details

Details for the file flask-restful-swagger-3-0.5.1.tar.gz.

File metadata

  • Download URL: flask-restful-swagger-3-0.5.1.tar.gz
  • Upload date:
  • Size: 554.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.8.0 pkginfo/1.9.6 readme-renderer/34.0 requests/2.27.1 requests-toolbelt/0.10.1 urllib3/1.26.14 tqdm/4.64.1 importlib-metadata/4.8.3 keyring/23.4.1 rfc3986/1.5.0 colorama/0.4.5 CPython/3.6.9

File hashes

Hashes for flask-restful-swagger-3-0.5.1.tar.gz
Algorithm Hash digest
SHA256 68261e6a720b80b8eecfce4da7e31759eb08ceb882e8e342d30a3ce46373ac8a
MD5 cb052dd8527070431a13c46104d709d0
BLAKE2b-256 f9e121dcc5d7152b5365076407ef5ea9bca3b2ec578d10742de4a1bae6745144

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page