api.py 5.41 KB
Newer Older
1
from future.utils import iteritems
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
2
from .models import Error, Results, Entry, from_string
3 4 5 6 7
import logging
logger = logging.getLogger(__name__)

API_PARAMS = {
    "algorithm": {
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
8
        "aliases": ["algorithms", "a", "algo"],
9
        "required": False,
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
10 11
        "description": ("Algorithms that will be used to process the request."
                        "It may be a list of comma-separated names."),
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
12 13 14
    },
    "expanded-jsonld": {
        "@id": "expanded-jsonld",
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
15
        "aliases": ["expanded"],
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
16
        "options": "boolean",
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
17
        "required": True,
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
18
        "default": False
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
19
    },
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
20 21 22 23 24 25
    "with_parameters": {
        "aliases": ['withparameters',
                    'with-parameters'],
        "options": "boolean",
        "default": False,
        "required": True
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
26
    },
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
27 28 29 30
    "outformat": {
        "@id": "outformat",
        "aliases": ["o"],
        "default": "json-ld",
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
31
        "required": True,
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
32
        "options": ["json-ld", "turtle"],
33 34 35 36
    },
    "help": {
        "@id": "help",
        "description": "Show additional help to know more about the possible parameters",
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
37
        "aliases": ["h"],
38
        "required": True,
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
39 40 41 42 43 44 45 46 47 48 49 50 51 52
        "options": "boolean",
        "default": False
    },
    "emotionModel": {
        "@id": "emotionModel",
        "aliases": ["emoModel"],
        "required": False
    },
    "conversion": {
        "@id": "conversion",
        "description": "How to show the elements that have (not) been converted",
        "required": True,
        "options": ["filtered", "nested", "full"],
        "default": "full"
53 54 55
    }
}

J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
56 57 58 59 60 61 62 63 64 65
PLUGINS_PARAMS = {
    "plugin_type": {
        "@id": "pluginType",
        "description": 'What kind of plugins to list',
        "aliases": ["pluginType"],
        "required": True,
        "default": 'analysisPlugin'
    }
}

66 67
WEB_PARAMS = {
    "inHeaders": {
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
68
        "aliases": ["headers"],
69
        "required": True,
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
70 71
        "default": False,
        "options": "boolean"
72 73 74 75 76
    },
}

CLI_PARAMS = {
    "plugin_folder": {
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
77
        "aliases": ["folder"],
78 79 80
        "required": True,
        "default": "."
    },
J. Fernando Sánchez's avatar
YAPFed  
J. Fernando Sánchez committed
81
}
82 83 84 85

NIF_PARAMS = {
    "input": {
        "@id": "input",
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
86
        "aliases": ["i"],
87 88 89 90 91
        "required": True,
        "help": "Input text"
    },
    "intype": {
        "@id": "intype",
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
92
        "aliases": ["t"],
93 94 95 96
        "required": False,
        "default": "direct",
        "options": ["direct", "url", "file"],
    },
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
97 98 99 100 101 102 103
    "informat": {
        "@id": "informat",
        "aliases": ["f"],
        "required": False,
        "default": "text",
        "options": ["turtle", "text", "json-ld"],
    },
104 105
    "language": {
        "@id": "language",
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
106
        "aliases": ["l"],
107 108 109 110
        "required": False,
    },
    "prefix": {
        "@id": "prefix",
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
111
        "aliases": ["p"],
112 113 114 115 116
        "required": True,
        "default": "",
    },
    "urischeme": {
        "@id": "urischeme",
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
117
        "aliases": ["u"],
118 119 120
        "required": False,
        "default": "RFC5147String",
        "options": "RFC5147String"
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
121
    }
122 123 124
}


J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
125 126 127 128
def parse_params(indict, *specs):
    if not specs:
        specs = [NIF_PARAMS]
    logger.debug("Parsing: {}\n{}".format(indict, specs))
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
129
    outdict = indict.copy()
130
    wrong_params = {}
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
131 132
    for spec in specs:
        for param, options in iteritems(spec):
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
            if param[0] == "@":  # Exclude json-ld properties
                continue
            for alias in options.get("aliases", []):
                # Replace each alias with the correct name of the parameter
                if alias in indict and alias is not param:
                    outdict[param] = indict[alias]
                    del indict[alias]
                    continue
            if param not in outdict:
                if "default" in options:
                    # We assume the default is correct
                    outdict[param] = options["default"]
                elif options.get("required", False):
                    wrong_params[param] = spec[param]
                continue
            if "options" in options:
                if options["options"] == "boolean":
                    outdict[param] = outdict[param] in [None, True, 'true', '1']
                elif outdict[param] not in options["options"]:
                    wrong_params[param] = spec[param]
153
    if wrong_params:
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
154
        logger.debug("Error parsing: %s", wrong_params)
J. Fernando Sánchez's avatar
YAPFed  
J. Fernando Sánchez committed
155
        message = Error(
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
156
            status=400,
J. Fernando Sánchez's avatar
YAPFed  
J. Fernando Sánchez committed
157 158 159 160
            message="Missing or invalid parameters",
            parameters=outdict,
            errors={param: error
                    for param, error in iteritems(wrong_params)})
161
        raise message
162
    if 'algorithm' in outdict and not isinstance(outdict['algorithm'], list):
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
163
        outdict['algorithm'] = outdict['algorithm'].split(',')
164
    return outdict
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
165 166


J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
167
def parse_extra_params(request, plugin=None):
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
    params = request.parameters.copy()
    if plugin:
        extra_params = parse_params(params, plugin.get('extra_params', {}))
        params.update(extra_params)
    return params


def parse_call(params):
    '''Return a results object based on the parameters used in a call/request.
    '''
    params = parse_params(params, NIF_PARAMS)
    if params['informat'] == 'text':
        results = Results()
        entry = Entry(nif__isString=params['input'])
        results.entries.append(entry)
    elif params['informat'] == 'json-ld':
        results = from_string(params['input'], cls=Results)
    else:
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
186
        raise NotImplementedError('Informat {} is not implemented'.format(params['informat']))
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
187 188
    results.parameters = params
    return results