openbel-api 1.2.6-java → 1.2.7-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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)
|