rx_nav 0.1.0

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: cb4e475d76c23889b8562311f14a44dfbd8b2922
4
+ data.tar.gz: e522d9a590ca890ca3b2f1aa0f89ad3eeba55e9f
5
+ SHA512:
6
+ metadata.gz: 796b5de96b725a354f1c2d8e223abb8f4095696908b15109fa08ae58da44da2a18e4ad365f752f0e6906b9400b88f0e88311dd790ac789bdd9fa7296bd4fc711
7
+ data.tar.gz: 17db9257fa3aa69c526fdb923669c04b1b4b963081abe76d034e09124796dcfa96c02d6bb3ca95c84beaef915b09a4701fb308ddbd117582c665ef0d09737dcf
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in rx_nav.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Jonathan Bender
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # RxNav
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'rx_nav'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install rx_nav
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/lib/rx_nav.rb ADDED
@@ -0,0 +1,27 @@
1
+ require 'net/http'
2
+ require 'nori'
3
+ require 'nokogiri'
4
+ require 'ostruct'
5
+
6
+ # Core of the API responses
7
+ require 'rx_nav/concept'
8
+ require 'rx_nav/interaction'
9
+
10
+ # Individual APIs
11
+ require 'rx_nav/ndfrt'
12
+ require 'rx_nav/rx_norm'
13
+ require 'rx_nav/rx_terms'
14
+
15
+ module RxNav
16
+
17
+ def self.nori
18
+ Nori.new(convert_tags_to: -> tag { tag.snakecase.to_sym })
19
+ end
20
+
21
+ def self.make_request query
22
+ encoded_query = URI.encode(query)
23
+ request = URI.parse('http://rxnav.nlm.nih.gov/REST' + encoded_query)
24
+ return RxNav.nori.parse(Net::HTTP.get request)
25
+ end
26
+
27
+ end
@@ -0,0 +1,58 @@
1
+ require 'ostruct'
2
+
3
+ module RxNav
4
+ class Concept < OpenStruct
5
+
6
+ def name
7
+ name = self.concept_name
8
+ name ? name.capitalize : nil
9
+ end
10
+
11
+ def kind
12
+ kind = self.concept_kind
13
+ kind ? titleize_kind(self.concept_kind) : nil
14
+ end
15
+
16
+ def to_s
17
+ display_name || full_name || full_generic_name || name
18
+ end
19
+
20
+ def get_terms_info
21
+ if self.rxcui.nil?
22
+ if self.nui.nil?
23
+ raise "This concept doesn't have a nui or rxcui"
24
+ else
25
+ rxcui = RxNav::RxNorm.find_rxcui_by_id('nui', self.nui)
26
+ end
27
+ end
28
+ rxcui = rxcui ? rxcui : self.rxcui
29
+ rxcui ? merge_concept(RxNav::RxTerms.get_info(rxcui)) : self
30
+ end
31
+
32
+ def get_ndfrt_info
33
+ if self.nui.nil?
34
+ if self.rxcui.nil?
35
+ raise "This concept doesn't have a nui or rxcui"
36
+ else
37
+ concept = RxNav::NDFRT.find_by_id('rxcui', self.rxcui)
38
+ end
39
+ end
40
+ nui = concept ? concept.nui : self.nui
41
+ nui ? merge_concept(RxNav::NDFRT.get_info(nui)) : self
42
+ end
43
+
44
+ private
45
+
46
+ def titleize_kind str
47
+ str.split("_")[0...-1].map(&:capitalize).join(" ") if str.is_a? String
48
+ end
49
+
50
+ def merge_concept concept
51
+ return self if concept.attributes.nil?
52
+ concept.attributes.each do |k,v|
53
+ self.k = v if self.k.nil?
54
+ end
55
+ end
56
+
57
+ end
58
+ end
@@ -0,0 +1,25 @@
1
+ require 'ostruct'
2
+
3
+ module RxNav
4
+ class Interaction < OpenStruct
5
+
6
+ def initialize interaction_hash
7
+ concepts = interaction_hash[:group_concepts][:concept]
8
+
9
+ @drugs = extract_drugs concepts
10
+ @nui = extract_interaction_id concepts
11
+ @severity = interaction_hash[:severity]
12
+ end
13
+
14
+ private
15
+
16
+ def extract_drugs concepts
17
+ concepts.select { |c| c[:concept_kind] != 'DRUG_INTERACTION_KIND' }.map{ |c| RxNav::Concept.new(c) }
18
+ end
19
+
20
+ def extract_interaction_id concepts
21
+ concepts.select { |c| c[:concept_kind] == 'DRUG_INTERACTION_KIND' }.first[:concept_nui]
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,113 @@
1
+ module RxNav
2
+ class NDFRT
3
+ class << self
4
+ def api_version
5
+ get_response_hash("/version")[:version][:version_name].to_s
6
+ end
7
+
8
+ def possible_options_for type
9
+ get_options type.to_s.downcase
10
+ end
11
+
12
+ def possible_associations
13
+ get_options "association"
14
+ end
15
+
16
+ def possible_types
17
+ get_options "type"
18
+ end
19
+
20
+ def possible_kinds
21
+ get_options("kind").map { |k| k.split('_')[0...-1].join('_').downcase }
22
+ end
23
+
24
+ def possible_properties
25
+ get_options "property"
26
+ end
27
+
28
+ def possible_roles
29
+ get_options "role"
30
+ end
31
+
32
+ def find_by hash
33
+ return find_by_id(hash[:type], hash[:id]) if hash.has_key? :id
34
+ return find_by_name(hash[:name], hash[:kind]) if hash.has_key? :name
35
+ end
36
+
37
+ def find_by_id type, id
38
+ type = type.upcase
39
+ id = id.to_s
40
+ query = "/idType=#{type}&idString=#{id}"
41
+ return get_concepts query
42
+ end
43
+
44
+ def find_by_name name, kind = nil
45
+ query = "/search?conceptName=#{name}"
46
+ unless kind.nil?
47
+ kind = kind.upcase + '_KIND'
48
+ query += "&kindName=#{kind}"
49
+ end
50
+ return get_concepts query
51
+ end
52
+
53
+ def find_interacting_drugs nui, scope = 3
54
+ query = "/interaction/nui=#{nui}&scope=#{scope}"
55
+ response = get_response_hash query
56
+ data = response[:group_interactions][:interactions][:group_interacting_drugs][:interacting_drug]
57
+ data = [data] unless data.is_a? Array
58
+ return data.map { |i| RxNav::Concept.new i[:concept] }
59
+ end
60
+
61
+ def find_interactions_between nuis, scope = 3
62
+ query = "/interaction?nuis=#{nuis.join('+')}&scope=#{scope}"
63
+ data = get_response_hash query
64
+ return data[:full_interaction_group][:full_interaction].map do |fi|
65
+ RxNav::Interaction.new fi[:interaction_triple_group][:interaction_triple]
66
+ end
67
+ end
68
+
69
+ def get_info nui, concept = nil
70
+ raise "Nui cannot be nil" if nui.nil?
71
+ query = "/allInfo/#{nui}"
72
+ data = get_response_hash(query)[:full_concept]
73
+ return RxNav::Concept.new(data)
74
+ end
75
+
76
+ def all_records_by_kind kind
77
+ kind = kind.upcase + "_KIND"
78
+ query = "/allconcepts?kind=#{kind}"
79
+ data = get_response_hash(query)[:group_concepts][:concept]
80
+ return data.map { |c| RxNav::Concept.new c }
81
+ end
82
+
83
+ private
84
+
85
+ def get_response_hash query
86
+ RxNav.make_request('/Ndfrt' + query)[:ndfrtdata]
87
+ end
88
+
89
+ def get_options type
90
+ data = get_response_hash "/#{type}List"
91
+ return data["#{type}_list".to_sym]["#{type}_name".to_sym].map { |a| a.to_s }
92
+ end
93
+
94
+ def get_concepts query
95
+ data = get_response_hash(query)[:group_concepts]
96
+ if data && data[:concept]
97
+ data = [data] unless data.is_a?(Array)
98
+ return data.map { |c| RxNav::Concept.new(c) }
99
+ else
100
+ return nil
101
+ end
102
+ end
103
+
104
+ end
105
+
106
+ self.singleton_class.send(:alias_method, :version, :api_version)
107
+
108
+ self.singleton_class.send(:alias_method, :available_options_for, :possible_options_for)
109
+
110
+ self.singleton_class.send(:alias_method, :all_concepts_by_kind, :all_records_by_kind)
111
+
112
+ end
113
+ end
@@ -0,0 +1,66 @@
1
+ module RxNav
2
+ class RxNorm
3
+ class << self
4
+ def search_by_name name, max_results = 20, option = 0
5
+ query = "/approximateTerm?term=#{name}&maxEntries=#{max_results}"
6
+ # The API spec includes an option parameter, but doesn't specify options
7
+ # other than the default
8
+ # query += "&option=#{option}" if option
9
+ data = get_response_hash(query)[:approximate_group][:candidate]
10
+ data = [data] if (data && !data.is_a?(Array))
11
+ return data.nil? ? nil : data.map { |c| RxNav::Concept.new(c) }
12
+ end
13
+
14
+ def find_rxcui_by_id type, id
15
+ type = type.upcase
16
+ id = id.to_s
17
+ query = "/rxcui?idtype=#{type}&id=#{id}"
18
+ return extract_rxcui query
19
+ end
20
+
21
+ def find_rxcui_by_name name
22
+ query = "/rxcui?name=#{name}"
23
+ return extract_rxcui query
24
+ end
25
+
26
+ def properties id
27
+ query = "/rxcui/#{id}/properties"
28
+ return OpenStruct.new get_response_hash(query)[:properties]
29
+ end
30
+
31
+ def quantity id
32
+ query = "/rxcui/#{id}/quantity"
33
+ return OpenStruct.new get_response_hash(query)[:quantity_group]
34
+ end
35
+
36
+ def strength id
37
+ query = "/rxcui/#{id}/strength"
38
+ return OpenStruct.new get_response_hash(query)[:strength_group]
39
+ end
40
+
41
+ def complete_info id
42
+ result = self.properties(id)
43
+ result.strength = self.strength(id).strength
44
+ result.quantity = self.quantity(id).quantity
45
+ return result
46
+ end
47
+
48
+ private
49
+
50
+ def get_response_hash query
51
+ RxNav.make_request(query)[:rxnormdata]
52
+ end
53
+
54
+ def extract_rxcui query
55
+ data = get_response_hash(query)
56
+ if data[:id_group]
57
+ data = [data] unless data.is_a?(Array)
58
+ return data.map { |c| c[:rxnorm_id] }
59
+ else
60
+ return nil
61
+ end
62
+ end
63
+
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,26 @@
1
+ module RxNav
2
+ class RxTerms
3
+ class << self
4
+ def all_concepts
5
+ query = "/allconcepts"
6
+ data = get_response_hash(query)[:min_concept_group]
7
+ return data.map{ |c| RxNav::Concept.new(c) }
8
+ end
9
+
10
+ def all_info id
11
+ query = "/rxcui/#{id}/allinfo"
12
+ data = get_response_hash(query)[:rxterms_properties]
13
+ return RxNav::Concept.new(data)
14
+ end
15
+
16
+ private
17
+
18
+ def get_response_hash query
19
+ RxNav.make_request('/RxTerms' + query)[:rxtermsdata]
20
+ end
21
+ end
22
+
23
+ self.singleton_class.send(:alias_method, :get_info, :all_info)
24
+
25
+ end
26
+ end
@@ -0,0 +1,3 @@
1
+ module RxNav
2
+ VERSION = "0.1.0"
3
+ end
data/rx_nav.gemspec ADDED
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'rx_nav/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'rx_nav'
8
+ spec.version = RxNav::VERSION
9
+ spec.authors = ['Jonathan Bender']
10
+ spec.email = ['jlbender@gmail.com']
11
+ spec.description = 'Ruby wrappers for the RxNav RESTful APIs'
12
+ spec.summary = 'Ruby-based way of interacting with the RxNav APIs (http://rxnav.nlm.nih.gov/APIsOverview.html)'
13
+ spec.homepage = 'https://github.com/jbender/rx_nav_ruby'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_dependency 'httparty'
22
+ spec.add_dependency 'nori'
23
+ spec.add_dependency 'nokogiri'
24
+
25
+ spec.add_development_dependency 'bundler', '~> 1.3'
26
+ spec.add_development_dependency 'rake'
27
+ end
metadata ADDED
@@ -0,0 +1,127 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rx_nav
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Jonathan Bender
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-11-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: httparty
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: nori
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: nokogiri
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '1.3'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: '1.3'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: Ruby wrappers for the RxNav RESTful APIs
84
+ email:
85
+ - jlbender@gmail.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - .gitignore
91
+ - Gemfile
92
+ - LICENSE.txt
93
+ - README.md
94
+ - Rakefile
95
+ - lib/rx_nav.rb
96
+ - lib/rx_nav/concept.rb
97
+ - lib/rx_nav/interaction.rb
98
+ - lib/rx_nav/ndfrt.rb
99
+ - lib/rx_nav/rx_norm.rb
100
+ - lib/rx_nav/rx_terms.rb
101
+ - lib/rx_nav/version.rb
102
+ - rx_nav.gemspec
103
+ homepage: https://github.com/jbender/rx_nav_ruby
104
+ licenses:
105
+ - MIT
106
+ metadata: {}
107
+ post_install_message:
108
+ rdoc_options: []
109
+ require_paths:
110
+ - lib
111
+ required_ruby_version: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - '>='
114
+ - !ruby/object:Gem::Version
115
+ version: '0'
116
+ required_rubygems_version: !ruby/object:Gem::Requirement
117
+ requirements:
118
+ - - '>='
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ requirements: []
122
+ rubyforge_project:
123
+ rubygems_version: 2.1.10
124
+ signing_key:
125
+ specification_version: 4
126
+ summary: Ruby-based way of interacting with the RxNav APIs (http://rxnav.nlm.nih.gov/APIsOverview.html)
127
+ test_files: []