Add swagger documentation
parent
d5d2c4d8c8
commit
6c856965a1
|
@ -2,12 +2,14 @@
|
||||||
from flask_api import FlaskAPI
|
from flask_api import FlaskAPI
|
||||||
from flask_sqlalchemy import SQLAlchemy
|
from flask_sqlalchemy import SQLAlchemy
|
||||||
from flask_bcrypt import Bcrypt
|
from flask_bcrypt import Bcrypt
|
||||||
|
from flasgger import Swagger
|
||||||
|
|
||||||
app = FlaskAPI(__name__, instance_relative_config=True)
|
app = FlaskAPI(__name__, instance_relative_config=True)
|
||||||
app.config.from_object('config')
|
app.config.from_object('config')
|
||||||
app.config.from_pyfile('config.py', silent=True)
|
app.config.from_pyfile('config.py', silent=True)
|
||||||
db = SQLAlchemy(app)
|
db = SQLAlchemy(app)
|
||||||
bcrypt = Bcrypt(app)
|
bcrypt = Bcrypt(app)
|
||||||
|
swagger = Swagger(app, template_file='swagger/template.yaml')
|
||||||
|
|
||||||
|
|
||||||
def setup_blueprints(app):
|
def setup_blueprints(app):
|
||||||
|
@ -34,5 +36,5 @@ setup_blueprints(app)
|
||||||
|
|
||||||
|
|
||||||
@app.route("/")
|
@app.route("/")
|
||||||
def hello():
|
def root():
|
||||||
return "Hello World!"
|
return "Hello World!"
|
||||||
|
|
|
@ -4,6 +4,7 @@ from .resources.account import AccountResource
|
||||||
from .resources.token import TokenResource
|
from .resources.token import TokenResource
|
||||||
from marshmallow import ValidationError
|
from marshmallow import ValidationError
|
||||||
|
|
||||||
|
|
||||||
api_bp = Blueprint('api', __name__)
|
api_bp = Blueprint('api', __name__)
|
||||||
api = Api(api_bp)
|
api = Api(api_bp)
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
from flask_restful import Resource, abort
|
from flask_restful import Resource, abort
|
||||||
from webargs import fields
|
from webargs import fields
|
||||||
from webargs.flaskparser import use_args
|
from webargs.flaskparser import use_args
|
||||||
|
from flasgger import swag_from
|
||||||
import app.accounts as accounts
|
import app.accounts as accounts
|
||||||
|
|
||||||
|
|
||||||
|
@ -14,6 +15,7 @@ class AccountResource(Resource):
|
||||||
}
|
}
|
||||||
|
|
||||||
@use_args(user_args)
|
@use_args(user_args)
|
||||||
|
@swag_from('swagger/create_account_spec.yaml')
|
||||||
def post(self, args):
|
def post(self, args):
|
||||||
try:
|
try:
|
||||||
args = args['user']
|
args = args['user']
|
||||||
|
@ -25,3 +27,7 @@ class AccountResource(Resource):
|
||||||
return '', 201
|
return '', 201
|
||||||
except ValueError:
|
except ValueError:
|
||||||
abort(422, message='Account already exists', status='error')
|
abort(422, message='Account already exists', status='error')
|
||||||
|
|
||||||
|
@swag_from('swagger/get_account_spec.yaml')
|
||||||
|
def get(self):
|
||||||
|
return '', 200
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
Creates new user account
|
||||||
|
Requires User object and creates account
|
||||||
|
or returns an error if account already exists
|
||||||
|
---
|
||||||
|
tags:
|
||||||
|
- Account
|
||||||
|
parameters:
|
||||||
|
- in: body
|
||||||
|
name: body
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- user
|
||||||
|
properties:
|
||||||
|
user:
|
||||||
|
required:
|
||||||
|
- username
|
||||||
|
- password
|
||||||
|
- email
|
||||||
|
$ref: '#/definitions/User'
|
||||||
|
responses:
|
||||||
|
201:
|
||||||
|
description: Successful creation
|
||||||
|
422:
|
||||||
|
description: Account already exists
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/Error'
|
|
@ -0,0 +1,36 @@
|
||||||
|
Creates new token for given account
|
||||||
|
Requires a registered User with a valid username and password
|
||||||
|
Creates a JWT token and returns it or returns an error if credentials are wrong
|
||||||
|
---
|
||||||
|
tags:
|
||||||
|
- Token
|
||||||
|
- Account
|
||||||
|
parameters:
|
||||||
|
- in: body
|
||||||
|
name: body
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- user
|
||||||
|
properties:
|
||||||
|
user:
|
||||||
|
$ref: '#/definitions/Credentials'
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: Successful creation
|
||||||
|
schema:
|
||||||
|
required:
|
||||||
|
- status
|
||||||
|
- token
|
||||||
|
properties:
|
||||||
|
status:
|
||||||
|
type: string
|
||||||
|
default: success
|
||||||
|
token:
|
||||||
|
type: string
|
||||||
|
description: JWT token
|
||||||
|
401:
|
||||||
|
description: Bad credentials
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/Error'
|
|
@ -0,0 +1,22 @@
|
||||||
|
Gets a user account
|
||||||
|
---
|
||||||
|
tags:
|
||||||
|
- Account
|
||||||
|
parameters:
|
||||||
|
- in: body
|
||||||
|
name: body
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- user
|
||||||
|
properties:
|
||||||
|
user:
|
||||||
|
$ref: '#/definitions/User'
|
||||||
|
responses:
|
||||||
|
201:
|
||||||
|
description: Successful creation
|
||||||
|
422:
|
||||||
|
description: Account already exists
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/Error'
|
|
@ -1,6 +1,7 @@
|
||||||
from flask_restful import Resource, abort
|
from flask_restful import Resource, abort
|
||||||
from webargs import fields
|
from webargs import fields
|
||||||
from webargs.flaskparser import use_args
|
from webargs.flaskparser import use_args
|
||||||
|
from flasgger import swag_from
|
||||||
import app.accounts as accounts
|
import app.accounts as accounts
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,6 +14,7 @@ class TokenResource(Resource):
|
||||||
}
|
}
|
||||||
|
|
||||||
@use_args(user_args)
|
@use_args(user_args)
|
||||||
|
@swag_from('swagger/create_token_spec.yaml')
|
||||||
def post(self, args):
|
def post(self, args):
|
||||||
try:
|
try:
|
||||||
args = args['user']
|
args = args['user']
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
---
|
||||||
|
servers:
|
||||||
|
- url: https://final-iot-backend.herokuapp.com/
|
||||||
|
description: Heroku deployed app for testing
|
||||||
|
|
||||||
|
basePath: ""
|
||||||
|
|
||||||
|
definitions:
|
||||||
|
|
||||||
|
username:
|
||||||
|
type: string
|
||||||
|
description: User's name in the system
|
||||||
|
default: testusername
|
||||||
|
|
||||||
|
email:
|
||||||
|
type: string
|
||||||
|
format: email
|
||||||
|
description: User's registered email
|
||||||
|
default: user@test.com
|
||||||
|
|
||||||
|
password:
|
||||||
|
type: string
|
||||||
|
format: password
|
||||||
|
description: User's password
|
||||||
|
default: TestPassword1234
|
||||||
|
|
||||||
|
status:
|
||||||
|
type: string
|
||||||
|
description: Status of request
|
||||||
|
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
description: Descriptive message
|
||||||
|
|
||||||
|
Credentials:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- username
|
||||||
|
- password
|
||||||
|
properties:
|
||||||
|
username:
|
||||||
|
$ref: '#/definitions/username'
|
||||||
|
password:
|
||||||
|
$ref: '#/definitions/password'
|
||||||
|
|
||||||
|
User:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- username
|
||||||
|
- password
|
||||||
|
- email
|
||||||
|
properties:
|
||||||
|
username:
|
||||||
|
$ref: '#/definitions/username'
|
||||||
|
password:
|
||||||
|
$ref: '#/definitions/password'
|
||||||
|
email:
|
||||||
|
$ref: '#/definitions/email'
|
||||||
|
|
||||||
|
Error:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- status
|
||||||
|
- message
|
||||||
|
properties:
|
||||||
|
status:
|
||||||
|
$ref: '#/definitions/status'
|
||||||
|
default: error
|
||||||
|
message:
|
||||||
|
$ref: '#/definitions/message'
|
||||||
|
default: Error message
|
||||||
|
|
||||||
|
info:
|
||||||
|
description: Python (Flask) backend for IoT sysyem made for master's degree final project
|
||||||
|
title: IoT Backend
|
||||||
|
version: 0.0.1
|
||||||
|
swagger: '2.0'
|
|
@ -3,6 +3,7 @@ aniso8601==3.0.0
|
||||||
bcrypt==3.1.4
|
bcrypt==3.1.4
|
||||||
cffi==1.11.5
|
cffi==1.11.5
|
||||||
click==6.7
|
click==6.7
|
||||||
|
flasgger==0.8.3
|
||||||
Flask==1.0.2
|
Flask==1.0.2
|
||||||
Flask-API==1.0
|
Flask-API==1.0
|
||||||
Flask-Bcrypt==0.7.1
|
Flask-Bcrypt==0.7.1
|
||||||
|
@ -14,9 +15,11 @@ Flask-SQLAlchemy==2.3.2
|
||||||
gunicorn==19.8.1
|
gunicorn==19.8.1
|
||||||
itsdangerous==0.24
|
itsdangerous==0.24
|
||||||
Jinja2==2.10
|
Jinja2==2.10
|
||||||
|
jsonschema==2.6.0
|
||||||
Mako==1.0.7
|
Mako==1.0.7
|
||||||
MarkupSafe==1.0
|
MarkupSafe==1.0
|
||||||
marshmallow==3.0.0b9
|
marshmallow==3.0.0b9
|
||||||
|
mistune==0.8.3
|
||||||
paho-mqtt==1.3.1
|
paho-mqtt==1.3.1
|
||||||
psycopg2==2.7.4
|
psycopg2==2.7.4
|
||||||
psycopg2-binary==2.7.4
|
psycopg2-binary==2.7.4
|
||||||
|
@ -25,6 +28,7 @@ PyJWT==1.6.1
|
||||||
python-dateutil==2.7.2
|
python-dateutil==2.7.2
|
||||||
python-editor==1.0.3
|
python-editor==1.0.3
|
||||||
pytz==2018.4
|
pytz==2018.4
|
||||||
|
PyYAML==3.12
|
||||||
six==1.11.0
|
six==1.11.0
|
||||||
SQLAlchemy==1.2.7
|
SQLAlchemy==1.2.7
|
||||||
typing==3.6.4
|
typing==3.6.4
|
||||||
|
|
Loading…
Reference in New Issue