api.py 5.38 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 17 18
        "required": True,
        "default": 0
    },
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
19 20 21 22 23 24
    "with_parameters": {
        "aliases": ['withparameters',
                    'with-parameters'],
        "options": "boolean",
        "default": False,
        "required": True
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
25
    },
26 27 28
    "plugin_type": {
        "@id": "pluginType",
        "description": 'What kind of plugins to list',
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
29
        "aliases": ["pluginType"],
30 31 32
        "required": True,
        "default": "analysisPlugin"
    },
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
33 34 35 36
    "outformat": {
        "@id": "outformat",
        "aliases": ["o"],
        "default": "json-ld",
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
37
        "required": True,
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
38
        "options": ["json-ld", "turtle"],
39 40 41 42
    },
    "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
43
        "aliases": ["h"],
44
        "required": True,
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
45 46 47 48 49 50 51 52 53 54 55 56 57 58
        "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"
59 60 61 62 63
    }
}

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

CLI_PARAMS = {
    "plugin_folder": {
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
73
        "aliases": ["folder"],
74 75 76
        "required": True,
        "default": "."
    },
J. Fernando Sánchez's avatar
YAPFed  
J. Fernando Sánchez committed
77
}
78 79 80 81

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


J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
121 122 123 124
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
125
    outdict = indict.copy()
126
    wrong_params = {}
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
    for spec in specs:
        for param, options in iteritems(spec):
            if param[0] != "@":  # Exclude json-ld properties
                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 options.get("required", False) and "default" not in options:
                        wrong_params[param] = spec[param]
                    else:
                        if "default" in options:
                            outdict[param] = options["default"]
                elif "options" in spec[param]:
                    if spec[param]["options"] == "boolean":
                        outdict[param] = outdict[param] in [None, True, 'true', '1']
                    elif outdict[param] not in spec[param]["options"]:
                        wrong_params[param] = spec[param]
147
    if wrong_params:
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
148
        logger.debug("Error parsing: %s", wrong_params)
J. Fernando Sánchez's avatar
YAPFed  
J. Fernando Sánchez committed
149
        message = Error(
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
150
            status=400,
J. Fernando Sánchez's avatar
YAPFed  
J. Fernando Sánchez committed
151 152 153 154
            message="Missing or invalid parameters",
            parameters=outdict,
            errors={param: error
                    for param, error in iteritems(wrong_params)})
155
        raise message
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
156 157
    if 'algorithm' in outdict and isinstance(outdict['algorithm'], str):
        outdict['algorithm'] = outdict['algorithm'].split(',')
158
    return outdict
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182


def get_extra_params(request, plugin=None):
    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:
        raise NotImplemented('Informat {} is not implemented'.format(params['informat']))
    results.parameters = params
    return results