forked from N3evin/AmiiboAPI
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.py
153 lines (117 loc) · 3.66 KB
/
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#!/usr/bin/env python
# coding=utf-8
"""
@author: N3evin
@copyright: Copyright 2017, AmiiboAPI
@license: MIT License
"""
import datetime, time, colors
from rfc3339 import rfc3339
from flask import Flask, jsonify, make_response, render_template, request, g
from flask_compress import Compress
from flask_cors import CORS
from flask_limiter import Limiter
from flask_limiter.util import get_remote_address
from commons.amiibo_json_encounter import AmiiboJSONEncoder
from amiibo.manager import AmiiboManager
from routes.game_series import gameseriesApp
from routes.amiibo_series import amiiboseriesApp
from routes.type import typeApp
from routes.character import characterApp
from routes.amiibo import amiiboApp
app = Flask(__name__)
application = app
# Register app blueprints
app.register_blueprint(gameseriesApp)
app.register_blueprint(amiiboseriesApp)
app.register_blueprint(typeApp)
app.register_blueprint(characterApp)
app.register_blueprint(amiiboApp)
CORS(app)
app.json_encoder = AmiiboJSONEncoder
Compress(app)
amiibo_manager = AmiiboManager.from_json()
# Set default limit for limiter.
limiter = Limiter(
app,
key_func=get_remote_address,
default_limits=["300 per day"]
)
# Index
@app.route('/')
@limiter.exempt
def index():
return render_template('home.html')
# Documentation
@app.route('/docs/')
@limiter.exempt
def documentation():
return render_template('docs.html')
# FAQs
@app.route('/faq/')
@limiter.exempt
def faqPage():
return render_template('faq.html')
# Handle 400 as json or else Flask will use html as default.
@app.errorhandler(400)
@limiter.exempt
def bad_request(e):
return make_response(jsonify(error=e.description, code=400), 400)
# Handle 404 as json or else Flask will use html as default.
@app.errorhandler(404)
@limiter.exempt
def not_found(e):
return make_response(jsonify(error=e.description, code=404), 404)
# Handle 429 error.
@app.errorhandler(429)
def ratelimit_handler(e):
return make_response(jsonify(error="rate limit exceeded %s" % e.description, code=429))
# remove limit for local ip.
@limiter.request_filter
def ip_whitelist():
return request.remote_addr == "127.0.0.1"
# Last updated info
@app.route('/api/lastupdated/', methods=['GET'])
def route_api_last_updated():
respond = jsonify({'lastUpdated': amiibo_manager.last_updated})
return respond
# store the start time before request.
@app.before_request
def start_timer():
g.start = time.time()
# log after request
@app.after_request
def log_request(response):
if request.path == '/favicon.ico':
return response
elif request.path.startswith('/api') == False:
return response
now = time.time()
duration = round(now - g.start, 2)
dt = datetime.datetime.fromtimestamp(now)
timestamp = rfc3339(dt)
ip = request.headers.get('X-Forwarded-For', request.remote_addr)
host = request.host.split(':', 1)[0]
args = dict(request.args)
log_params = [
('method', request.method, 'blue'),
('path', request.path, 'blue'),
('status', response.status_code, 'yellow'),
('duration', duration, 'green'),
('time', timestamp, 'magenta'),
('ip', ip, 'red'),
('host', host, 'red'),
('params', args, 'blue')
]
request_id = request.headers.get('X-Request-ID')
if request_id:
log_params.append(('request_id', request_id, 'yellow'))
parts = []
for name, value, color in log_params:
part = colors.color("{}={}".format(name, value), fg=color)
parts.append(part)
line = " ".join(parts)
app.logger.info(line)
return response
if __name__ == "__main__":
app.run(debug=True, extra_files=['database/amiibo.json'])