Skip to content

Commit 185cb3f

Browse files
use flask-smorest openapi docs instead of flasgger
1 parent 7ea0a1c commit 185cb3f

File tree

6 files changed

+58
-631
lines changed

6 files changed

+58
-631
lines changed

app/__init__.py

Lines changed: 25 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
from flask_migrate import Migrate
77
from flask_sqlalchemy import SQLAlchemy
88
from dotenv import load_dotenv
9-
from flasgger import Swagger
109
from sqlalchemy import MetaData
1110
from flask_smorest import Api
1211

@@ -41,6 +40,31 @@ def register_blueprints():
4140
app.config["API_VERSION"] = "v1"
4241
app.config["OPENAPI_VERSION"] = "3.0.2"
4342

43+
# flask-smorest openapi swagger
44+
app.config["OPENAPI_URL_PREFIX"] = "/"
45+
app.config["OPENAPI_SWAGGER_UI_PATH"] = "/"
46+
app.config["OPENAPI_SWAGGER_UI_URL"] = "https://cdn.jsdelivr.net/npm/swagger-ui-dist/"
47+
48+
# flask-smorest Swagger UI top level authorize dialog box
49+
app.config["API_SPEC_OPTIONS"] = {
50+
"components": {
51+
"securitySchemes": {
52+
"access_token": {
53+
"type": "http",
54+
"scheme": "bearer",
55+
"bearerFormat": "JWT",
56+
"description": "Enter your JWT access token",
57+
},
58+
"refresh_token": {
59+
"type": "http",
60+
"scheme": "bearer",
61+
"bearerFormat": "JWT",
62+
"description": "Enter your JWT refresh token",
63+
},
64+
}
65+
}
66+
}
67+
4468
# PostgreSQL-compatible naming convention (to follow the naming convention already used in the DB)
4569
# https://stackoverflow.com/questions/4107915/postgresql-default-constraint-names
4670
naming_convention = {
@@ -73,47 +97,3 @@ def invalid_token_callback(error):
7397
@jwt.unauthorized_loader
7498
def missing_token_callback(error):
7599
return jsonify(code="authorization_required", error="JWT needed for this operation. Login, if needed."), 401
76-
77-
78-
swagger_config = {
79-
'openapi': '3.0.0',
80-
'title': 'Ecommerce REST API',
81-
'version': None,
82-
'termsOfService': None,
83-
'description': None,
84-
'specs': [
85-
{
86-
"endpoint": 'api_spec',
87-
"route": '/api_spec.json',
88-
"rule_filter": lambda rule: True, # all in
89-
"model_filter": lambda tag: True, # all in
90-
}
91-
],
92-
'components': {
93-
'securitySchemes': {
94-
'access_token': {
95-
'type': 'http',
96-
'scheme': 'bearer',
97-
'bearerFormat': 'JWT',
98-
'description': 'Enter your JWT access token'
99-
},
100-
'refresh_token': {
101-
'type': 'http',
102-
'scheme': 'bearer',
103-
'bearerFormat': 'JWT',
104-
'description': 'Enter your JWT refresh token'
105-
}
106-
}
107-
},
108-
'specs_route': '/'
109-
}
110-
111-
template = {
112-
'tags': [
113-
{'name': 'Category', 'description': 'Operations with categories'},
114-
{'name': 'Subcategory', 'description': 'Operations with subategories'},
115-
{'name': 'Product', 'description': 'Operations with products'},
116-
{'name': 'User', 'description': 'Operations with users'},
117-
]
118-
}
119-
swagger = Swagger(app, template=template, config=swagger_config, merge=True)

app/routes/auth.py

Lines changed: 7 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -14,46 +14,15 @@
1414
from app.models import User
1515
from app.schemas import AuthIn, AuthOut
1616

17-
bp = Blueprint("auth", __name__)
17+
bp = Blueprint("Auth", __name__)
1818

1919

2020
@bp.route("/register")
2121
class Register(MethodView):
22+
@bp.doc(summary="Register a new user")
2223
@bp.arguments(AuthIn)
2324
@bp.response(201)
2425
def post(self, data):
25-
"""
26-
Register a new user.
27-
---
28-
tags:
29-
- User
30-
description: Register a new user.
31-
requestBody:
32-
required: true
33-
description: email - Email id <br> password - Password
34-
content:
35-
application/json:
36-
schema:
37-
type: object
38-
required:
39-
- email
40-
- password
41-
properties:
42-
email:
43-
type: string
44-
password:
45-
type: string
46-
responses:
47-
201:
48-
description: User registered successfully.
49-
400:
50-
description: Invalid input.
51-
409:
52-
description: Email already exists.
53-
500:
54-
description: Internal Server Error.
55-
"""
56-
5726
user = User()
5827
user.set_password(data["password"])
5928

@@ -74,42 +43,10 @@ def post(self, data):
7443

7544
@bp.route("/login")
7645
class Login(MethodView):
77-
"""Login a user and return access & refresh tokens."""
78-
46+
@bp.doc(summary="Login a user")
7947
@bp.arguments(AuthIn)
8048
@bp.response(200, AuthOut)
8149
def post(self, data):
82-
"""
83-
Login a user.
84-
---
85-
tags:
86-
- User
87-
description: Login a user.
88-
requestBody:
89-
required: true
90-
description: email - Email id <br> password - Password
91-
content:
92-
application/json:
93-
schema:
94-
type: object
95-
required:
96-
- email
97-
- password
98-
properties:
99-
email:
100-
type: string
101-
password:
102-
type: string
103-
responses:
104-
200:
105-
description: User logged in successfully.
106-
400:
107-
description: Invalid input.
108-
401:
109-
description: Invalid email or password.
110-
500:
111-
description: Internal Server Error.
112-
"""
11350
user = User.get(email=data["email"])
11451
if not user or not user.check_password(data["password"]):
11552
return abort(
@@ -129,26 +66,12 @@ def post(self, data):
12966

13067
@bp.route("/refresh")
13168
class Refresh(MethodView):
132-
"""Get new access token using your refresh token."""
133-
13469
@jwt_required(refresh=True)
70+
@bp.doc(
71+
summary="Get new access token using your refresh token",
72+
security=[{"refresh_token": []}],
73+
)
13574
@bp.response(200, AuthOut(only=("access_token",)))
13675
def post(self):
137-
"""
138-
Get new access token using your refresh token
139-
---
140-
tags:
141-
- User
142-
description: Get new access token using your refresh token.
143-
security:
144-
- refresh_token: []
145-
responses:
146-
200:
147-
description: New access token.
148-
401:
149-
description: Token expired, missing or invalid.
150-
500:
151-
description: Internal Server Error.
152-
"""
15376
identity = get_jwt_identity()
15477
return {"access_token": create_access_token(identity=identity, fresh=False)}

0 commit comments

Comments
 (0)