api.py 2.16 KB
Newer Older
1
2
3
4
#
# Copyright The NOMAD Authors.
#
# This file is part of NOMAD. See https://nomad-lab.eu for further info.
5
6
7
8
9
#
# 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
#
10
#     http://www.apache.org/licenses/LICENSE-2.0
11
12
#
# Unless required by applicable law or agreed to in writing, software
13
# distributed under the License is distributed on an "AS IS" BASIS,
14
15
16
# 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.
17
#
18

19
20
from flask import Blueprint, Response
from flask_restplus import Api, reqparse
21
import urllib.parse
22
from rdflib import Graph
23
24
25
26
27

from nomad import config

blueprint = Blueprint('dcat', __name__)

28
base_url = config.api_url(api='dcat')
29
30
31
32


def url(*args, **kwargs):
    ''' Returns the full dcat api url for the given path (args) and query (kwargs) parameters. '''
33
    url = f'{base_url.rstrip("/")}/{"/".join(args).lstrip("/")}'
34
35

    if len(kwargs) > 0:
36
        return f'{url}?{urllib.parse.urlencode(kwargs)}'
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
    else:
        return url


api = Api(
    blueprint,
    version='1.0', title='NOMAD\'s API for servicing dcat resources',
    description='NOMAD\'s API for serving dcat resources',
    validate=True)


# For some unknown reason it is necessary for each fr api to have a handler.
# Otherwise the global app error handler won't be called.
@api.errorhandler(Exception)
def errorhandler(error):
    '''When an internal server error is caused by an unexpected exception.'''
    return str(error)
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74


arg_parser = reqparse.RequestParser()
arg_parser.add_argument('format', type=str, choices=[
    'xml',
    'n3',
    'turtle',
    'nt',
    'pretty-xml',
    'trig'])


def rdf_respose(g: Graph) -> Response:
    args = arg_parser.parse_args()
    format_ = args.get('format')
    if format_ is None:
        format_ = 'pretty-xml'
    content_type = 'application/xml' if format in ['xml', 'pretty-xml'] else 'text/%s' % format_
    return Response(
        g.serialize(format=format_).decode('utf-8'), 200,
        {'Content-Type': content_type})