__init__.py 2.63 KB
Newer Older
Pierre Dittgen's avatar
Pierre Dittgen committed
1
import json
Christophe Benz's avatar
Christophe Benz committed
2
import logging
3
import os
4
import re
5 6
from pathlib import Path

7
import cachecontrol
8 9
import flask
import jinja2
Christophe Benz's avatar
Christophe Benz committed
10
import pkg_resources
11 12
import requests
import tableschema
Pierre Dittgen's avatar
Pierre Dittgen committed
13
from commonmark import commonmark
14

15 16
import opendataschema

17
from . import config
18

Christophe Benz's avatar
Christophe Benz committed
19 20
log = logging.getLogger(__name__)

21

22 23 24
def generate_schema_from_url_func(session):
    """Generates a function that encloses session"""

25 26 27 28 29
    def tableschema_from_url(url):
        response = session.get(url)
        response.raise_for_status()
        descriptor = response.json()
        return tableschema.Schema(descriptor)
30

31 32 33
    return tableschema_from_url


34 35 36 37 38 39
class SchemaCatalogRegistry:
    """Retain section_name -> catalog url matching
    and creates SchemaCatalog instance on demand"""

    def __init__(self, session):
        self.session = session
40
        self.ref_map = {}
41

42 43
    def add_ref(self, name, ref):
        self.ref_map[name] = ref
44 45

    def build_schema_catalog(self, name):
46 47 48 49 50 51 52 53 54
        ref = self.ref_map.get(name)
        if not ref:
            return None
        try:
            catalog = opendataschema.SchemaCatalog(ref, session=self.session)
        except requests.exceptions.RequestException as exc:
            log.exception(exc)
            return None
        return catalog
55 56


57 58
caching_session = cachecontrol.CacheControl(requests.Session())
tableschema_from_url = generate_schema_from_url_func(caching_session)
59

60
# And load schema catalogs which URLs are found in homepage_config.json
61
schema_catalog_registry = SchemaCatalogRegistry(caching_session)
62
if config.HOMEPAGE_CONFIG:
Christophe Benz's avatar
Christophe Benz committed
63
    log.info("Initializing homepage sections...")
64
    for section in config.HOMEPAGE_CONFIG['sections']:
Christophe Benz's avatar
Christophe Benz committed
65 66
        name = section['name']
        log.info('Initializing homepage section "{}"...'.format(name))
67
        catalog_ref = section.get('catalog')
68
        if catalog_ref:
69
            schema_catalog_registry.add_ref(name, catalog_ref)
70
    log.info("...done")
71 72

# Flask things
73
app = flask.Flask(__name__)
74 75
app.secret_key = config.SECRET_KEY

76 77 78 79
# Jinja2 url_quote_plus custom filter
# https://stackoverflow.com/questions/12288454/how-to-import-custom-jinja2-filters-from-another-file-and-using-flask
blueprint = flask.Blueprint('filters', __name__)

80

Pierre Dittgen's avatar
Pierre Dittgen committed
81 82 83 84 85 86 87 88 89
@jinja2.contextfilter
@blueprint.app_template_filter()
def commonmark2html(context, value):
    return commonmark(value)


app.register_blueprint(blueprint)


90 91
@app.context_processor
def inject_version():
92
    return {"validata_ui_version": pkg_resources.get_distribution("validata-ui").version}
93 94


95 96 97 98 99
@app.context_processor
def inject_config():
    return {"config": config}


100
# Keep this import after app initialisation (to avoid cyclic imports)
101
from . import views  # noqa isort:skip