oba_client 2.0.3

Sign up to get free protection for your applications and to get access to all the features.
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