-
Notifications
You must be signed in to change notification settings - Fork 1
/
server.py
123 lines (84 loc) · 2.95 KB
/
server.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
from flask import Flask, Response, jsonify, make_response, request
from flask_cors import CORS
from qlit.thesaurus import TermNotFoundError, Termset, Thesaurus
from qlit.simple import SimpleThesaurus, name_to_ref
app = Flask(__name__)
CORS(app)
THESAURUS = Thesaurus().parse('qlit.nt')
print(f'Loaded thesaurus with {len(THESAURUS.refs())} terms')
THESAURUS_SIMPLE = SimpleThesaurus(THESAURUS)
FORMATS = {
'ttl': 'text/turtle',
'jsonld': 'application/ld+json',
'xml': 'application/rdf+xml',
}
def find_mimetype() -> str:
# First prio: `format` param
format_param = request.args.get('format')
if format_param and FORMATS.get(format_param):
return FORMATS.get(format_param)
# Next prio: `Accept` header
header_mimetype = request.accept_mimetypes.best
if header_mimetype and header_mimetype in FORMATS.values():
return header_mimetype
# Fall back to Turtle
return 'text/turtle'
def termset_response(termset: Termset) -> Response:
"""Use preferred MIME type for serialization and response."""
mimetype = find_mimetype()
data = termset.serialize(format=mimetype)
# Specify encoding.
if mimetype.startswith('text/'):
mimetype += '; charset=utf-8'
return make_response(data, 200, {'Content-Type': mimetype})
# "Rdf" routes are in RDF space.
@app.route('/')
def rdf_all():
return termset_response(THESAURUS)
@app.route('/<name>')
def rdf_one(name):
ref = name_to_ref(name)
return termset_response(THESAURUS.get(ref))
# "Api" routes are in simple non-RDF space.
@app.route("/api/term/<name>")
def api_one(name):
return jsonify(THESAURUS_SIMPLE.get(name))
@app.route("/api/labels")
def api_labels():
return jsonify(THESAURUS_SIMPLE.get_labels())
@app.route("/api/search")
def api_search():
# TODO Handle missing/bad arg
s = request.args.get('s')
return jsonify(THESAURUS_SIMPLE.search(s))
@app.route("/api/collections")
def api_collections():
return jsonify(THESAURUS_SIMPLE.get_collections())
@app.route("/api/collections/<name>")
def api_collection(name):
tree = bool(request.args.get('tree'))
return jsonify(THESAURUS_SIMPLE.get_collection(name, tree))
@app.route("/api/roots")
def api_roots():
return jsonify(THESAURUS_SIMPLE.get_roots())
@app.route("/api/narrower")
def api_narrower():
# TODO Handle missing/bad arg
broader = request.args.get('broader')
return jsonify(THESAURUS_SIMPLE.get_narrower(broader))
@app.route("/api/broader")
def api_broader():
# TODO Handle missing/bad arg
narrower = request.args.get('narrower')
return jsonify(THESAURUS_SIMPLE.get_broader(narrower))
@app.route("/api/related")
def api_related():
# TODO Handle missing/bad arg
other = request.args.get('other')
return jsonify(THESAURUS_SIMPLE.get_related(other))
@app.errorhandler(TermNotFoundError)
def handle_term_not_found(e):
return make_response(jsonify({
'status': 'error',
'message': str(e),
}), 404)