blueprints.py 4.26 KB
Newer Older
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
1 2
#!/usr/bin/python
# -*- coding: utf-8 -*-
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
3 4
# Copyright 2014 J. Fernando Sánchez Rada - Grupo de Sistemas Inteligentes
# DIT, UPM
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
5
#
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
6 7 8
# 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
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
9
#
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
10
# http://www.apache.org/licenses/LICENSE-2.0
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
11
#
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
12
# Unless required by applicable law or agreed to in writing, software
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
13 14 15 16
#    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.
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
17 18 19
"""
Blueprints for Senpy
"""
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
20 21
from flask import (Blueprint, request, current_app, render_template, url_for,
                   jsonify)
22
from .models import Error, Response, Plugins, read_schema
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
23 24
from .api import WEB_PARAMS, API_PARAMS, parse_params
from .version import __version__
25
from functools import wraps
26

J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
27
import logging
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
28

J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
29 30
logger = logging.getLogger(__name__)

31 32
api_blueprint = Blueprint("api", __name__)
demo_blueprint = Blueprint("demo", __name__)
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
33
ns_blueprint = Blueprint("ns", __name__)
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
34

J. Fernando Sánchez's avatar
YAPFed  
J. Fernando Sánchez committed
35

36
def get_params(req):
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
37
    if req.method == 'POST':
38
        indict = req.form.to_dict(flat=True)
J. Fernando Sánchez's avatar
Oups  
J. Fernando Sánchez committed
39
    elif req.method == 'GET':
40
        indict = req.args.to_dict(flat=True)
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
41
    else:
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
42
        raise Error(message="Invalid data")
43
    return indict
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
44

J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
45

J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
46
@demo_blueprint.route('/')
Ignacio Corcuera's avatar
Ignacio Corcuera committed
47
def index():
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
48
    return render_template("index.html", version=__version__)
Ignacio Corcuera's avatar
Ignacio Corcuera committed
49

J. Fernando Sánchez's avatar
YAPFed  
J. Fernando Sánchez committed
50

51 52
@api_blueprint.route('/contexts/<entity>.jsonld')
def context(entity="context"):
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
53 54 55 56 57 58 59 60 61 62
    context = Response._context
    context['@vocab'] = url_for('ns.index', _external=True)
    return jsonify({"@context": context})


@ns_blueprint.route('/')  # noqa: F811
def index():
    context = Response._context
    context['@vocab'] = url_for('.ns', _external=True)
    return jsonify({"@context": context})
Ignacio Corcuera's avatar
Ignacio Corcuera committed
63

J. Fernando Sánchez's avatar
YAPFed  
J. Fernando Sánchez committed
64

65 66
@api_blueprint.route('/schemas/<schema>')
def schema(schema="definitions"):
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
67
    try:
68
        return jsonify(read_schema(schema))
J. Fernando Sánchez's avatar
YAPFed  
J. Fernando Sánchez committed
69
    except Exception:  # Should be FileNotFoundError, but it's missing from py2
70 71
        return Error(message="Schema not found", status=404).flask()

J. Fernando Sánchez's avatar
YAPFed  
J. Fernando Sánchez committed
72

73 74 75
def basic_api(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
76
        raw_params = get_params(request)
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
77 78 79 80
        headers = {'X-ORIGINAL-PARAMS': raw_params}
        # Get defaults
        web_params = parse_params({}, spec=WEB_PARAMS)
        api_params = parse_params({}, spec=API_PARAMS)
81

J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
82
        outformat = 'json-ld'
83
        try:
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
84 85 86 87 88 89 90 91
            print('Getting request:')
            print(request)
            web_params = parse_params(raw_params, spec=WEB_PARAMS)
            api_params = parse_params(raw_params, spec=API_PARAMS)
            if hasattr(request, 'params'):
                request.params.update(api_params)
            else:
                request.params = api_params
92 93 94
            response = f(*args, **kwargs)
        except Error as ex:
            response = ex
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
95 96 97 98 99

        in_headers = web_params['inHeaders'] != "0"
        expanded = api_params['expanded-jsonld']
        outformat = api_params['outformat']

J. Fernando Sánchez's avatar
YAPFed  
J. Fernando Sánchez committed
100 101 102
        return response.flask(
            in_headers=in_headers,
            headers=headers,
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
103 104 105 106 107 108
            prefix=url_for('.api', _external=True),
            context_uri=url_for('api.context',
                                entity=type(response).__name__,
                                _external=True),
            outformat=outformat,
            expanded=expanded)
J. Fernando Sánchez's avatar
YAPFed  
J. Fernando Sánchez committed
109

110
    return decorated_function
J. Fernando Sánchez's avatar
YAPFed  
J. Fernando Sánchez committed
111 112


113 114 115 116 117 118 119 120 121
@api_blueprint.route('/', methods=['POST', 'GET'])
@basic_api
def api():
    response = current_app.senpy.analyse(**request.params)
    return response


@api_blueprint.route('/plugins/', methods=['POST', 'GET'])
@basic_api
122 123 124
def plugins():
    sp = current_app.senpy
    dic = Plugins(plugins=list(sp.plugins.values()))
125
    return dic
J. Fernando Sánchez's avatar
YAPFed  
J. Fernando Sánchez committed
126 127


128 129
@api_blueprint.route('/plugins/<plugin>/', methods=['POST', 'GET'])
@basic_api
130
def plugin(plugin=None):
131
    sp = current_app.senpy
132
    if plugin == 'default' and sp.default_plugin:
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
133 134 135 136 137
        return sp.default_plugin
    plugins = sp.filter_plugins(
        id='plugins/{}'.format(plugin)) or sp.filter_plugins(name=plugin)
    if plugins:
        response = list(plugins.values())[0]
138
    else:
139
        return Error(message="Plugin not found", status=404)
140
    return response