openbel-api 0.4.0-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +7 -0
  2. data/.gemspec +65 -0
  3. data/CHANGELOG.md +22 -0
  4. data/INSTALL.md +19 -0
  5. data/INSTALL_RUBY.md +107 -0
  6. data/LICENSE +191 -0
  7. data/README.md +208 -0
  8. data/app/openbel/api/app.rb +83 -0
  9. data/app/openbel/api/config.rb +45 -0
  10. data/app/openbel/api/config.ru +3 -0
  11. data/app/openbel/api/helpers/pager.rb +109 -0
  12. data/app/openbel/api/middleware/auth.rb +112 -0
  13. data/app/openbel/api/resources/adapters/basic_json.rb +52 -0
  14. data/app/openbel/api/resources/annotation.rb +141 -0
  15. data/app/openbel/api/resources/base.rb +16 -0
  16. data/app/openbel/api/resources/completion.rb +89 -0
  17. data/app/openbel/api/resources/evidence.rb +115 -0
  18. data/app/openbel/api/resources/evidence_transform.rb +143 -0
  19. data/app/openbel/api/resources/function.rb +98 -0
  20. data/app/openbel/api/resources/match_result.rb +79 -0
  21. data/app/openbel/api/resources/namespace.rb +174 -0
  22. data/app/openbel/api/routes/annotations.rb +168 -0
  23. data/app/openbel/api/routes/authenticate.rb +108 -0
  24. data/app/openbel/api/routes/base.rb +326 -0
  25. data/app/openbel/api/routes/datasets.rb +519 -0
  26. data/app/openbel/api/routes/evidence.rb +330 -0
  27. data/app/openbel/api/routes/expressions.rb +560 -0
  28. data/app/openbel/api/routes/functions.rb +41 -0
  29. data/app/openbel/api/routes/namespaces.rb +382 -0
  30. data/app/openbel/api/routes/root.rb +39 -0
  31. data/app/openbel/api/schemas.rb +34 -0
  32. data/app/openbel/api/schemas/annotation_collection.schema.json +20 -0
  33. data/app/openbel/api/schemas/annotation_resource.schema.json +36 -0
  34. data/app/openbel/api/schemas/annotation_value_collection.schema.json +21 -0
  35. data/app/openbel/api/schemas/annotation_value_resource.schema.json +35 -0
  36. data/app/openbel/api/schemas/completion_collection.schema.json +21 -0
  37. data/app/openbel/api/schemas/completion_resource.schema.json +146 -0
  38. data/app/openbel/api/schemas/evidence.schema.json +198 -0
  39. data/app/openbel/api/schemas/evidence_collection.schema.json +98 -0
  40. data/app/openbel/api/schemas/evidence_resource.schema.json +29 -0
  41. data/app/openbel/api/schemas/namespace_value_collection.schema.json +21 -0
  42. data/app/openbel/api/schemas/namespace_value_resource.schema.json +43 -0
  43. data/app/openbel/api/util.rb +11 -0
  44. data/bin/openbel-api +78 -0
  45. data/bin/openbel-config +46 -0
  46. data/config/async_evidence.rb +12 -0
  47. data/config/async_jena.rb +14 -0
  48. data/config/config.yml +31 -0
  49. data/config/server_config.rb +184 -0
  50. data/lib/openbel/api/cache/cache.rb +30 -0
  51. data/lib/openbel/api/config/config.rb +33 -0
  52. data/lib/openbel/api/evidence/api.rb +39 -0
  53. data/lib/openbel/api/evidence/facet_api.rb +18 -0
  54. data/lib/openbel/api/evidence/facet_filter.rb +83 -0
  55. data/lib/openbel/api/evidence/mongo.rb +247 -0
  56. data/lib/openbel/api/evidence/mongo_facet.rb +105 -0
  57. data/lib/openbel/api/helpers/dependency_graph.rb +52 -0
  58. data/lib/openbel/api/model/rdf_resource.rb +74 -0
  59. data/lib/openbel/api/plugin/cache/kyotocabinet.rb +85 -0
  60. data/lib/openbel/api/plugin/configure_plugins.rb +97 -0
  61. data/lib/openbel/api/plugin/evidence/evidence.rb +58 -0
  62. data/lib/openbel/api/plugin/plugin.rb +99 -0
  63. data/lib/openbel/api/plugin/plugin_manager.rb +20 -0
  64. data/lib/openbel/api/plugin/plugin_repository.rb +60 -0
  65. data/lib/openbel/api/storage/cache_proxy.rb +74 -0
  66. data/lib/openbel/api/storage/triple_storage.rb +43 -0
  67. metadata +379 -0
@@ -0,0 +1,41 @@
1
+ require 'bel'
2
+
3
+ module OpenBEL
4
+ module Routes
5
+
6
+ class Functions < Base
7
+ include BEL::Language
8
+
9
+ SORTED_FUNCTIONS = FUNCTIONS.values.uniq.sort_by { |fx|
10
+ fx[:short_form]
11
+ }
12
+
13
+ options '/api/functions' do
14
+ response.headers['Allow'] = 'OPTIONS,GET'
15
+ status 200
16
+ end
17
+
18
+ options '/api/functions/:fx' do
19
+ response.headers['Allow'] = 'OPTIONS,GET'
20
+ status 200
21
+ end
22
+
23
+ get '/api/functions' do
24
+ render(SORTED_FUNCTIONS, :function_collection)
25
+ end
26
+
27
+ # BEL Completion
28
+ get '/api/functions/:fx' do
29
+ fx_match = FUNCTIONS[params[:fx].to_sym]
30
+ halt 404 unless fx_match
31
+
32
+ render(
33
+ [fx_match],
34
+ :function_collection
35
+ )
36
+ end
37
+ end
38
+ end
39
+ end
40
+ # vim: ts=2 sw=2:
41
+ # encoding: utf-8
@@ -0,0 +1,382 @@
1
+ require 'bel'
2
+ require 'cgi'
3
+ require 'multi_json'
4
+ require 'uri'
5
+
6
+ module OpenBEL
7
+ module Routes
8
+
9
+ # REST API for retrieving namespaces and values. Provides the following capabilities:
10
+ #
11
+ # * Retrieve namespaces.
12
+ # * Retrieve values for a namespace using the identifier, preferred name, or title.
13
+ # * Retrieve equivalences for one or more values.
14
+ # * Retrieve equivalences in a target namespace for one or more values.
15
+ # * Retrieve orthologs for one or more values.
16
+ # * Retrieve orthologs in a target namespace for one or more values.
17
+ class Namespaces < Base
18
+
19
+ RESULT_TYPES = {
20
+ :resource => :all,
21
+ :name => :prefLabel,
22
+ :identifier => :identifier,
23
+ :title => :title
24
+ }
25
+
26
+ def initialize(app)
27
+ super
28
+
29
+ # RdfRepository using Jena.
30
+ @rr = BEL::RdfRepository.plugins[:jena].create_repository(
31
+ :tdb_directory => OpenBEL::Settings[:resource_rdf][:jena][:tdb_directory]
32
+ )
33
+
34
+ # Namespaces using RdfRepository
35
+ @namespaces = BEL::Resource::Namespaces.new(@rr)
36
+
37
+ # Resource Search using SQLite.
38
+ @search = BEL::Resource::Search.plugins[:sqlite].create_search(
39
+ :database_file => OpenBEL::Settings[:resource_search][:sqlite][:database_file]
40
+ )
41
+ end
42
+
43
+ options '/api/namespaces' do
44
+ response.headers['Allow'] = 'OPTIONS,GET'
45
+ status 200
46
+ end
47
+
48
+ options '/api/namespaces/:namespace' do
49
+ response.headers['Allow'] = 'OPTIONS,GET'
50
+ status 200
51
+ end
52
+
53
+ options '/api/namespaces/:namespace/equivalents' do
54
+ response.headers['Allow'] = 'OPTIONS,POST,GET'
55
+ status 200
56
+ end
57
+
58
+ options '/api/namespaces/:namespace/orthologs' do
59
+ response.headers['Allow'] = 'OPTIONS,POST,GET'
60
+ status 200
61
+ end
62
+
63
+ options '/api/namespaces/:namespace/values/:value' do
64
+ response.headers['Allow'] = 'OPTIONS,GET'
65
+ status 200
66
+ end
67
+
68
+ options '/api/namespaces/:namespace/values/:value/equivalents' do
69
+ response.headers['Allow'] = 'OPTIONS,GET'
70
+ status 200
71
+ end
72
+
73
+ options '/api/namespaces/:namespace/values/:value/equivalents/:target' do
74
+ response.headers['Allow'] = 'OPTIONS,GET'
75
+ status 200
76
+ end
77
+
78
+ options '/api/namespaces/:namespace/values/:value/orthologs' do
79
+ response.headers['Allow'] = 'OPTIONS,GET'
80
+ status 200
81
+ end
82
+
83
+ options '/api/namespaces/:namespace/values/:value/orthologs/:target' do
84
+ response.headers['Allow'] = 'OPTIONS,GET'
85
+ status 200
86
+ end
87
+
88
+ get '/api/namespaces' do
89
+ namespaces = @namespaces.each.to_a
90
+
91
+ halt 404 if not namespaces or namespaces.empty?
92
+
93
+ render_collection(
94
+ namespaces.sort { |x,y|
95
+ x.prefLabel.to_s <=> y.prefLabel.to_s
96
+ },
97
+ :namespace
98
+ )
99
+ end
100
+
101
+ get '/api/namespaces/values' do
102
+ start = (params[:start] || 0).to_i
103
+ size = (params[:size] || -1).to_i
104
+ size = -1 if size <= 0
105
+ faceted = as_bool(params[:faceted])
106
+ halt 501 if faceted
107
+
108
+ filter_hash = Hash.new{ |h,k| h[k] = Hash.new(&h.default_proc) }
109
+ filter_params = CGI::parse(env["QUERY_STRING"])['filter']
110
+ filter_params.each do |filter|
111
+ filter = read_filter(filter)
112
+ halt 400 unless ['category', 'name', 'value'].all? { |f| filter.include? f}
113
+ filter_hash[filter['category']][filter['name']] = filter['value']
114
+ end
115
+
116
+ halt 404 unless filter_hash['fts']['search'].is_a?(String)
117
+ match = filter_hash['fts']['search']
118
+ halt 404 unless match.length > 1
119
+
120
+ match_results = @search.search(wildcard_match(match), :namespace_concept, nil, nil,
121
+ :start => start,
122
+ :size => size
123
+ ).map { |result|
124
+ value = OpenBEL::Resource::Namespaces::NamespaceValueSearchResult.new(@rr, result.uri)
125
+ value.match_text = result.snippet
126
+ value
127
+ }.to_a
128
+
129
+ halt 404 if not match_results or match_results.empty?
130
+ render_collection(
131
+ match_results,
132
+ :namespace_value,
133
+ :adapter => Oat::Adapters::BasicJson
134
+ )
135
+ end
136
+
137
+ get '/api/namespaces/:namespace' do |namespace|
138
+ namespace = @namespaces.find(namespace).first
139
+
140
+ halt 404 unless namespace
141
+
142
+ status 200
143
+ render_resource(
144
+ namespace,
145
+ :namespace
146
+ )
147
+ end
148
+
149
+ get '/api/namespaces/:namespace/values' do |namespace|
150
+ namespace = @namespaces.find(namespace).first
151
+ halt 404 unless namespace
152
+
153
+ start = (params[:start] || 0).to_i
154
+ size = (params[:size] || -1).to_i
155
+ size = -1 if size <= 0
156
+ faceted = as_bool(params[:faceted])
157
+ halt 501 if faceted
158
+
159
+ filter_hash = Hash.new{ |h,k| h[k] = Hash.new(&h.default_proc) }
160
+ filter_params = CGI::parse(env["QUERY_STRING"])['filter']
161
+ filter_params.each do |filter|
162
+ filter = read_filter(filter)
163
+ halt 400 unless ['category', 'name', 'value'].all? { |f| filter.include? f}
164
+ filter_hash[filter['category']][filter['name']] = filter['value']
165
+ end
166
+
167
+ halt 404 unless filter_hash['fts']['search'].is_a?(String)
168
+ match = filter_hash['fts']['search']
169
+ halt 404 unless match.length > 1
170
+
171
+ match_results = @search.search(wildcard_match(match), :namespace_concept, namespace.uri.to_s, nil,
172
+ :start => start,
173
+ :size => size
174
+ ).map { |result|
175
+ value = OpenBEL::Resource::Namespaces::NamespaceValueSearchResult.new(@rr, result.uri)
176
+ value.match_text = result.snippet
177
+ value
178
+ }.to_a
179
+
180
+ halt 404 if not match_results or match_results.empty?
181
+ render_collection(
182
+ match_results,
183
+ :namespace_value,
184
+ :adapter => Oat::Adapters::BasicJson
185
+ )
186
+ end
187
+
188
+ # TODO Requires a Namespace API to retrieve equivalents for matched values.
189
+ # get '/api/namespaces/:namespace/equivalents' do |namespace|
190
+ # halt 400 unless request.params['value']
191
+
192
+ # values = CGI::parse(env["QUERY_STRING"])['value']
193
+ # options = {}
194
+ # if request.params['namespace']
195
+ # options[:target] = request.params['namespace']
196
+ # end
197
+
198
+ # if request.params['result']
199
+ # result = request.params['result'].to_sym
200
+ # halt 400 unless RESULT_TYPES.include? result
201
+ # options[:result] = RESULT_TYPES[result]
202
+ # end
203
+
204
+ # eq_mapping = @api.find_equivalents(namespace, values, options)
205
+ # halt 404 if eq_mapping.values.all? { |v| v == nil }
206
+ # response.headers['Content-Type'] = 'application/json'
207
+ # MultiJson.dump eq_mapping
208
+ # end
209
+
210
+ # TODO Requires a Namespace API to retrieve equivalents for matched values.
211
+ # post '/api/namespaces/:namespace/equivalents' do |namespace|
212
+ # halt 400 unless request.media_type == 'application/x-www-form-urlencoded'
213
+
214
+ # content = request.body.read
215
+ # halt 400 if content.empty?
216
+
217
+ # params = Hash[
218
+ # URI.decode_www_form(content).group_by(&:first).map{
219
+ # |k,a| [k,a.map(&:last)]
220
+ # }
221
+ # ]
222
+
223
+ # halt 400 unless params['value']
224
+
225
+ # options = {}
226
+ # if params['namespace']
227
+ # options[:target] = params['namespace'].first
228
+ # end
229
+
230
+ # if params['result']
231
+ # result = params['result'].first.to_sym
232
+ # halt 400 unless RESULT_TYPES.include? result
233
+ # options[:result] = RESULT_TYPES[result]
234
+ # end
235
+
236
+ # eq_mapping = @api.find_equivalents(namespace, params['value'], options)
237
+ # response.headers['Content-Type'] = 'application/json'
238
+ # MultiJson.dump eq_mapping
239
+ # end
240
+
241
+ # TODO Requires a Namespace API to retrieve orthologs for matched values.
242
+ # get '/api/namespaces/:namespace/orthologs' do |namespace|
243
+ # halt 400 unless request.params['value']
244
+
245
+ # values = CGI::parse(env["QUERY_STRING"])['value']
246
+ # options = {}
247
+ # if request.params['namespace']
248
+ # options[:target] = request.params['namespace']
249
+ # end
250
+
251
+ # if request.params['result']
252
+ # result = request.params['result'].to_sym
253
+ # halt 400 unless RESULT_TYPES.include? result
254
+ # options[:result] = RESULT_TYPES[result]
255
+ # end
256
+
257
+ # orth_mapping = @api.find_orthologs(namespace, values, options)
258
+ # halt 404 if orth_mapping.values.all? { |v| v == nil }
259
+ # response.headers['Content-Type'] = 'application/json'
260
+ # MultiJson.dump orth_mapping
261
+ # end
262
+
263
+ # TODO Requires a Namespace API to retrieve orthologs for matched values.
264
+ # post '/api/namespaces/:namespace/orthologs' do |namespace|
265
+ # halt 400 unless request.media_type == 'application/x-www-form-urlencoded'
266
+
267
+ # content = request.body.read
268
+ # halt 400 if content.empty?
269
+
270
+ # params = Hash[
271
+ # URI.decode_www_form(content).group_by(&:first).map{
272
+ # |k,a| [k,a.map(&:last)]
273
+ # }
274
+ # ]
275
+
276
+ # halt 400 unless params['value']
277
+
278
+ # options = {}
279
+ # if params['namespace']
280
+ # options[:target] = params['namespace'].first
281
+ # end
282
+
283
+ # if params['result']
284
+ # result = params['result'].first.to_sym
285
+ # halt 400 unless RESULT_TYPES.include? result
286
+ # options[:result] = RESULT_TYPES[result]
287
+ # end
288
+
289
+ # orth_mapping = @api.find_orthologs(namespace, params['value'], options)
290
+ # response.headers['Content-Type'] = 'application/json'
291
+ # MultiJson.dump orth_mapping
292
+ # end
293
+
294
+ get '/api/namespaces/:namespace/values/:value' do |namespace, value|
295
+ namespace = @namespaces.find(namespace).first
296
+ halt 404 unless namespace
297
+
298
+ value = namespace.find(value).first
299
+ halt 404 unless value
300
+
301
+ status 200
302
+ render_resource(
303
+ value,
304
+ :namespace_value,
305
+ :adapter => Oat::Adapters::BasicJson
306
+ )
307
+ end
308
+
309
+ get '/api/namespaces/:namespace/values/:value/equivalents' do |namespace, value|
310
+ namespace = @namespaces.find(namespace).first
311
+ halt 404 unless namespace
312
+
313
+ value = namespace.find(value).first
314
+ halt 404 unless value
315
+
316
+ equivalents = value.equivalents.to_a
317
+ halt 404 if not equivalents or equivalents.empty?
318
+
319
+ render_collection(
320
+ equivalents,
321
+ :namespace_value,
322
+ :adapter => Oat::Adapters::BasicJson
323
+ )
324
+ end
325
+
326
+ get '/api/namespaces/:namespace/values/:value/equivalents/:target' do |namespace, value, target|
327
+ namespace = @namespaces.find(namespace).first
328
+ halt 404 unless namespace
329
+ halt 404 unless @namespaces.find(target).first
330
+
331
+ value = namespace.find(value).first
332
+ halt 404 unless value
333
+
334
+ target_equivalents = value.equivalents(target).to_a
335
+ halt 404 if not target_equivalents or target_equivalents.empty?
336
+
337
+ render_collection(
338
+ target_equivalents,
339
+ :namespace_value,
340
+ :adapter => Oat::Adapters::BasicJson
341
+ )
342
+ end
343
+
344
+ get '/api/namespaces/:namespace/values/:value/orthologs' do |namespace, value|
345
+ namespace = @namespaces.find(namespace).first
346
+ halt 404 unless namespace
347
+
348
+ value = namespace.find(value).first
349
+ halt 404 unless value
350
+
351
+ orthologs = value.orthologs.to_a
352
+ halt 404 if not orthologs or orthologs.empty?
353
+
354
+ render_collection(
355
+ orthologs,
356
+ :namespace_value,
357
+ :adapter => Oat::Adapters::BasicJson
358
+ )
359
+ end
360
+
361
+ get '/api/namespaces/:namespace/values/:value/orthologs/:target' do |namespace, value, target|
362
+ namespace = @namespaces.find(namespace).first
363
+ halt 404 unless namespace
364
+ halt 404 unless @namespaces.find(target).first
365
+
366
+ value = namespace.find(value).first
367
+ halt 404 unless value
368
+
369
+ target_orthologs = value.orthologs(target).to_a
370
+ halt 404 if not target_orthologs or target_orthologs.empty?
371
+
372
+ render_collection(
373
+ target_orthologs,
374
+ :namespace_value,
375
+ :adapter => Oat::Adapters::BasicJson
376
+ )
377
+ end
378
+ end
379
+ end
380
+ end
381
+ # vim: ts=2 sw=2:
382
+ # encoding: utf-8
@@ -0,0 +1,39 @@
1
+ module OpenBEL
2
+ module Routes
3
+
4
+ class Root < Base
5
+
6
+ options '/api' do
7
+ response.headers['Allow'] = 'OPTIONS,GET'
8
+ status 200
9
+ end
10
+
11
+ get '/api' do
12
+ response.headers['Content-Type'] = 'application/hal+json'
13
+ MultiJson.dump({
14
+ :_links => {
15
+ :item => [
16
+ {
17
+ :href => "#{base_url}/api/annotations"
18
+ },
19
+ {
20
+ :href => "#{base_url}/api/evidence"
21
+ },
22
+ {
23
+ :href => "#{base_url}/api/expressions"
24
+ },
25
+ {
26
+ :href => "#{base_url}/api/functions"
27
+ },
28
+ {
29
+ :href => "#{base_url}/api/namespaces"
30
+ }
31
+ ]
32
+ }
33
+ })
34
+ end
35
+ end
36
+ end
37
+ end
38
+ # vim: ts=2 sw=2:
39
+ # encoding: utf-8