rycus86/demo-site

View on GitHub
src/app.py

Summary

Maintainability
A
0 mins
Test Coverage
from flask import Flask, request, make_response, render_template, send_from_directory
from flask_caching import Cache
from prometheus_flask_exporter import PrometheusMetrics

from utils import *

app = Flask(__name__)
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 30 * 24 * 60 * 60  # 1 month

cache = Cache(app, config={'CACHE_TYPE': 'simple'})
metrics = PrometheusMetrics(app)

metrics.info('flask_app_info', 'Application info',
             version=os.environ.get('GIT_COMMIT') or 'unknown')

metrics.info(
    'flask_app_built_at', 'Application build timestamp'
).set(
    float(os.environ.get('BUILD_TIMESTAMP') or '0')
)


@app.route('/')
def main():
    resources = load_resources()
    first_tab = resources.get('tabs')[0].get('key')
    return page(first_tab)


@app.route('/page/<key>')
@cache.memoize(timeout=7 * 24 * 60 * 60)  # 1 week
def page(key):
    resources = load_resources()
    if key not in (tab.get('key') for tab in resources.get('tabs')):
        return page_not_found('Missing tab: %s' % key)

    current_tab = next(tab for tab in resources.get('tabs') if tab.get('key') == key)

    response = make_response(render_template('layout.html',
                                             selected_tab=key,
                                             seo_data=current_tab.get('seo'),
                                             markdown=process_markdown,
                                             assets=load_static_asset_mappings(),
                                             read=read_resource_file,
                                             **resources))

    add_preload_headers(response)

    return response


def add_preload_headers(response):
    assets = load_static_asset_mappings()

    for name, link in assets.items():
        if name.endswith('.css'):
            response.headers.add('Link', '<%s>; rel=preload; as=style' % link)

        elif name.endswith('.js'):
            response.headers.add('Link', '<%s>; rel=preload; as=script' % link)


@app.route('/render/<template>', methods=['POST'])
def render(template):
    return render_template('render/%s.html' % template, data=request.json, markdown=process_markdown)


@app.route('/markdown', methods=['POST'])
def render_markdown():
    return process_markdown(request.data.decode('utf-8'))


@app.route('/favicon.ico')
@metrics.do_not_track()
def favicon():
    return send_from_directory('assets', 'favicon.ico')


@app.route('/asset/<hash>/<path:asset_file>')
@metrics.do_not_track()
@metrics.histogram('flask_http_static_asset',
                   'HTTP request metrics for static assets by type',
                   labels={'status': lambda r: r.status_code,
                           'extension': lambda: os.path.splitext(request.path)[1]},
                   buckets=(0.005, 0.01, 0.05, 0.1, 1, 5))
def asset(hash, asset_file):
    return send_from_directory('assets', asset_file)


@app.errorhandler(404)
def page_not_found(error):
    return render_template('404.html'), 404


if __name__ == '__main__':  # pragma: no cover
    app.run(host=os.environ.get('HTTP_HOST', '127.0.0.1'),
            port=int(os.environ.get('HTTP_PORT', '5000')),
            threaded=True, debug=False)