blueprints.py 4.74 KB
Newer Older
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/usr/bin/python
# -*- coding: utf-8 -*-
#    Copyright 2014 J. Fernando Sánchez Rada - Grupo de Sistemas Inteligentes
#                                                       DIT, UPM
#
#    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.
'''
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
18
Simple Sentiment Analysis server
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
19
20
'''
import json
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
21
22
23
24
import logging
logger = logging.getLogger(__name__)

from flask import Blueprint, render_template, request, jsonify, current_app
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
25

26
nif_blueprint = Blueprint("NIF Sentiment Analysis Server", __name__)
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
27

28
29
30
31
32
BASIC_PARAMS = {
    "algorithm": {"aliases": ["algorithm", "a", "algo"],
                  "required": False,
                  },
}
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
33

34
def get_params(req, params=BASIC_PARAMS):
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
35
36
37
    indict = None
    if req.method == 'POST':
        indict = req.form
J. Fernando Sánchez's avatar
Oups    
J. Fernando Sánchez committed
38
    elif req.method == 'GET':
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
39
40
41
42
43
        indict = req.args
    else:
        raise ValueError("Invalid data")

    outdict = {}
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
44
    wrongParams = {}
45
    for param, options in params.iteritems():
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
46
47
48
49
        for alias in options["aliases"]:
            if alias in indict:
                outdict[param] = indict[alias]
        if param not in outdict:
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
50
            if options.get("required", False):
51
                wrongParams[param] = params[param]
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
52
            else:
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
53
54
55
                if "default" in options:
                    outdict[param] = options["default"]
        else:
56
57
58
            if "options" in params[param] and \
                outdict[param] not in params[param]["options"]:
                wrongParams[param] = params[param]
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
59
60
61
62
    if wrongParams:
        message = {"status": "failed", "message": "Missing or invalid parameters"}
        message["parameters"] = outdict
        message["errors"] = {param:error for param, error in wrongParams.iteritems()}
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
63
64
65
66
        raise ValueError(json.dumps(message))
    return outdict

def basic_analysis(params):
67
68
69
70
71
    response = {"@context": ["http://demos.gsi.dit.upm.es/eurosentiment/static/context.jsonld",
                             {
                                 "@base": "{}#".format(request.url.encode('utf-8'))
                             }
                             ],
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
72
73
74
75
76
77
78
                "analysis": [{
                    "@type": "marl:SentimentAnalysis"
                }],
                "entries": []
                }
    if "language" in params:
        response["language"] = params["language"]
79
    for idx, sentence in enumerate(params["input"].split(".")):
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
80
        response["entries"].append({
81
            "@id": "Sentence{}".format(idx),
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
82
83
84
85
            "nif:isString": sentence
        })
    return response

86
@nif_blueprint.route('/', methods=['POST', 'GET'])
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
87
88
def home(entries=None):
    try:
89
90
        algo = get_params(request).get("algorithm", None)
        specific_params = current_app.senpy.parameters(algo)
91
        params = get_params(request, specific_params)
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
92
93
        response = current_app.senpy.analyse(**params)
        return jsonify(response)
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
94
95
    except ValueError as ex:
        return ex.message
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
96
97
    except Exception as ex:
        return jsonify(status="400", message=ex.message)
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
98

99
100
101
102
103
@nif_blueprint.route("/default")
def default():
    return current_app.senpy.default_plugin
    #return plugins(action="list", plugin=current_app.senpy.default_algorithm)

104
105
106
107
@nif_blueprint.route('/plugins/', methods=['POST', 'GET'])
@nif_blueprint.route('/plugins/<plugin>', methods=['POST', 'GET'])
@nif_blueprint.route('/plugins/<plugin>/<action>', methods=['POST', 'GET'])
def plugins(plugin=None, action="list"):
108
    filt = {}
109
    if plugin:
110
111
112
113
        filt["name"] = plugin
    plugs = current_app.senpy.filter_plugins(**filt)
    if plugin and not plugs:
        return "Plugin not found", 400
114
    if action == "list":
115
116
        with_params = request.args.get("params", "") == "1"
        dic = {plug:plugs[plug].jsonable(with_params) for plug in plugs}
117
        return jsonify(dic)
118
119
    if action == "disable":
        current_app.senpy.disable_plugin(plugin)
120
121
        return "Ok"
    elif action == "enable":
122
123
124
125
        current_app.senpy.enable_plugin(plugin)
        return "Ok"
    elif action == "reload":
        current_app.senpy.reload_plugin(plugin)
126
127
        return "Ok"
    else:
128
        return "action '{}' not allowed".format(action), 400
129

J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
130
if __name__ == '__main__':
131
    import config
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
132
133
    from flask import Flask
    app = Flask(__name__)
134
    app.register_blueprint(nif_blueprint)
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
135
136
    app.debug = config.DEBUG
    app.run()