Passed
Pull Request — master (#409)
by Jace
01:39
created

configure_exceptions()   A

Complexity

Conditions 2

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 7
ccs 5
cts 5
cp 1
cc 2
crap 2
rs 9.4285
1 1
import os
2 1
import logging
3 1
4 1
from flask import request, current_app
5
from flask_api import FlaskAPI
6 1
from flask_api.exceptions import APIException, NotFound
7 1
import bugsnag
8 1
from bugsnag.flask import handle_exceptions
9
10 1
from . import extensions
11 1
from . import services
12 1
from . import stores
13 1
from . import routes
14
15
16 1
log = logging.getLogger('api')
17
18
19 1
class TemplateNotFound(NotFound):
20 1
    detail = "Template not found."
21
22
23 1
class InvalidMaskedCode(NotFound):
24 1
    detail = "Masked URL does not match any image."
25
26
27 1
class FilenameTooLong(APIException):
28 1
    status_code = 414
29 1
    detail = "Filename too long."
30
31
32 1
class InvalidImageLink(APIException):
33 1
    status_code = 415
34 1
    detail = "Unsupported image type."
35
36
37 1
def create_app(config):
38 1
    app = FlaskAPI(__name__)
39 1
    app.config.from_object(config)
40
41 1
    configure_exceptions(app)
42
    configure_logging(app)
43 1
44 1
    register_extensions(app)
45 1
    register_services(app)
46
    register_blueprints(app)
47 1
48
    return app
49 1
50
51
def configure_exceptions(app):
52 1
    if app.config['BUGSNAG_API_KEY']:  # pragma: no cover
53 1
        bugsnag.configure(
54
            api_key=app.config['BUGSNAG_API_KEY'],
55 1
            project_root=app.config['ROOT'],
56 1
        )
57 1
        handle_exceptions(app)
58
59
60 1
def configure_logging(app):
61 1
    logging.basicConfig(level=app.config['LOG_LEVEL'],
62
                        format="%(levelname)s: %(message)s")
63
    logging.getLogger('werkzeug').setLevel(logging.WARNING)
64 1
    logging.getLogger('yorm').setLevel(logging.WARNING)
65 1
    logging.getLogger('requests').setLevel(logging.WARNING)
66
    logging.getLogger('PIL').setLevel(logging.INFO)
67
68
69
def register_extensions(app):
70
    extensions.cors.init_app(app, methods=['GET', 'OPTIONS'], allow_headers='*')
71
    extensions.cache_control.init_app(app)
72 1
73 1
74
def register_services(app):
75 1
    exceptions = services.Exceptions(
76 1
        TemplateNotFound,
77
        InvalidMaskedCode,
78 1
        FilenameTooLong,
79 1
        InvalidImageLink,
80
    )
81 1
82
    templates_root = os.path.join(app.config['ROOT'], 'data', 'templates')
83
    template_store = stores.template.TemplateStore(templates_root)
84
85 1
    fonts_root = os.path.join(app.config['ROOT'], 'data', 'fonts')
86
    font_store = stores.font.FontStore(fonts_root)
87
88
    images_root = os.path.join(app.config['ROOT'], 'data', 'images')
89 1
    image_store = stores.image.ImageStore(images_root, app.config)
90
91
    app.link_service = services.link.LinkService(
92
        exceptions=exceptions,
93 1
        template_store=template_store,
94
    )
95
    app.template_service = services.template.TemplateService(
96
        exceptions=exceptions,
97
        template_store=template_store,
98
    )
99
    app.font_service = services.font.FontService(
100 1
        exceptions=exceptions,
101 1
        font_store=font_store
102 1
    )
103 1
    app.image_service = services.image.ImageService(
104 1
        exceptions=exceptions,
105 1
        template_store=template_store,
106
        font_store=font_store,
107 1
        image_store=image_store,
108
    )
109 1
110
    def log_request(response=None):
111
        if current_app.debug:
112 1
            status = response.status_code if response else ''
113 1
            log.info(f"{request.method}: {request.full_path} - {status}")
114 1
115 1
        return response
116 1
117 1
    app.before_request(log_request)
118 1
    app.after_request(log_request)
119 1
120 1
121 1
def register_blueprints(app):
122 1
    app.register_blueprint(routes.api_aliases.blueprint)
123 1
    app.register_blueprint(routes.api_fonts.blueprint)
124 1
    app.register_blueprint(routes.api_legacy.blueprint)
125
    app.register_blueprint(routes.api_links.blueprint)
126
    app.register_blueprint(routes.api_root.blueprint)
127 1
    app.register_blueprint(routes.api_search.blueprint)
128
    app.register_blueprint(routes.api_templates.blueprint)
129 1
    app.register_blueprint(routes.custom.blueprint)
130 1
    app.register_blueprint(routes.examples.blueprint)
131 1
    app.register_blueprint(routes.image.blueprint)
132 1
    app.register_blueprint(routes.index.blueprint)
133 1
    app.register_blueprint(routes.latest.blueprint)
134
    app.register_blueprint(routes.static.blueprint)
135