-
Notifications
You must be signed in to change notification settings - Fork 85
/
factory.py
165 lines (137 loc) · 5.31 KB
/
factory.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
154
155
156
157
158
159
160
161
162
163
164
165
'''
This file is the acting web server.
@debug, enables debugging, and tracebacks
@host, tells the OS (guest VM) to accept connections from all public IP
addresses.
Note: both the handler, and logger has levels. If the level of the logger is
higher than that of the handler, no messages will be handled by the
corresponding handler.
'''
import yaml
import logging
from flask import Flask, g
from logging.handlers import RotatingFileHandler
from brain.cache.session import RedisSessionInterface
from interface.views_api import blueprint_api
from interface.views_web import blueprint_web
from flask_jwt_extended import JWTManager
# application factory
def create_app(args={'instance': 'web'}):
# path to hiera
prepath = 'hiera'
# get values from yaml
with open(prepath + '/database.yaml', 'r') as stream:
settings = yaml.load(stream)
sql = settings['database']['mariadb']
nosql = settings['database']['mongodb']
with open(prepath + '/common.yaml', 'r') as stream:
settings = yaml.load(stream)
general = settings['general']
with open(prepath + '/webserver/webserver-' + args['instance'] + '.yaml', 'r') as stream:
settings = yaml.load(stream)
webserver = settings['webserver']
with open(prepath + '/cache.yaml', 'r') as stream:
settings = yaml.load(stream)
cache = settings['redis']
with open(prepath + '/application.yaml', 'r') as stream:
settings = yaml.load(stream)
application = settings['application']
crypto = settings['crypto']
validate_password = settings['validate_password']
# programmatic-api: set the flask-jwt-extended extension
if args['instance'] == 'api':
app = Flask(__name__)
app.secret_key = application['security_key']
app.config['JWT_SECRET_KEY'] = application['security_key']
app.register_blueprint(blueprint_api)
JWTManager(app)
# web-interface: replace default cookie session with server-side redis
else:
app = Flask(
__name__,
template_folder='interface/templates',
static_folder='interface/static'
)
app.session_interface = RedisSessionInterface(
cache['host'],
cache['port'],
cache['db']
)
app.secret_key = application['security_key']
app.register_blueprint(blueprint_web)
# local logger: used for this module
ROOT = general['root']
LOG_PATH = webserver['flask']['log_path']
HANDLER_LEVEL = application['log_level']
# flask attributes: accessible across application
app.config.update(
HOST=general['host'],
CACHE_HOST=cache['host'],
CACHE_PORT=cache['port'],
CACHE_DB=cache['db'],
ROOT=ROOT,
SQL_HOST=sql['host'],
SQL_LOG_PATH=sql['log_path'],
SQL_DB=sql['name'],
SQL_USERNAME=sql['username'],
SQL_PASSWORD=sql['password'],
NOSQL_HOST=nosql['hostname'] + ':' + str(nosql['net']['port']),
NOSQL_DB=nosql['name'],
NOSQL_USERNAME=nosql['username'],
NOSQL_PASSWORD=nosql['password'],
LOG_LEVEL=HANDLER_LEVEL,
FLASK_LOG_PATH=webserver['flask']['log_path'],
ERROR_LOG_PATH=application['error_log_path'],
WARNING_LOG_PATH=application['warning_log_path'],
INFO_LOG_PATH=application['info_log_path'],
DEBUG_LOG_PATH=application['debug_log_path'],
MODEL_TYPE=application['model_type'],
DATASET_TYPE=application['dataset']['types'],
SV_KERNEL_TYPE=application['sv_kernel_type'],
MAXCOL_ANON=application['dataset']['anonymous']['max_collection'],
MAXDOC_ANON=application['dataset']['anonymous']['max_document'],
MAXCOL_AUTH=application['dataset']['authenticated']['max_collection'],
MAXDOC_AUTH=application['dataset']['authenticated']['max_document'],
SALT_LENGTH=crypto['salt_length'],
SCRYPT_N=crypto['scrypt_n'],
SCRYPT_R=crypto['scrypt_r'],
SCRYPT_P=crypto['scrypt_p'],
PASSWORD_MIN_C=validate_password['password_min_c'],
PASSWORD_MAX_C=validate_password['password_max_c'],
USER_ID=0
)
# log format
formatter = logging.Formatter(
"[%(asctime)s] {%(pathname)s:%(lineno)d} "
"%(levelname)s - %(message)s"
)
# initialize the log handler
handler = RotatingFileHandler(
LOG_PATH,
maxBytes=10000000,
backupCount=5
)
# log handler level
handler.setLevel(HANDLER_LEVEL)
handler.setFormatter(formatter)
app.logger.addHandler(handler)
# app logger level
log = logging.getLogger('werkzeug')
log.setLevel(logging.DEBUG)
log.addHandler(handler)
# return
return app
def register_teardowns(app):
@app.teardown_appcontext
def close_db(error):
'''
This function closes the database connection, everytime the app context
tears down. A teardown can happen because of two reasons: either
everything went well (the error parameter will be None) or an exception
happened, in which case the error is passed to the teardown function.
Note: http://flask.pocoo.org/docs/0.12/tutorial/dbcon/
'''
if hasattr(g, 'mongodb'):
g.mongodb.close()
if hasattr(g, 'mariadb'):
g.mariadb.close()