oba_client 2.0.3

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.
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ doc
2
+ pkg
3
+ .yardoc
4
+ .buildpath
5
+ .project
6
+
data/History.md ADDED
@@ -0,0 +1,54 @@
1
+ ## 2.0.3 / 2010-07-17
2
+ Quick fix in docs.
3
+
4
+ ## 2.0.2 / 2010-07-08
5
+ Parse version and nbAnnotation for ontologies.
6
+
7
+ ## 2.0.1 / 2010-07-08
8
+
9
+ Rubyforge doesn't allow "_", so we have "oba-client", not "oba_client".
10
+
11
+ # 2.0.0 / 2010-07-08
12
+
13
+ * Parse XML entirely. See README for more information on the return value.
14
+
15
+ ## 1.2.1 / 2010-07-08
16
+
17
+ * Link correctly (problem with using markdown-ed URL in README.md).
18
+
19
+ ## 1.2.0 / 2010-07-08
20
+
21
+ * Parse statistics.
22
+
23
+ ## 1.1.1 / 2010-07-08
24
+
25
+ * Rake or Hoe bug workaround.
26
+
27
+ ## 1.1.0 / 2010-07-08
28
+
29
+ * Fully parse MGREP mappings.
30
+
31
+ ## 1.0.5 / 2010-07-08
32
+
33
+ * Modify docs slightly.
34
+
35
+ ## 1.0.4 / 2010-07-08
36
+
37
+ * Add all possible parameter values for the Annotator.
38
+
39
+ ## 1.0.3 / 2010-07-07
40
+
41
+ * Add more tests.
42
+
43
+ ## 1.0.2 / 2010-07-07
44
+
45
+ * Oops, no release notes.
46
+
47
+ ## 1.0.1 / 2010-07-07
48
+
49
+ * Oops, fix a symbol bug.
50
+
51
+ # 1.0.0 / 2010-07-07
52
+
53
+ * Initial release.
54
+ * Does not yet parse statistics.
data/Manifest.txt ADDED
@@ -0,0 +1,6 @@
1
+ History.md
2
+ Manifest.txt
3
+ README.md
4
+ Rakefile
5
+ lib/oba_client.rb
6
+ test/test_oba_client.rb
data/README.md ADDED
@@ -0,0 +1,103 @@
1
+ # oba-client
2
+
3
+ * [RubyForge project](http://rubyforge.org/projects/oba-client "RubyForge project")
4
+
5
+ ## DESCRIPTION:
6
+
7
+ A client for accessing the NCBO's Open Biomedical Annotator service.
8
+ See [the Annotator documentation](http://www.bioontology.org/wiki/index.php/Annotator_User_Guide "Documentation") for much more information.
9
+
10
+ ## FEATURES:
11
+
12
+ * Many
13
+
14
+ ## REQUIREMENTS:
15
+
16
+ * None
17
+
18
+ ## INSTALL:
19
+
20
+ sudo gem install oba-client
21
+ gem install --user-install oba-client
22
+
23
+ ## USAGE:
24
+
25
+ require "rubygems"
26
+ require "oba-client"
27
+
28
+ client = OBAClient.new
29
+ # As XML.
30
+ result = client.execute("some text string")
31
+
32
+ client2 = OBAClient.new({:parse_xml => true})
33
+ # Returns {:statistics => {information about the annotation},
34
+ # :annotations => [Array of annotations of text],
35
+ # :ontologies => [Array of ontologies used]}
36
+ # Like:
37
+ :statistics => {"MAPPING" => 1951, "MGREP" => 2319, "ISA_CLOSURE" => 30}
38
+ :annotations => [{
39
+ :score => 199,
40
+ :id => 203820,
41
+ :localConceptId => "42877/CARO:0000013",
42
+ :localOntologyId => 42877,
43
+ :isTopLevel => true,
44
+ :fullId => "http://purl.obolibrary.org/obo/FBbt_00007002",
45
+ :preferredName => "cell",
46
+ :synonyms => ["body cell"],
47
+ :definitions => ["a cell", "some other definition"],
48
+
49
+ :semanticTypes => [
50
+ {:id => 230820, :semanticType => "T043", :description => "desc"},
51
+ "etc..."
52
+ ]
53
+
54
+ :context => {
55
+ :contextName => "MAPPING",
56
+ :isDirect => false,
57
+ :from => 10,
58
+ :to => 20,
59
+ :mappedConcept => {
60
+ "has" => "the same information as other annotations, minus score"
61
+ }
62
+ }
63
+
64
+ :mappingType => "Automatic"
65
+ }, "more annotations..."]
66
+
67
+ :ontologies => [{
68
+ :localOntologyId => 40404,
69
+ :name => "Ontology Name",
70
+ :virtualOntologyId => 1042,
71
+ :version => 1.1,
72
+ :nbAnnotation => 40
73
+
74
+ }, "more ontologies..."]
75
+
76
+ client2.execute("another text string, maybe longer this time.")
77
+ client2.execute("this is the second query for this client!")
78
+
79
+ # Or, parse some file you've already got lying about (pass as a string).
80
+ parsed = OBAClient::parse("<?xml version='1.0'>...</xml>")
81
+
82
+ ## LICENSE:
83
+
84
+ Copyright (c) 2010 Rob Tirrell
85
+
86
+ Permission is hereby granted, free of charge, to any person obtaining a copy
87
+ of this software and associated documentation files (the "Software"), to deal
88
+ in the Software without restriction, including without limitation the rights
89
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
90
+ copies of the Software, and to permit persons to whom the Software is
91
+ furnished to do so, subject to the following conditions:
92
+
93
+ The above copyright notice and this permission notice shall be included in
94
+ all copies or substantial portions of the Software.
95
+
96
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
97
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
98
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
99
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
100
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
101
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
102
+ THE SOFTWARE.
103
+
data/Rakefile ADDED
@@ -0,0 +1,74 @@
1
+ require "rubygems"
2
+ require File.dirname(__FILE__) + "/lib/oba_client.rb"
3
+ #require "hoe"
4
+
5
+ #Hoe.plugin :yard
6
+
7
+ #Hoe.spec "oba-client" do
8
+ # self.developer "Rob Tirrell", "rpt@stanford.edu"
9
+ # self.url = "http://rubyforge.org/projects/oba-client"
10
+ #
11
+ # self.yard_title = "OBAClient Documentation"
12
+ # self.yard_options = ["--default-return", "void"]
13
+ # self.yard_markup = "markdown"
14
+ # self.remote_yard_dir = ""
15
+ #
16
+ # self.rubyforge_name = "oba-client"
17
+ #end
18
+
19
+ require 'rubygems'
20
+ require 'rake'
21
+
22
+ begin
23
+ require 'jeweler'
24
+ Jeweler::Tasks.new do |gem|
25
+ gem.name = "oba_client"
26
+ gem.summary = "A client for the Open Biomedical Annotator."
27
+ gem.description = "See above."
28
+ gem.email = "rpt@stanford.edu"
29
+ gem.homepage = "http://github.com/rtirrell/oba_client"
30
+ gem.authors = ["Rob Tirrell"]
31
+ gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
32
+ gem.add_development_dependency "yard", ">= 0"
33
+ gem.version = OBAClient::VERSION
34
+
35
+
36
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
37
+ end
38
+ Jeweler::GemcutterTasks.new
39
+ rescue LoadError
40
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
41
+ end
42
+
43
+ require 'rake/testtask'
44
+ Rake::TestTask.new(:test) do |test|
45
+ test.libs << 'lib' << 'test'
46
+ test.pattern = 'test/**/test_*.rb'
47
+ test.verbose = true
48
+ end
49
+
50
+ begin
51
+ require 'rcov/rcovtask'
52
+ Rcov::RcovTask.new do |test|
53
+ test.libs << 'test'
54
+ test.pattern = 'test/**/test_*.rb'
55
+ test.verbose = true
56
+ end
57
+ rescue LoadError
58
+ task :rcov do
59
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
60
+ end
61
+ end
62
+
63
+ task :test => :check_dependencies
64
+
65
+ task :default => :test
66
+
67
+ begin
68
+ require 'yard'
69
+ YARD::Rake::YardocTask.new
70
+ rescue LoadError
71
+ task :yardoc do
72
+ abort "YARD is not available. In order to run yardoc, you must: sudo gem install yard"
73
+ end
74
+ end
data/Rakefile-2 ADDED
File without changes
data/lib/oba_client.rb ADDED
@@ -0,0 +1,282 @@
1
+ require "rubygems"
2
+ require "nokogiri"
3
+ require "cgi"
4
+ require "net/http"
5
+ require "uri"
6
+
7
+ ##
8
+ # A class for interacting with the Open Biomedical Annotator. There are two
9
+ # things we do: get text, and parse it. We can do both independently or
10
+ # serially.
11
+ class OBAClient
12
+ VERSION = "2.0.3"
13
+
14
+ ##
15
+ # A high HTTP read timeout, as the service sometimes takes awhile to respond.
16
+ DEFAULT_TIMEOUT = 30
17
+
18
+ ##
19
+ # The endpoint URI for the production version of the Annotator service.
20
+ DEFAULT_URI = "http://rest.bioontology.org/obs/annotator"
21
+
22
+ ##
23
+ # The header for every request. There's no need to specify this per-instance.
24
+ HEADER = {"Content-Type" => "application/x-www-form-urlencoded"}
25
+
26
+ ##
27
+ # Parameters the annotator accepts. Any one not in this list (excluding
28
+ # textToAnnotate) is not valid.
29
+ ANNOTATOR_PARAMETERS = [
30
+ :email,
31
+ :filterNumber,
32
+ :format,
33
+ :isStopWordsCaseSensitive,
34
+ :isVirtualOntologyID,
35
+ :levelMax,
36
+ :longestOnly,
37
+ :ontologiesToExpand,
38
+ :ontologiesToKeepInResult,
39
+ :mappingTypes,
40
+ :minTermSize,
41
+ :scored,
42
+ :semanticTypes,
43
+ :stopWords,
44
+ :wholeWordOnly,
45
+ :withDefaultStopWords,
46
+ :withSynonyms,
47
+ ]
48
+
49
+ ##
50
+ # Instantiate the class with a set of reused options. Options used by the
51
+ # method are:
52
+ #
53
+ # * {String} **uri**: the URI of the annotator service (default:
54
+ # {DEFAULT_URI}).
55
+ # * {Fixnum} **timeout**: the length of the read timeout (default:
56
+ # {DEFAULT_TIMEOUT}).
57
+ # * {Boolean} **parse_xml**: whether to parse the received text (default:
58
+ # false).
59
+ # * {Array}<{String}> **ontologies**: a pseudo-parameter which sets both
60
+ # ontologiesToExpand and ontologiesToKeepInResult.
61
+ # @param [Hash<String, String>] options Parameters for the annotation.
62
+ def initialize(options = {})
63
+ @uri = URI.parse(options.delete(:uri) || DEFAULT_URI)
64
+ @timeout = options.delete(:timeout) || DEFAULT_TIMEOUT
65
+ @parse_xml = options.delete(:parse_xml)
66
+
67
+ if ontologies = options.delete(:ontologies)
68
+ [:ontologiesToExpand, :ontologiesToKeepInResult].each do |k|
69
+ if options.include?(k)
70
+ puts "WARNING: specified both :ontologies and #{k}, ignoring #{k}."
71
+ end
72
+ options[k] = ontologies
73
+ end
74
+ end
75
+
76
+ @options = {}
77
+ options.each do |k, v|
78
+ if !ANNOTATOR_PARAMETERS.include?(k)
79
+ puts "WARNING: #{k} is not a valid annotator parameter."
80
+ end
81
+ if v.is_a? Array
82
+ @options[k] = v.join(",")
83
+ else
84
+ @options[k] = v
85
+ end
86
+ end
87
+
88
+ if !@options.include?(:email)
89
+ puts "TIP: as a courtesy, consider including your email in the " +
90
+ "request (:email => 'a@b.com')"
91
+ end
92
+ end
93
+
94
+ ##
95
+ # Perform the annotation.
96
+ # @param [String] text The text to annotate.
97
+ # @return [Hash<Symbol, Array>, String, nil] A Hash representing the parsed
98
+ # document, the raw XML if parsing is not requested, or nil if the
99
+ # request times out.
100
+ def execute(text)
101
+ request = Net::HTTP::Post.new(@uri.path, initheader=HEADER)
102
+ request.body = {:textToAnnotate => text}.merge(@options).map do |k, v|
103
+ "#{CGI.escape(k.to_s)}=#{CGI.escape(v.to_s)}"
104
+ end.join("&")
105
+ puts request.body if $DEBUG
106
+
107
+ begin
108
+ response = Net::HTTP.new(@uri.host, @uri.port).start do |http|
109
+ http.read_timeout = @timeout
110
+ http.request(request)
111
+ end
112
+ @parse_xml ? self.class.parse(response.body) : response.body
113
+ rescue Timeout::Error
114
+ puts "Request for #{text[0..10]}... timed-out at #{@timeout} seconds."
115
+ end
116
+ end
117
+
118
+
119
+ STATISTICS_BEANS_XPATH = "/success/data/annotatorResultBean/statistics/statisticsBean"
120
+ ANNOTATION_BEANS_XPATH = "/success/data/annotatorResultBean/annotations/annotationBean"
121
+ ONTOLOGY_BEANS_XPATH = "/success/data/annotatorResultBean/ontologies/ontologyUsedBean"
122
+
123
+ ##
124
+ # Attributes for mapping concepts (only one type).
125
+ CONCEPT_ATTRIBUTES = {
126
+ :id => lambda {|c| c.xpath("id").text.to_i},
127
+ :localConceptId => lambda {|c| c.xpath("localConceptId").text},
128
+ :localOntologyId => lambda {|c| c.xpath("localOntologyId").text.to_i},
129
+ :isTopLevel => lambda {|c| to_b(c.xpath("isTopLevel").text)},
130
+ :fullId => lambda {|c| c.xpath("fullId").text},
131
+ :preferredName => lambda {|c| c.xpath("preferredName").text},
132
+
133
+ :synonyms => lambda do |c|
134
+ c.xpath("synonyms/synonym").map do |s|
135
+ s.xpath("string").text
136
+ end
137
+ end,
138
+
139
+ :semanticTypes => lambda do |c|
140
+ c.xpath("semanticTypes/semanticTypeBean").map do |s|
141
+ {
142
+ :id => s.xpath("id").text.to_i,
143
+ :semanticType => s.xpath("semanticType").text,
144
+ :description => s.xpath("description").text
145
+ }
146
+ end
147
+ end
148
+ }
149
+
150
+
151
+ ##
152
+ # Attributes for mapping and mgrep contexts (both will add
153
+ # additional attributes).
154
+ CONTEXT_ATTRIBUTES = {
155
+ :contextName => lambda {|c| c.xpath("contextName").text},
156
+ :isDirect => lambda {|c| to_b(c.xpath("isDirect").text)},
157
+ :from => lambda {|c| c.xpath("from").text.to_i},
158
+ :to => lambda {|c| c.xpath("to").text.to_i},
159
+ }
160
+
161
+ ##
162
+ # Attributes for annotation contexts.
163
+ ANNOTATION_CONTEXT_ATTRIBUTES = {
164
+ :score => lambda {|c| c.xpath("score").text.to_i},
165
+ :concept => lambda {|c| parse_concept(c.xpath("concept").first)},
166
+ :context => lambda {|c| parse_context(c.xpath("context").first)}
167
+ }
168
+
169
+ ##
170
+ # Attributes for mapping contexts.
171
+ MAPPED_CONTEXT_ATTRIBUTES = CONTEXT_ATTRIBUTES.merge(
172
+ :mappingType => lambda {|c| c.xpath("mappingType").text},
173
+ :mappedConcept => lambda {|c| parse_concept(c.xpath("mappedConcept").first)}
174
+ )
175
+
176
+ ##
177
+ # Attributes for mgrep contexts.
178
+ MGREP_CONTEXT_ATTRIBUTES = CONTEXT_ATTRIBUTES.merge(
179
+ :name => lambda {|c| c.xpath("term/name").text},
180
+ :localConceptId => lambda {|c| c.xpath("term/localConceptId").text},
181
+ :isPreferred => lambda {|c| to_b(c.xpath("term/isPreferred").text)},
182
+ :dictionaryId => lambda {|c| c.xpath("term/dictionaryId").text}
183
+ )
184
+
185
+ ##
186
+ # Map the bean type to the set of attributes we parse from it.
187
+ CONTEXT_CLASSES = {
188
+ "annotationContextBean" => ANNOTATION_CONTEXT_ATTRIBUTES,
189
+ "mgrepContextBean" => MGREP_CONTEXT_ATTRIBUTES,
190
+ "mappingContextBean" => MAPPED_CONTEXT_ATTRIBUTES,
191
+ }
192
+
193
+ ##
194
+ # Parse a context: an annotation, or a mapping/mgrep context bean.
195
+ #
196
+ # @param [Nokgiri::XML::Node] context The root node of the context.
197
+ #
198
+ # @return [Hash<Symbol, Object>] The parsed context.
199
+ def self.parse_context(context)
200
+ # Annotations (annotationBeans) do not have a class, so we'll refer to them
201
+ # as annotationContextBeans. context_class will be one of the types in
202
+ # {CONTEXT_CLASSES}.
203
+ context_class = if context.attribute("class").nil?
204
+ "annotationContextBean"
205
+ else
206
+ context.attribute("class").value
207
+ end
208
+
209
+ Hash[CONTEXT_CLASSES[context_class].map do |k, v|
210
+ [k, v.call(context)]
211
+ end]
212
+ end
213
+
214
+ ##
215
+ # Parse a concept: a toplevel annotation concept, or an annotation's
216
+ # mapping concept.
217
+ #
218
+ # @param [Nokogiri::XML::Node] concept The root node of the concept.
219
+ #
220
+ # @return [Hash<Symbol, Object>] The parsed concept.
221
+ def self.parse_concept(concept)
222
+ Hash[CONCEPT_ATTRIBUTES.map do |k, v|
223
+ [k, v.call(concept)]
224
+ end]
225
+ end
226
+
227
+ ##
228
+ # Parse raw XML, returning a Hash with three elements: statistics,
229
+ # annotations, and ontologies. Respectively, these represent the annotation
230
+ # statistics (annotations by mapping type, etc., as a Hash), an Array of
231
+ # each annotation (as a Hash), and an Array of ontologies used (also as
232
+ # a Hash).
233
+ #
234
+ # @param [String] xml The XML we'll be parsing.
235
+ #
236
+ # @return [Hash<Symbol, Object>] A Hash representation of the XML, as
237
+ # described in the README.
238
+ def self.parse(xml)
239
+ puts "WARNING: text is empty!" if (xml.gsub(/\n/, "") == "")
240
+ doc = Nokogiri::XML.parse(xml)
241
+
242
+ statistics = Hash[doc.xpath(STATISTICS_BEANS_XPATH).map do |sb|
243
+ [sb.xpath("mapping").text, sb.xpath("nbAnnotation").text.to_i]
244
+ end]
245
+
246
+ annotations = doc.xpath(ANNOTATION_BEANS_XPATH).map do |annotation|
247
+ parse_context(annotation)
248
+ end
249
+
250
+ ontologies = doc.xpath(ONTOLOGY_BEANS_XPATH).map do |ontology|
251
+ {
252
+ :localOntologyId => ontology.xpath("localOntologyId").text.to_i,
253
+ :virtualOntologyId => ontology.xpath("virtualOntologyId").text.to_i,
254
+ :name => ontology.xpath("name").text,
255
+ :version => ontology.xpath("version").text.to_f,
256
+ :nbAnnotation => ontology.xpath("nbAnnotation").text.to_i
257
+ }
258
+ end
259
+
260
+ {
261
+ :statistics => statistics,
262
+ :annotations => annotations,
263
+ :ontologies => ontologies
264
+ }
265
+ end
266
+
267
+ ##
268
+ # A little helper: convert a string true/false or 1/0 value to boolean.
269
+ # AFAIK, there's no better way to do this.
270
+ #
271
+ # @param [String] value The value to convert.
272
+ #
273
+ # @return [true, false]
274
+ def self.to_b(value)
275
+ case value
276
+ when "0" then false
277
+ when "1" then true
278
+ when "false" then false
279
+ when "true" then true
280
+ end
281
+ end
282
+ end
@@ -0,0 +1,91 @@
1
+ require "test/unit"
2
+ require "oba-client"
3
+
4
+ TEST_TEXTS = [
5
+ "Mexico,, Disease Thing \o\r\m\n\t\v\l\rzebrafish !!! cancer of the thorax. large intestine thorax",
6
+ %Q{LOROE aonuhaso unseu anoeuhs aeuhsaonuh asoneuhason uaosenuh aosenuhaose
7
+ aoneuhasonuhaoenuh anoeuhasn euhasoneu haosneuhaosenuhaoesunahoeusnaoeuteeano
8
+ aot tt t t t t t t tae \n!!@)$@(#)%@\#!)@# asoeuaohsenutahoeusaheou
9
+ }
10
+ ]
11
+
12
+ class TestOBAClient < Test::Unit::TestCase
13
+ def test_reuse_instance
14
+ ann = OBAClient.new
15
+ TEST_TEXTS.each do |text|
16
+ xml = ann.execute(text)
17
+ assert xml[0..4] == "<?xml"
18
+ end
19
+ end
20
+
21
+ def test_reuse_instance_with_email
22
+ ann = OBAClient.new :email => "r.tirrell@gmail.com"
23
+ TEST_TEXTS.each do |text|
24
+ xml = ann.execute(text)
25
+ assert xml[0..4] == "<?xml"
26
+ end
27
+ end
28
+
29
+ def test_annotation_no_parameters
30
+ TEST_TEXTS.each do |text|
31
+ ann = OBAClient.new
32
+ xml = ann.execute(text)
33
+ assert xml[0..4] == "<?xml"
34
+ end
35
+ end
36
+
37
+ def test_annotation_parse
38
+ TEST_TEXTS.each do |text|
39
+ ann = OBAClient.new :parse_xml => true
40
+ parsed = ann.execute(text)
41
+ assert parsed[:statistics].is_a?(Hash)
42
+ assert parsed[:annotations].is_a?(Array)
43
+ assert parsed[:ontologies].is_a?(Array)
44
+ end
45
+ end
46
+
47
+ def test_annotation_keep_one_ontology
48
+ TEST_TEXTS.each do |text|
49
+ ann = OBAClient.new(
50
+ :ontologiesToKeepInResult => [42812],
51
+ :parse_xml => true
52
+ )
53
+ parsed = ann.execute(text)
54
+ assert parsed[:ontologies].all? {|o| o[:localOntologyId] == 42812}
55
+ end
56
+ end
57
+
58
+ def test_annotation_invalid_parameters
59
+ TEST_TEXTS.each do |text|
60
+ ann = OBAClient.new(
61
+ :ontologiesToKeepInResult => [42812],
62
+ :parse_xml => true,
63
+ :blah_blah => true,
64
+ :hoho => ["merry", "christmas"]
65
+ )
66
+ parsed = ann.execute(text)
67
+ assert parsed[:statistics].is_a?(Hash)
68
+ assert parsed[:annotations].is_a?(Array)
69
+ assert parsed[:ontologies].is_a?(Array)
70
+ end
71
+ end
72
+
73
+ def test_ontologies_pseudo_parameter
74
+ ann = OBAClient.new(:ontologies => [42812], :parse_xml => true)
75
+ TEST_TEXTS.each do |text|
76
+ parsed = ann.execute(text)
77
+ assert parsed[:ontologies].all? {|o| o[:localOntologyId] == 42812}
78
+ end
79
+ end
80
+
81
+ def test_parse
82
+ parsed = OBAClient::parse("<?xml version='1.0'></xml>")
83
+ end
84
+
85
+ def test_with_print
86
+ ann = OBAClient.new(:ontologies => [42838, 35686], :parse_xml => false)
87
+ ann = OBAClient.new(:ontologies => [42838, 35686], :parse_xml => true)
88
+ end
89
+
90
+
91
+ end
metadata ADDED
@@ -0,0 +1,101 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: oba_client
3
+ version: !ruby/object:Gem::Version
4
+ hash: 9
5
+ prerelease: false
6
+ segments:
7
+ - 2
8
+ - 0
9
+ - 3
10
+ version: 2.0.3
11
+ platform: ruby
12
+ authors:
13
+ - Rob Tirrell
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-07-16 00:00:00 -07:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: thoughtbot-shoulda
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :development
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: yard
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ hash: 3
44
+ segments:
45
+ - 0
46
+ version: "0"
47
+ type: :development
48
+ version_requirements: *id002
49
+ description: See above.
50
+ email: rpt@stanford.edu
51
+ executables: []
52
+
53
+ extensions: []
54
+
55
+ extra_rdoc_files:
56
+ - README.md
57
+ files:
58
+ - .gitignore
59
+ - History.md
60
+ - Manifest.txt
61
+ - README.md
62
+ - Rakefile
63
+ - Rakefile-2
64
+ - lib/oba_client.rb
65
+ - test/test_oba_client.rb
66
+ has_rdoc: true
67
+ homepage: http://github.com/rtirrell/oba_client
68
+ licenses: []
69
+
70
+ post_install_message:
71
+ rdoc_options:
72
+ - --charset=UTF-8
73
+ require_paths:
74
+ - lib
75
+ required_ruby_version: !ruby/object:Gem::Requirement
76
+ none: false
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ hash: 3
81
+ segments:
82
+ - 0
83
+ version: "0"
84
+ required_rubygems_version: !ruby/object:Gem::Requirement
85
+ none: false
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ hash: 3
90
+ segments:
91
+ - 0
92
+ version: "0"
93
+ requirements: []
94
+
95
+ rubyforge_project:
96
+ rubygems_version: 1.3.7
97
+ signing_key:
98
+ specification_version: 3
99
+ summary: A client for the Open Biomedical Annotator.
100
+ test_files:
101
+ - test/test_oba_client.rb