-
Notifications
You must be signed in to change notification settings - Fork 5
/
main.py
147 lines (112 loc) · 4.6 KB
/
main.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
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2013 Ivan Kolodyazhny.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from flask import Flask, render_template
def __import_blueprint(blueprint_str):
split = blueprint_str.split('.')
module_path = '.'.join(split[0: len(split) - 1])
variable_name = split[-1]
mod = __import__(module_path, fromlist=[variable_name])
return getattr(mod, variable_name)
def config_str_to_obj(cfg):
if isinstance(cfg, basestring):
module = __import__('config', fromlist=[cfg])
return getattr(module, cfg)
return cfg
def app_factory(config, app_name=None, blueprints=None):
app_name = app_name or __name__
app = Flask(app_name)
config = config_str_to_obj(config)
configure_app(app, config)
configure_blueprints(app, blueprints or config.BLUEPRINTS)
configure_error_handlers(app)
configure_database(app)
configure_context_processors(app)
configure_template_filters(app)
configure_extensions(app)
configure_before_request(app)
configure_views(app)
return app
def configure_app(app, config):
app.config.from_object(config)
app.config.from_envvar("APP_CONFIG", silent=True) # avaiable in the server
def configure_blueprints(app, blueprints):
for blueprint_config in blueprints:
blueprint, kw = None, {}
if (isinstance(blueprint_config, basestring)):
blueprint = blueprint_config
elif (isinstance(blueprint_config, dict)):
blueprint = blueprint_config[0]
kw = blueprint_config[1]
blueprint = __import_blueprint(blueprint)
app.register_blueprint(blueprint, **kw)
def configure_error_handlers(app):
@app.errorhandler(403)
def forbidden_page(error):
"""
The server understood the request, but is refusing to fulfill it.
Authorization will not help and the request SHOULD NOT be repeated.
If the request method was not HEAD and the server wishes to make public
why the request has not been fulfilled, it SHOULD describe the reason
for the refusal in the entity. If the server does not wish to make this
information available to the client, the status code 404 (Not Found)
can be used instead.
"""
return render_template("access_forbidden.html"), 403
@app.errorhandler(404)
def page_not_found(error):
"""
The server has not found anything matching the Request-URI.
No indication is given of whether the condition is temporary
or permanent. The 410 (Gone) status code SHOULD be used if
the server knows, through some internally configurable mechanism,
that an old resource is permanently unavailable and has no
forwarding address. This status code is commonly used when
the server does not wish to reveal exactly why the request
has been refused, or when no other response is applicable.
"""
return render_template("page_not_found.html"), 404
@app.errorhandler(405)
def method_not_allowed_page(error):
"""
The method specified in the Request-Line is not allowed for
the resource identified by the Request-URI. The response
MUST include an Allow header containing a list of valid
methods for the requested resource.
"""
return render_template("method_not_allowed.html"), 405
@app.errorhandler(500)
def server_error_page(error):
return render_template("server_error.html"), 500
def configure_database(app):
"Database configuration should be set here"
# uncomment for sqlalchemy support
# from database import db
# db.app = app
# db.init_app(app)
def configure_context_processors(app):
"Modify templates context here"
pass
def configure_template_filters(app):
"Configure filters and tags for jinja"
pass
def configure_extensions(app):
"Configure extensions like mail and login here"
pass
def configure_before_request(app):
pass
def configure_views(app):
"Add some simple views here like index_view"
pass