forked from flasgger/flasgger
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdecorators_in_init_app.py
133 lines (113 loc) · 3.45 KB
/
decorators_in_init_app.py
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
"""
A slight variation of the basic auth example to demonstrate using the
"decorators" parameter in init_app, instead of during Swagger object
creation itself.
This is useful in cases when the application factory pattern is used in your
flask app.
The example is very similar to the basic_auth example, except that the
decorators parameter is passed in init_app.
Doc for the original basic auth example follows.
An example that uses HTTP Basic Auth to protect the /apidocs and
/apispec_1.json endpoints.
In this example the login credentials to view the Swagger docs are as follows:
Username: guest
Password: secret
Failing to provide the right credentials results in a 401 Unauthorized
response from all the Flasgger endpoints.
"""
from flask import Flask, request, redirect, Response, jsonify
from functools import wraps
from flasgger import Swagger
def requires_basic_auth(f):
"""Decorator to require HTTP Basic Auth for your endpoint."""
def check_auth(username, password):
return username == "guest" and password == "secret"
def authenticate():
return Response(
"Authentication required.", 401,
{"WWW-Authenticate": "Basic realm='Login Required'"},
)
@wraps(f)
def decorated(*args, **kwargs):
# NOTE: This example will require Basic Auth only when you run the
# app directly. For unit tests, we can't block it from getting the
# Swagger specs so we just allow it to go thru without auth.
# The following two lines of code wouldn't be needed in a normal
# production environment.
if __name__ != "__main__":
return f(*args, **kwargs)
auth = request.authorization
if not auth or not check_auth(auth.username, auth.password):
return authenticate()
return f(*args, **kwargs)
return decorated
app = Flask(__name__)
app.config["SWAGGER"] = {
"title": "Swagger Basic Auth App",
"uiversion": 2,
}
swag = Swagger(
template={
"swagger": "2.0",
"info": {
"title": "Swagger Basic Auth App",
"version": "1.0",
},
"consumes": [
"application/json",
],
"produces": [
"application/json",
],
},
)
# passing decorators in init_app
swag.init_app(app, decorators=[requires_basic_auth])
@app.route("/echo/<name>", methods=["GET", "POST"])
def echo(name):
"""
Echo back the name and any posted parameters.
---
tags:
- echo
parameters:
- in: path
name: name
type: string
required: true
- in: body
name: body
description: JSON parameters.
schema:
properties:
first_name:
type: string
description: First name.
example: Alice
last_name:
type: string
description: Last name.
example: Smith
dob:
type: string
format: date
description: Date of birth.
example: 1990-01-01
comment:
type: string
description: Something arbitrary.
example: Hello world
responses:
200:
description: OK.
"""
data = {
"url_name": name,
"json": request.json,
}
return jsonify(data)
@app.route("/")
def index():
return redirect("/apidocs")
if __name__ == "__main__":
app.run(debug=True)