-
Notifications
You must be signed in to change notification settings - Fork 2
/
app.py
92 lines (73 loc) · 2.85 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
import json
import logging
import os
import re
import sys
import xmltodict
from collections import defaultdict
from flask import Flask
from flask import jsonify
from flask import request
from flask_log_request_id import RequestID
from flask_log_request_id import RequestIDLogFilter
verbs = ['get', 'post', 'delete', 'put', 'patch']
routes = {v: defaultdict(dict) for v in verbs}
app = Flask(__name__)
RequestID(app)
logging.basicConfig(level='INFO', stream=sys.stderr)
handler = logging.getLogger().handlers[0]
handler.addFilter(RequestIDLogFilter())
handler.setFormatter(logging.Formatter(
"%(asctime)s:%(request_id)s:%(levelname)s:%(name)s:%(lineno)d:%(funcName)s:%(message)s"))
logging.getLogger().addHandler(handler)
logger = logging.getLogger()
@app.route("/", defaults={'path': ''}, methods=['get', 'post', 'put', 'patch', 'delete'])
@app.route("/<path:path>", methods=['get', 'post', 'put', 'patch', 'delete'])
def catch_all(path, *args, **kwargs):
verb = request.method
path = "/" + path.replace("//", "/")
file_to_serve = routes[verb.lower()].get(path, False)
if file_to_serve:
return render_json(file_to_serve)
else:
for key, file_path in routes[verb.lower()].iteritems():
if re.match(key, path):
matches = re.search(key, path)
return render_json(file_path, **matches.groupdict())
return jsonify({
"message": "Not Found"
}), 404
def render_json(path, **kwargs):
with open(path, "r") as f:
if path.lower().endswith('.xml'):
d = xmltodict.parse(f.read())
else:
d = json.load(f)
return jsonify(d), 200
def discover_routes(path, base_dir=None):
base_dir = base_dir if base_dir is not None else path
for f in os.listdir(path):
fullpath = os.path.join(path, f)
if os.path.isdir(fullpath):
discover_routes(fullpath, base_dir)
elif os.path.isfile(fullpath):
filename, ext = f.split(".")
if filename in verbs:
comps = fullpath.split("/")
route = "/".join(["(?P<" + c.strip(":") + ">.*)" if ":" in c else c for c in comps[:-1]])
route = route.replace(base_dir, "")
routes[filename][route] = fullpath
@app.before_request
def before():
logger.info("request.method, request.path: {}, {}".format(request.method, request.path))
logger.info("request.headers: {}".format(request.headers))
logger.info("request.args: {}".format(request.args))
logger.info("request.form: {}".format(request.form))
logger.info("request.get_json(): {}".format(request.get_json()))
@app.after_request
def after(response):
logger.info("response.status_code: {}".format(response.status_code))
return response
if __name__ == '__main__':
discover_routes("./apis")
app.run(debug=True, host="0.0.0.0", port=5000)