1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
|
"""
Example of swagger document auto loading by endpoint
name(view function/method name), parsed by
flask_restful.reqparse.RequestParser and validated by jsonschema
"""
import os
from flask import Flask, request, jsonify, Response
from flask.views import MethodView
from flasgger import Swagger
app = Flask(__name__)
app.config['SWAGGER'] = {
'title': 'Flasgger Parsed Method/Function View Example',
'doc_dir': './examples/docs/'
}
swag = Swagger(
app,
template_file=os.path.join(
os.getcwd(), 'examples', 'docs', 'template.yml'),
parse=True)
class ItemsView(MethodView):
"""
Flasgger will try to load "./examples/docs/items/{method}.yml" as
swagger document
"""
def get(self):
"""
If we set "parse" is True in Flasgger app, we will get parsed and
validated data stored in "flask.request.parsed_data".
In "parsed_data", different location's var stored in different key,
there is a map between RequestParser's location and swagger
doc's "in" parameter, eg: 'query' -> 'args'.See
"Swagger.SCHEMA_LOCATIONS" for more locations
"""
return jsonify(
[{'name': 'test', 'id': 1,
'type': request.parsed_data['args']['type']},
{'name': 'test2', 'id': 2,
'type': request.parsed_data['args']['type']}])
def post(self):
return jsonify(
{'name': request.parsed_data['json']['name'], 'id': 3,
'type': request.parsed_data['json']['type']})
class ItemMethodView(MethodView):
def get(self, id):
return jsonify({'name': 'test', 'id': id, 'type': 'NORMAL'})
def put(self, id):
return jsonify(
{'name': request.parsed_data['json']['name'],
'id': 3, 'type': 'NORMAL'})
class EmptyView(MethodView):
"""In this view, we do not provide api doc"""
def get(self):
return Response(status=200)
@app.route('/api/users/<group>/', methods=['POST'])
def users(group):
"""Create one user with nested json body.
---
tags:
- FunctionView
parameters:
- name: group
in: path
type: string
required: true
- name: User
in: body
schema:
type: object
required:
- data
properties:
data:
type: object
required:
- name
- age
properties:
age:
type: integer
name:
type: string
tags:
type: array
minItems: 1
items:
type: integer
definitions:
User:
type: object
properties:
id:
type: integer
name:
type: string
group:
type: string
age:
type: integer
responses:
200:
description: ok
schema:
$ref: '#/definitions/User'
examples:
{'id': 1, 'name': 'test', 'group': 1, 'age': 20}
400:
description: Miss data
"""
return jsonify(
{'id': 1,
'name': request.parsed_data['json']['data']['name'],
'age': request.parsed_data['json']['data']['age'],
'group': request.parsed_data['path']['group']})
@app.route('/api/user/')
def user():
"""Flasgger will try to load './examples/docs/user.yml' as swagger doc
"""
return jsonify({'id': request.parsed_data['args']['id'], 'name': 'test'})
app.add_url_rule(
'/api/items/', view_func=ItemsView.as_view(name='items'),
methods=['GET', 'POST'])
app.add_url_rule(
'/api/items/<int:id>/', view_func=ItemMethodView.as_view(name='item'),
methods=['GET', 'PUT'])
app.add_url_rule(
'/api/empty/', view_func=EmptyView.as_view(name='empty'),
methods=['GET'])
def test_swag(client, specs_data):
"""
This test is runs automatically in Travis CI
:param client: Flask app test client
:param specs_data: {'url': {swag_specs}} for every spec in app
"""
res = client.get('/api/items/')
assert res.status_code == 400
res = client.get('/api/items/?type=myLengthIsTooLong')
assert res.status_code == 400
res = client.get('/api/items/?type=NORMAL')
assert res.status_code == 200
res = client.get('/api/items/1/')
assert res.status_code == 200
res = client.put('/api/items/1/')
assert res.status_code == 400
res = client.put('/api/items/1/', json={'name': 'test'})
assert res.status_code == 200
res = client.post('/api/users/1/', json={'name': 'miss data'})
assert res.status_code == 400
res = client.post(
'/api/users/1/',
json={'data': {'name': 'test', 'age': 20}, 'tags': ['error_tag']})
assert res.status_code == 400
res = client.post(
'/api/users/1/',
json={'data': {'name': 'test', 'age': 20}, 'tags': [1, 2]})
assert res.status_code == 200
if __name__ == '__main__':
app.run(debug=True)
|