openbel-api 1.2.6-java → 1.2.7-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +2 -0
- data/VERSION +1 -1
- data/app/openbel/api/helpers/nanopub.rb +159 -0
- data/app/openbel/api/resources/completion.rb +3 -2
- data/app/openbel/api/routes/base.rb +1 -1
- data/app/openbel/api/routes/datasets.rb +33 -22
- data/app/openbel/api/routes/nanopubs.rb +2 -158
- data/bin/bel2.0-example-statements.bel +344 -0
- data/bin/bel2_document_examples.bel +250 -0
- data/bin/test_bel2_validation.py +68 -0
- data/bin/test_results.json +2208 -0
- data/config/config.yml +1 -1
- metadata +10 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 60772f35d5cba63231bf2b925c748c58606af095
|
4
|
+
data.tar.gz: 8bc2ff556addbbf5abb156e39ced7a3ce1b8fd86
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0c35fb15fb67b14b9a2b8fe3fc97187624c47bf281ab30d91f53b2104e7074366bd627fde75bdcd71a396da1a16c7a26c3ea43c84c026a0e4b677983dd398095
|
7
|
+
data.tar.gz: d2db63a059a447c718cb91c538645971122fda499cc981a668706948c6a8a5cf33b0974206b760442cd6e2c583280495f3dd02d8fac64d38fadf2eac63d0ad0c
|
data/README.md
CHANGED
@@ -273,6 +273,8 @@ Releases of *openbel-api* should follow these steps:
|
|
273
273
|
|
274
274
|
Built with collaboration and a lot of :heart: by the [OpenBEL][OpenBEL] community.
|
275
275
|
|
276
|
+
<a href="https://koding.com/"> <img src="https://koding-cdn.s3.amazonaws.com/badges/made-with-koding/v1/koding_badge_ReadmeLight.png" srcset="https://koding-cdn.s3.amazonaws.com/badges/made-with-koding/v1/koding_badge_ReadmeLight.png 1x, https://koding-cdn.s3.amazonaws.com/badges/made-with-koding/v1/koding_badge_ReadmeLight@2x.png 2x" alt="Made with Koding" /> </a>
|
277
|
+
|
276
278
|
[OpenBEL]: http://www.openbel.org
|
277
279
|
[OpenBEL Platform]: https://github.com/OpenBEL/openbel-platform
|
278
280
|
[RAML]: http://raml.org/
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.2.
|
1
|
+
1.2.7
|
@@ -69,5 +69,164 @@ module OpenBEL
|
|
69
69
|
end
|
70
70
|
end
|
71
71
|
end
|
72
|
+
|
73
|
+
def validate_experiment_context(experiment_context)
|
74
|
+
valid_annotations = []
|
75
|
+
invalid_annotations = []
|
76
|
+
experiment_context.values.each do |annotation|
|
77
|
+
name, value = annotation.values_at(:name, :value)
|
78
|
+
found_annotation = @annotations.find(name).first
|
79
|
+
|
80
|
+
if found_annotation
|
81
|
+
if found_annotation.find(value).first == nil
|
82
|
+
# structured annotations, without a match, is invalid
|
83
|
+
invalid_annotations << annotation
|
84
|
+
else
|
85
|
+
# structured annotations, with a match, is invalid
|
86
|
+
valid_annotations << annotation
|
87
|
+
end
|
88
|
+
else
|
89
|
+
# free annotations considered valid
|
90
|
+
valid_annotations << annotation
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
[
|
95
|
+
invalid_annotations.empty? ? :valid : :invalid,
|
96
|
+
{
|
97
|
+
:valid => invalid_annotations.empty?,
|
98
|
+
:valid_annotations => valid_annotations,
|
99
|
+
:invalid_annotations => invalid_annotations,
|
100
|
+
:message =>
|
101
|
+
invalid_annotations
|
102
|
+
.map { |annotation|
|
103
|
+
name, value = annotation.values_at(:name, :value)
|
104
|
+
%Q{The value "#{value}" was not found in annotation "#{name}".}
|
105
|
+
}
|
106
|
+
.join("\n")
|
107
|
+
}
|
108
|
+
]
|
109
|
+
end
|
110
|
+
|
111
|
+
def validate_statement(bel)
|
112
|
+
filter =
|
113
|
+
BELParser::ASTFilter.new(
|
114
|
+
BELParser::ASTGenerator.new("#{bel}\n"),
|
115
|
+
:simple_statement,
|
116
|
+
:observed_term,
|
117
|
+
:nested_statement
|
118
|
+
)
|
119
|
+
_, _, ast = filter.each.first
|
120
|
+
|
121
|
+
if ast.nil? || ast.empty?
|
122
|
+
return [
|
123
|
+
:syntax_invalid,
|
124
|
+
{
|
125
|
+
valid_syntax: false,
|
126
|
+
valid_semantics: false,
|
127
|
+
message: 'Invalid syntax.',
|
128
|
+
warnings: [],
|
129
|
+
term_signatures: []
|
130
|
+
}
|
131
|
+
]
|
132
|
+
end
|
133
|
+
|
134
|
+
urir = BELParser::Resource.default_uri_reader
|
135
|
+
urlr = BELParser::Resource.default_url_reader
|
136
|
+
validator = BELParser::Language::ExpressionValidator.new(@spec, @supported_namespaces, urir, urlr)
|
137
|
+
message = ''
|
138
|
+
terms = ast.first.traverse.select { |node| node.type == :term }.to_a
|
139
|
+
|
140
|
+
semantics_functions =
|
141
|
+
BELParser::Language::Semantics.semantics_functions.reject { |fun|
|
142
|
+
fun == BELParser::Language::Semantics::SignatureMapping
|
143
|
+
}
|
144
|
+
|
145
|
+
result = validator.validate(ast.first)
|
146
|
+
syntax_errors = result.syntax_results.map(&:to_s)
|
147
|
+
|
148
|
+
semantic_warnings =
|
149
|
+
ast
|
150
|
+
.first
|
151
|
+
.traverse
|
152
|
+
.flat_map { |node|
|
153
|
+
semantics_functions.flat_map { |func|
|
154
|
+
func.map(node, @spec, @supported_namespaces)
|
155
|
+
}
|
156
|
+
}
|
157
|
+
.compact
|
158
|
+
|
159
|
+
if syntax_errors.empty? && semantic_warnings.empty?
|
160
|
+
valid = true
|
161
|
+
else
|
162
|
+
valid = false
|
163
|
+
message = ''
|
164
|
+
message +=
|
165
|
+
syntax_errors.reduce('') { |msg, error|
|
166
|
+
msg << "#{error}\n"
|
167
|
+
}
|
168
|
+
message +=
|
169
|
+
semantic_warnings.reduce('') { |msg, warning|
|
170
|
+
msg << "#{warning}\n"
|
171
|
+
}
|
172
|
+
message << "\n"
|
173
|
+
end
|
174
|
+
|
175
|
+
term_semantics =
|
176
|
+
terms.map { |term|
|
177
|
+
term_result = validator.validate(term)
|
178
|
+
valid &= term_result.valid_semantics?
|
179
|
+
bel_term = serialize(term)
|
180
|
+
|
181
|
+
unless valid
|
182
|
+
message << "Term: #{bel_term}\n"
|
183
|
+
term_result.invalid_signature_mappings.map { |m|
|
184
|
+
message << " #{m}\n"
|
185
|
+
}
|
186
|
+
message << "\n"
|
187
|
+
end
|
188
|
+
|
189
|
+
{
|
190
|
+
term: bel_term,
|
191
|
+
valid: term_result.valid_semantics?,
|
192
|
+
errors: term_result.syntax_results.map(&:to_s),
|
193
|
+
valid_signatures: term_result.valid_signature_mappings.map(&:to_s),
|
194
|
+
invalid_signatures: term_result.invalid_signature_mappings.map(&:to_s)
|
195
|
+
}
|
196
|
+
}
|
197
|
+
|
198
|
+
[
|
199
|
+
valid ? :valid : :semantics_invalid,
|
200
|
+
{
|
201
|
+
expression: bel,
|
202
|
+
valid_syntax: true,
|
203
|
+
valid_semantics: valid,
|
204
|
+
message: valid ? 'Valid semantics' : message,
|
205
|
+
errors: syntax_errors,
|
206
|
+
warnings: semantic_warnings.map(&:to_s),
|
207
|
+
term_signatures: term_semantics
|
208
|
+
}
|
209
|
+
]
|
210
|
+
end
|
211
|
+
|
212
|
+
def validate_nanopub!(bel_statement, experiment_context)
|
213
|
+
stmt_result, stmt_validation = validate_statement(bel_statement)
|
214
|
+
expctx_result, expctx_validation = validate_experiment_context(experiment_context)
|
215
|
+
|
216
|
+
return nil if stmt_result == :valid && expctx_result == :valid
|
217
|
+
|
218
|
+
halt(
|
219
|
+
422,
|
220
|
+
{'Content-Type' => 'application/json'},
|
221
|
+
render_json(
|
222
|
+
{
|
223
|
+
:nanopub_validation => {
|
224
|
+
:bel_statement_validation => stmt_validation,
|
225
|
+
:experiment_context_validation => expctx_validation
|
226
|
+
}
|
227
|
+
}
|
228
|
+
)
|
229
|
+
)
|
230
|
+
end
|
72
231
|
end
|
73
232
|
end
|
@@ -44,8 +44,9 @@ module OpenBEL
|
|
44
44
|
}
|
45
45
|
when :namespace_value
|
46
46
|
{
|
47
|
-
|
48
|
-
:
|
47
|
+
# TODO Add namespace
|
48
|
+
# :type => 'namespace_value',
|
49
|
+
# :href => "#{base_url}/api/namespaces/#{namespace}/values/#{id}"
|
49
50
|
}
|
50
51
|
when :relationship
|
51
52
|
{
|
@@ -136,28 +136,28 @@ module OpenBEL
|
|
136
136
|
)
|
137
137
|
end
|
138
138
|
|
139
|
-
datasets = @rr.query_pattern(RDF::Statement.new(nil, RDF.type, VOID.Dataset))
|
140
|
-
existing_dataset = datasets.find { |dataset_statement|
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
}
|
145
|
-
|
146
|
-
if existing_dataset
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
end
|
139
|
+
# datasets = @rr.query_pattern(RDF::Statement.new(nil, RDF.type, VOID.Dataset))
|
140
|
+
# existing_dataset = datasets.find { |dataset_statement|
|
141
|
+
# @rr.has_statement?(
|
142
|
+
# RDF::Statement.new(dataset_statement.subject, DC.identifier, identifier_statement.object)
|
143
|
+
# )
|
144
|
+
# }
|
145
|
+
|
146
|
+
# if existing_dataset
|
147
|
+
# dataset_uri = existing_dataset.subject.to_s
|
148
|
+
# headers 'Location' => dataset_uri
|
149
|
+
# halt(
|
150
|
+
# 409,
|
151
|
+
# { 'Content-Type' => 'application/json' },
|
152
|
+
# render_json(
|
153
|
+
# {
|
154
|
+
# :status => 409,
|
155
|
+
# :msg => %Q{The dataset document matches an existing dataset resource by identifier "#{identifier_statement.object}".},
|
156
|
+
# :location => dataset_uri
|
157
|
+
# }
|
158
|
+
# )
|
159
|
+
# )
|
160
|
+
# end
|
161
161
|
|
162
162
|
[void_dataset_uri, void_dataset]
|
163
163
|
ensure
|
@@ -216,6 +216,7 @@ module OpenBEL
|
|
216
216
|
|
217
217
|
dataset
|
218
218
|
end
|
219
|
+
|
219
220
|
end
|
220
221
|
|
221
222
|
options '/api/datasets' do
|
@@ -270,6 +271,8 @@ the "multipart/form-data" content type. Allowed dataset content types are: #{ACC
|
|
270
271
|
# Check dataset in request for suitability and conflict with existing resources.
|
271
272
|
void_dataset_uri, void_dataset = check_dataset(io, type)
|
272
273
|
|
274
|
+
# STDERR.puts "DBG: Variable config is #{void_dataset_uri.inspect}"
|
275
|
+
|
273
276
|
# Create dataset in RDF.
|
274
277
|
@rr.insert_statements(void_dataset)
|
275
278
|
|
@@ -298,6 +301,13 @@ the "multipart/form-data" content type. Allowed dataset content types are: #{ACC
|
|
298
301
|
hash[:_dataset] = dataset_id
|
299
302
|
hash[:bel_statement] = hash[:bel_statement].to_s
|
300
303
|
|
304
|
+
# Validate nanopub
|
305
|
+
original_bel_statement = hash[:bel_statement].to_s
|
306
|
+
|
307
|
+
# STDERR.puts "DBG: Variable config is #{original_bel_statement.inspect}"
|
308
|
+
# STDERR.puts "DBG: Variable config is #{nanopub.experiment_context.inspect}"
|
309
|
+
# validate_nanopub!(original_bel_statement, nanopub.experiment_context)
|
310
|
+
|
301
311
|
nanopub_batch << hash
|
302
312
|
|
303
313
|
if nanopub_batch.size == MONGO_BATCH
|
@@ -335,6 +345,7 @@ the "multipart/form-data" content type. Allowed dataset content types are: #{ACC
|
|
335
345
|
|
336
346
|
status 201
|
337
347
|
headers 'Location' => void_dataset_uri.to_s
|
348
|
+
render_json({"Location": void_dataset_uri.to_s})
|
338
349
|
end
|
339
350
|
|
340
351
|
get '/api/datasets/:id' do
|
@@ -140,164 +140,6 @@ module OpenBEL
|
|
140
140
|
end
|
141
141
|
end
|
142
142
|
|
143
|
-
def validate_experiment_context(experiment_context)
|
144
|
-
valid_annotations = []
|
145
|
-
invalid_annotations = []
|
146
|
-
experiment_context.values.each do |annotation|
|
147
|
-
name, value = annotation.values_at(:name, :value)
|
148
|
-
found_annotation = @annotations.find(name).first
|
149
|
-
|
150
|
-
if found_annotation
|
151
|
-
if found_annotation.find(value).first == nil
|
152
|
-
# structured annotations, without a match, is invalid
|
153
|
-
invalid_annotations << annotation
|
154
|
-
else
|
155
|
-
# structured annotations, with a match, is invalid
|
156
|
-
valid_annotations << annotation
|
157
|
-
end
|
158
|
-
else
|
159
|
-
# free annotations considered valid
|
160
|
-
valid_annotations << annotation
|
161
|
-
end
|
162
|
-
end
|
163
|
-
|
164
|
-
[
|
165
|
-
invalid_annotations.empty? ? :valid : :invalid,
|
166
|
-
{
|
167
|
-
:valid => invalid_annotations.empty?,
|
168
|
-
:valid_annotations => valid_annotations,
|
169
|
-
:invalid_annotations => invalid_annotations,
|
170
|
-
:message =>
|
171
|
-
invalid_annotations
|
172
|
-
.map { |annotation|
|
173
|
-
name, value = annotation.values_at(:name, :value)
|
174
|
-
%Q{The value "#{value}" was not found in annotation "#{name}".}
|
175
|
-
}
|
176
|
-
.join("\n")
|
177
|
-
}
|
178
|
-
]
|
179
|
-
end
|
180
|
-
|
181
|
-
def validate_statement(bel)
|
182
|
-
filter =
|
183
|
-
BELParser::ASTFilter.new(
|
184
|
-
BELParser::ASTGenerator.new("#{bel}\n"),
|
185
|
-
:simple_statement,
|
186
|
-
:observed_term,
|
187
|
-
:nested_statement
|
188
|
-
)
|
189
|
-
_, _, ast = filter.each.first
|
190
|
-
|
191
|
-
if ast.nil? || ast.empty?
|
192
|
-
return [
|
193
|
-
:syntax_invalid,
|
194
|
-
{
|
195
|
-
valid_syntax: false,
|
196
|
-
valid_semantics: false,
|
197
|
-
message: 'Invalid syntax.',
|
198
|
-
warnings: [],
|
199
|
-
term_signatures: []
|
200
|
-
}
|
201
|
-
]
|
202
|
-
end
|
203
|
-
|
204
|
-
urir = BELParser::Resource.default_uri_reader
|
205
|
-
urlr = BELParser::Resource.default_url_reader
|
206
|
-
validator = BELParser::Language::ExpressionValidator.new(@spec, @supported_namespaces, urir, urlr)
|
207
|
-
message = ''
|
208
|
-
terms = ast.first.traverse.select { |node| node.type == :term }.to_a
|
209
|
-
|
210
|
-
semantics_functions =
|
211
|
-
BELParser::Language::Semantics.semantics_functions.reject { |fun|
|
212
|
-
fun == BELParser::Language::Semantics::SignatureMapping
|
213
|
-
}
|
214
|
-
|
215
|
-
result = validator.validate(ast.first)
|
216
|
-
syntax_errors = result.syntax_results.map(&:to_s)
|
217
|
-
|
218
|
-
semantic_warnings =
|
219
|
-
ast
|
220
|
-
.first
|
221
|
-
.traverse
|
222
|
-
.flat_map { |node|
|
223
|
-
semantics_functions.flat_map { |func|
|
224
|
-
func.map(node, @spec, @supported_namespaces)
|
225
|
-
}
|
226
|
-
}
|
227
|
-
.compact
|
228
|
-
|
229
|
-
if syntax_errors.empty? && semantic_warnings.empty?
|
230
|
-
valid = true
|
231
|
-
else
|
232
|
-
valid = false
|
233
|
-
message = ''
|
234
|
-
message +=
|
235
|
-
syntax_errors.reduce('') { |msg, error|
|
236
|
-
msg << "#{error}\n"
|
237
|
-
}
|
238
|
-
message +=
|
239
|
-
semantic_warnings.reduce('') { |msg, warning|
|
240
|
-
msg << "#{warning}\n"
|
241
|
-
}
|
242
|
-
message << "\n"
|
243
|
-
end
|
244
|
-
|
245
|
-
term_semantics =
|
246
|
-
terms.map { |term|
|
247
|
-
term_result = validator.validate(term)
|
248
|
-
valid &= term_result.valid_semantics?
|
249
|
-
bel_term = serialize(term)
|
250
|
-
|
251
|
-
unless valid
|
252
|
-
message << "Term: #{bel_term}\n"
|
253
|
-
term_result.invalid_signature_mappings.map { |m|
|
254
|
-
message << " #{m}\n"
|
255
|
-
}
|
256
|
-
message << "\n"
|
257
|
-
end
|
258
|
-
|
259
|
-
{
|
260
|
-
term: bel_term,
|
261
|
-
valid: term_result.valid_semantics?,
|
262
|
-
errors: term_result.syntax_results.map(&:to_s),
|
263
|
-
valid_signatures: term_result.valid_signature_mappings.map(&:to_s),
|
264
|
-
invalid_signatures: term_result.invalid_signature_mappings.map(&:to_s)
|
265
|
-
}
|
266
|
-
}
|
267
|
-
|
268
|
-
[
|
269
|
-
valid ? :valid : :semantics_invalid,
|
270
|
-
{
|
271
|
-
expression: bel,
|
272
|
-
valid_syntax: true,
|
273
|
-
valid_semantics: valid,
|
274
|
-
message: valid ? 'Valid semantics' : message,
|
275
|
-
errors: syntax_errors,
|
276
|
-
warnings: semantic_warnings.map(&:to_s),
|
277
|
-
term_signatures: term_semantics
|
278
|
-
}
|
279
|
-
]
|
280
|
-
end
|
281
|
-
|
282
|
-
def validate_nanopub!(bel_statement, experiment_context)
|
283
|
-
stmt_result, stmt_validation = validate_statement(bel_statement)
|
284
|
-
expctx_result, expctx_validation = validate_experiment_context(experiment_context)
|
285
|
-
|
286
|
-
return nil if stmt_result == :valid && expctx_result == :valid
|
287
|
-
|
288
|
-
halt(
|
289
|
-
422,
|
290
|
-
{'Content-Type' => 'application/json'},
|
291
|
-
render_json(
|
292
|
-
{
|
293
|
-
:nanopub_validation => {
|
294
|
-
:bel_statement_validation => stmt_validation,
|
295
|
-
:experiment_context_validation => expctx_validation
|
296
|
-
}
|
297
|
-
}
|
298
|
-
)
|
299
|
-
)
|
300
|
-
end
|
301
143
|
end
|
302
144
|
|
303
145
|
options '/api/nanopubs' do
|
@@ -361,6 +203,8 @@ module OpenBEL
|
|
361
203
|
@annotation_transform.transform_nanopub!(nanopub, base_url)
|
362
204
|
|
363
205
|
# Validate nanopub when strict is enabled.
|
206
|
+
# STDERR.puts "DBG: Variable config is #{original_bel_statement.inspect}"
|
207
|
+
# STDERR.puts "DBG: Variable config is #{nanopub.experiment_context.inspect}"
|
364
208
|
validate_nanopub!(original_bel_statement, nanopub.experiment_context) if strict
|
365
209
|
|
366
210
|
facets = map_nanopub_facets(nanopub)
|