# flask-restful-swagger-3
## What is flask-restful-swagger-3?
flask-restful-swagger-3 is a wrapper for [flask-restful](http://flask-restful.readthedocs.org/en/latest/) which
enables [swagger3](http://swagger.io/) support according to the [openapi 3.0.0 specification](https://swagger.io/specification/).
This project is based on [flask-restful-swagger-2](https://github.com/soerface/flask-restful-swagger-2.0), 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`.
```python
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](http://swagger.io/specification/#infoObject). |
| `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` [server object](http://swagger.io/specification/#serverObject). |
| `schemas`| The Schema Object allows the definition of input and output data types. Maps to the [`schema`](http://swagger.io/specification/#schemaObject) |
| `content` | A list of MIME types the API can consume. Maps to the [`contents`](http://swagger.io/specification/#contentObject) field of the [components](http://swagger.io/specification/#componentObject). |
| `contact` | The contact information for the API. Maps to the `contact` field of the [info object](http://swagger.io/specification/#infoObject). |
| `description` | A short description of the application. Maps to the `description` field of the [info object](http://swagger.io/specification/#infoObject). |
| `external_docs` | Additional external documentation. Maps to the `externalDocs` field of the [operation object](http://swagger.io/specification/#operationObject). |
| `license` | The license information for the API. Maps to the `license` field of the [info object](http://swagger.io/specification/#infoObject). |
| `parameters` | The parameters that can be used across operations. Maps to the `parameters` field of the [operation object](http://swagger.io/specification/#operationObject). |
| `responses` | The responses that can be used across operations. Maps to the `responses` field of the [operation object](http://swagger.io/specification/#operationObject). |
| `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](http://swagger.io/specification/#openapiObject). |
| `securitySchemes` | The security schemes for the API. Maps to the `securitySchemes` field of the [component object](http://swagger.io/specification/#componentsObject). |
| `tags` | A list of tags used by the specification with additional metadata. Maps to the `tags` field fo the [OpenAPI Object](http://swagger.io/specification/#openapiObject). |
| `terms` | The terms of service for the API. Maps to the `termsOfService` field of the [info object](http://swagger.io/specification/#infoObject). |
| `title` | The title of the application (defaults to the flask app module name). Maps to the `title` field of the [info object](http://swagger.io/specification/#infoObject). |
## 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 os 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))
* `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)
* `swagger.parameter`: Add a parameter to the method (Don't use the `path`parameter, 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)
```python
from flask_restful_swagger_3 import swagger, Resource
class UserItemResource(Resource):
@swagger.tags(['user'])
@swagger.reorder_with(UserModel, description="Returns a 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.
```python
api.add_resource(UserItemResource, '/api/users/<int:user_id>')
```
## Parsing query parameters
If a resource function contains the special argument `_parser`, any `query` type parameters in 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`
```python
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):
type = 'object'
properties = {
'id': {
'type': 'integer',
'format': 'int64',
},
'name': {
'type': 'string'
},
'mail': EmailModel,
'keys': KeysModel.array()
}
required = ['name']
```
You can build your models according to the [swagger schema object specification](http://swagger.io/specification/#schemaObject)
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
```python
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.reqpar