infermedica 0.0.1

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: 24b61b9bf801f88cc86903f5234fccdf80990856
4
+ data.tar.gz: e8a6749ee08a349c3b15a06113767d4b0e47354f
5
+ SHA512:
6
+ metadata.gz: c2647ded5c5f09e2ff7b58b2f9c23e99fb8fdbee3c6dcef4dee11b4e410a1c64b1875fc6a138138b6c8ec5fe74e7a6eaf12d4e0ea2a1b3d15c9172492b42e67f
7
+ data.tar.gz: 671d82890a14f988e08d2fba0fa35a72def0a460ee2e77419b9bd4fda71c11562d93073c51264632f5d39f910ec11f7729a82097945ba0deeb823cfaa2132e37
data/.gitignore ADDED
@@ -0,0 +1,7 @@
1
+ config.yaml
2
+ tryit
3
+ tryit.sh
4
+ *.gem
5
+ lib/doc
6
+
7
+
@@ -0,0 +1,46 @@
1
+ require 'pp'
2
+ require 'yaml'
3
+ require 'infermedica'
4
+ require 'byebug'
5
+
6
+ access = YAML.load(File.read('./config.yaml'))
7
+ api = Infermedica::Api.new(access)
8
+
9
+ def dump_condition(cond)
10
+ puts "Id: #{cond.id}"
11
+ puts "Name: #{cond.name}"
12
+ puts "Categories: #{cond.categories}"
13
+ puts "Prevalence: #{cond.prevalence}"
14
+ puts "Acuteness: #{cond.acuteness}"
15
+ puts "Severity: #{cond.severity}"
16
+ puts "Extras: #{cond.extras}"
17
+ puts "Sex filter: #{cond.sex_filter}"
18
+ end
19
+
20
+ # Look for a specific condition
21
+
22
+ cond = api.get_condition('c_537')
23
+ dump_condition(cond)
24
+
25
+ # Look for a non existent condition
26
+
27
+ begin
28
+ cond = api.get_condition('fail_test')
29
+ rescue Infermedica::HttpError => e
30
+ puts
31
+ puts e
32
+ puts
33
+ end
34
+
35
+ # Get hash of all conditions.
36
+ # Note that this is not an Hash of Condition objects, but a hash of
37
+ # hashes, with the condition id as key
38
+
39
+ conditions = api.get_conditions
40
+ keys = conditions.keys
41
+ puts "The API currently has #{keys.size} conditions"
42
+
43
+ # Create an Infermedica::Condition object from one of the hash entry
44
+
45
+ my_cond = Infermedica::Condition.new(conditions['c_537'])
46
+ dump_condition(my_cond)
@@ -0,0 +1,43 @@
1
+ require 'pp'
2
+ require 'yaml'
3
+ require 'infermedica'
4
+
5
+ access = YAML.load(File.read('./config.yaml'))
6
+ api = Infermedica::Api.new(access)
7
+
8
+ # Create a diagnosis object with some initial patient info
9
+
10
+ diag = Infermedica::Diagnosis.new(sex: 'male', age: '35')
11
+
12
+ diag.add_symptom('s_21', 'present')
13
+ diag.add_symptom('s_98', 'present')
14
+ diag.add_symptom('s_107', 'present')
15
+
16
+ diag.add_pursued_conditions(['c_33', 'c_49']) # Optional
17
+
18
+ # Call the diagnosis endpoint
19
+
20
+ resp = api.diagnosis(diag)
21
+
22
+ # update diag with answers to questions in resp
23
+
24
+ diag.add_symptom('s_99', 'present')
25
+ diag.add_symptom('s_8', 'absent')
26
+ diag.add_symptom('s_25', 'present')
27
+
28
+ # Call diagnosis with updated symptoms
29
+
30
+ resp = api.diagnosis(diag)
31
+
32
+ diag.add_symptom('s_1193', 'present')
33
+ diag.add_symptom('s_604', 'present')
34
+ diag.add_symptom('s_23', 'absent')
35
+
36
+ resp = api.diagnosis(diag)
37
+
38
+ diag.add_symptom('s_122', 'absent')
39
+ resp = api.diagnosis(diag)
40
+
41
+ # Print the resulting data structure
42
+
43
+ pp resp
@@ -0,0 +1,42 @@
1
+ require 'pp'
2
+ require 'yaml'
3
+ require 'infermedica'
4
+
5
+ access = YAML.load(File.read('./config.yaml'))
6
+ api = Infermedica::Api.new(access)
7
+
8
+ # Create a diagnosis object
9
+
10
+ req = Infermedica::Diagnosis.new(sex: 'female', age: '35')
11
+
12
+ # Add some symptoms
13
+
14
+ req.add_symptom('s_10', 'present')
15
+ req.add_symptom('s_608', 'present')
16
+ req.add_symptom('s_1394', 'absent')
17
+ req.add_symptom('s_216', 'present')
18
+ req.add_symptom('s_9', 'present')
19
+ req.add_symptom('s_188', 'present')
20
+
21
+ # Can't get a explaination unless we have a target
22
+
23
+ begin
24
+ resp = api.explain(req)
25
+ rescue Infermedica::MissingField => e
26
+ puts
27
+ puts e
28
+ puts
29
+ end
30
+
31
+ # Add a target condition
32
+
33
+ req.add_target('c_371')
34
+
35
+ # See if the symptoms fit the condition
36
+
37
+ resp = api.explain(req)
38
+
39
+ # Print the resulting data structure
40
+
41
+ pp resp
42
+
data/examples/info.rb ADDED
@@ -0,0 +1,17 @@
1
+ require 'pp'
2
+ require 'yaml'
3
+ require 'infermedica'
4
+
5
+ access = YAML.load(File.read('./config.yaml'))
6
+ api = Infermedica::Api.new(access)
7
+
8
+ # Get info about the API
9
+
10
+ info = api.get_info
11
+
12
+ puts "API updated at: #{info.updated_at}"
13
+ puts "Condition count: #{info.conditions_count}"
14
+ puts "Lab test count: #{info.lab_tests_count}"
15
+ puts "Risk factor count: #{info.risk_factors_count}"
16
+ puts "Symptom count: #{info.symptoms_count}"
17
+
@@ -0,0 +1,42 @@
1
+ require 'pp'
2
+ require 'yaml'
3
+ require 'infermedica'
4
+ require 'byebug'
5
+
6
+ access = YAML.load(File.read('./config.yaml'))
7
+ api = Infermedica::Api.new(access)
8
+
9
+ def dump_lab_test(lt)
10
+ puts "Id: #{lt.id}"
11
+ puts "Name: #{lt.name}"
12
+ puts "Category: #{lt.category}"
13
+ puts "Result: #{lt.results}"
14
+ end
15
+
16
+ # Look for a specific lab test
17
+
18
+ lt = api.get_lab_test('lt_81')
19
+ dump_lab_test(lt)
20
+
21
+ # Look for a non existent symptom
22
+
23
+ begin
24
+ sym = api.get_lab_test('fail_test')
25
+ rescue Infermedica::HttpError => e
26
+ puts
27
+ puts e
28
+ puts
29
+ end
30
+
31
+ # Get a Hash of all lab tests
32
+ # Note that this is not an Hash of LabTest objects, but a hash of
33
+ # hashes, with the lab test id as key
34
+
35
+ lts = api.get_lab_tests
36
+ keys = lts.keys
37
+ puts "The API currently has #{keys.size} lab tests"
38
+
39
+ # Create an Infermedica::LabTest object from one of the hash entry
40
+
41
+ my_lt = Infermedica::LabTest.new(lts['lt_81'])
42
+ dump_lab_test(my_lt)
@@ -0,0 +1,45 @@
1
+ require 'pp'
2
+ require 'yaml'
3
+ require 'infermedica'
4
+ require 'byebug'
5
+
6
+ access = YAML.load(File.read('./config.yaml'))
7
+ api = Infermedica::Api.new(access)
8
+
9
+ def dump_risk_factor(rf)
10
+ puts "Id: #{rf.id}"
11
+ puts "Name: #{rf.name}"
12
+ puts "Category: #{rf.category}"
13
+ puts "Extras: #{rf.extras}"
14
+ puts "Sex filter: #{rf.sex_filter}"
15
+ puts "Image url: #{rf.image_url}"
16
+ puts "Image source: #{rf.image_source}"
17
+ end
18
+
19
+ # Look for a specific risk factor
20
+
21
+ rf = api.get_risk_factor('p_37')
22
+ dump_risk_factor(rf)
23
+
24
+ # Look for a non existent risk factor
25
+
26
+ begin
27
+ sym = api.get_risk_factor('fail_test')
28
+ rescue Infermedica::HttpError => e
29
+ puts
30
+ puts e
31
+ puts
32
+ end
33
+
34
+ # Get a Hash of all risk factors
35
+ # Note that this is not a Hash of LabTest objects, but a hash of
36
+ # hashes, with the lab test id as key
37
+
38
+ rfs = api.get_risk_factors
39
+ keys = rfs.keys
40
+ puts "The API currently has #{keys.size} risk factors"
41
+
42
+ # Create an Infermedica::RiskFactor object from one of the hash entry
43
+
44
+ my_rf = Infermedica::RiskFactor.new(rfs['p_37'])
45
+ dump_risk_factor(my_rf)
@@ -0,0 +1,16 @@
1
+ require 'pp'
2
+ require 'yaml'
3
+ require 'infermedica'
4
+
5
+ access = YAML.load(File.read('./config.yaml'))
6
+ api = Infermedica::Api.new(access)
7
+
8
+ puts 'Look for evidences containing phrase headache:'
9
+ puts api.search('headache')
10
+ puts 'Look for evidences containing phrase breast, only for female symptoms:'
11
+ puts api.search('breast', sex: 'female')
12
+ puts 'Same, but only 5 results'
13
+ puts api.search('breast', sex: 'female', max_results: 5)
14
+ puts 'With filters now. Only search in symptom and risk_factor'
15
+ puts api.search('trauma', filters: ['symptom', 'risk_factor'])
16
+
@@ -0,0 +1,49 @@
1
+ require 'pp'
2
+ require 'yaml'
3
+ require 'infermedica'
4
+ require 'byebug'
5
+
6
+ access = YAML.load(File.read('./config.yaml'))
7
+ api = Infermedica::Api.new(access)
8
+
9
+ def dump_symptom(s)
10
+ puts "Id: #{s.id}"
11
+ puts "Name: #{s.name}"
12
+ puts "Category: #{s.category}"
13
+ puts "Children: #{s.children}"
14
+ puts "Extras: #{s.extras}"
15
+ puts "Image Source: #{s.image_source}"
16
+ puts "Image url: #{s.image_url}"
17
+ puts "Parent Id: #{s.parent_id}"
18
+ puts "Parent Relation: #{s.parent_relation}"
19
+ puts "Sex filter: #{s.sex_filter}"
20
+ puts "Question: #{s.question}"
21
+ end
22
+
23
+ # Look for a specific symptom
24
+
25
+ sym = api.get_symptom('s_56')
26
+ dump_symptom(sym)
27
+
28
+ # Look for a non existent symptom
29
+
30
+ begin
31
+ sym = api.get_symptom('fail_test')
32
+ rescue Infermedica::HttpError => e
33
+ puts
34
+ puts e
35
+ puts
36
+ end
37
+
38
+ # Get a Hash of all symptoms
39
+ # Note that this is not a Hash of symptom objects, but a hash of
40
+ # hashes, with the symptom id as key
41
+
42
+ symptoms = api.get_symptoms
43
+ keys = symptoms.keys
44
+ puts "The API currently has #{keys.size} symptoms"
45
+
46
+ # Create an Infermedica::Symptom object from one of the hash entry
47
+
48
+ my_sym = Infermedica::Symptom.new(symptoms['s_551'])
49
+ dump_symptom(my_sym)
@@ -0,0 +1,15 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'infermedica'
3
+ s.version = '0.0.1'
4
+ s.date = '2017-01-09'
5
+ s.summary = 'Provide a Ruby interface to the Infermedica REST API'
6
+ s.description = 'A Ruby interface to the Infermedica REST API'
7
+ s.authors = ['Bruno Melli']
8
+ s.email = 'mjskier@tegali.com'
9
+ s.files = `git ls-files`.split($\)
10
+ s.require_paths = ['lib']
11
+ s.license = 'MIT'
12
+ s.homepage = 'https://github.com/mjskier/infermedica'
13
+ s.add_runtime_dependency 'json', '~>1.8', '>= 1.8.3'
14
+ end
15
+
@@ -0,0 +1,13 @@
1
+ module Infermedica
2
+
3
+ # = Condition
4
+ #
5
+ # Represents an infermedica condition
6
+
7
+ class Condition
8
+ include Infermedica::Model
9
+ attr_reader :id, :name, :categories, :prevalence, :acuteness,
10
+ :severity, :extras, :sex_filter
11
+ end
12
+
13
+ end
@@ -0,0 +1,80 @@
1
+ module Infermedica
2
+
3
+ # = Connection
4
+ # handles the http communication
5
+ # No assumption is made about content or return values
6
+ # The caller is responsible for converting to/from json
7
+
8
+ class Connection
9
+
10
+ # Default host. Can be overwritten with *endpoint: '/some/endpoint'
11
+ # When creating the Connection
12
+
13
+ ENDPOINT = 'https://api.infermedica.com'
14
+
15
+ def initialize(args)
16
+ raise ArgumentError,
17
+ 'Infermedica::Connection::initialize argument needs to be a Hash' unless
18
+ args.is_a?(Hash)
19
+ raise ArgumentError, 'api_id is required' unless args.key?(:api_id)
20
+ raise ArgumentError, 'api_key is required' unless args.key?(:api_key)
21
+ args[:endpoint] = ENDPOINT unless args.key?(:endpoint)
22
+
23
+ # Probably need more argument validation here...
24
+ args.each do |k, v|
25
+ instance_variable_set(:"@#{k}", v)
26
+ end
27
+
28
+ uri = URI.parse(@endpoint)
29
+ @http = Net::HTTP.new(uri.host, uri.port)
30
+ @http.use_ssl = true
31
+
32
+ @headers = {
33
+ 'App-Id': @api_id,
34
+ 'App-Key': @api_key,
35
+ }
36
+ @headers['Dev-Mode'] = args[:dev_mode] if args.key?(:dev_mode)
37
+ end
38
+
39
+ # TODO: Might have to deal with args
40
+
41
+ # Send a get request to the given path
42
+ def get(path)
43
+ # TODO: do more hardening on the path
44
+ request = Net::HTTP::Get.new('/v2' + path, @headers)
45
+ send_request(request)
46
+ end
47
+
48
+ # Send a post request to the given path
49
+ # json is the data to be passed to the post command
50
+ # params are additional header entries
51
+
52
+ def post(path, json, params = {})
53
+ request = Net::HTTP::Post.new('/v2' + path, @headers)
54
+ request.add_field('Content-Type', 'application/json')
55
+ request.body = json
56
+ params.each do |k, v|
57
+ request[k] = v
58
+ end
59
+ send_request(request)
60
+ end
61
+
62
+ private
63
+
64
+ # Check the response code, raise an exception in case of error
65
+
66
+ def validate_response(response) # :nodoc:
67
+ code = response.code.to_i
68
+ raise HttpError, "#{code} #{response.msg}" if code < 200 || code > 299
69
+ end
70
+
71
+ # Send the request, validate it
72
+ # Parse the JSON response into a data structure.
73
+
74
+ def send_request(request) # :nodoc:
75
+ response = @http.request(request)
76
+ validate_response(response)
77
+ JSON.parse(response.body)
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,73 @@
1
+ module Infermedica
2
+
3
+ # = Diagnosis
4
+ #
5
+ # Interface to the /diagnosis and /explain endpoints
6
+ # See examples/diagnosis.rb and examples/explain.rb for example use
7
+
8
+ class Diagnosis
9
+ attr_accessor :sex, :age, :symptoms, :case, :extras, :extras_permanent,
10
+ :lab_tests, :pursued, :risk_factors,
11
+ :case_id, :target
12
+
13
+ def initialize(args)
14
+ raise ArgumentError, 'Patient sex is required' unless args.key?(:sex)
15
+ raise ArgumentError, 'Patient age is required' unless args.key?(:age)
16
+
17
+ args[:time] = Time.now unless args.key?(:time)
18
+ args[:case_id] = nil unless args.key?(:case_id)
19
+
20
+ args.each do |k, v|
21
+ instance_variable_set(:"@#{k}", v)
22
+ end
23
+
24
+ %w[ symptoms lab_tests risk_factors pursued ].each do |k|
25
+ args.key?(k) || instance_variable_set(:"@#{k}", Array.new)
26
+ end
27
+
28
+ @extras = {}
29
+ @extras_permanent = {}
30
+ end
31
+
32
+ # Add a symptom to the list of symptom kept in this object
33
+ # k: symptom code (for example 's_10'
34
+ # v: symptom appropriate value (for example 'present')
35
+
36
+ def add_symptom(k, v)
37
+ @symptoms << { 'id': k, 'choice_id': v }
38
+ end
39
+
40
+ # Add a pursued_conditions
41
+ # TODO: find out what these are and how they are used
42
+
43
+ def add_pursued_conditions(args)
44
+ @pursued.push(*args)
45
+ end
46
+
47
+ # Set a target condition that will be used by the /explain endpoint
48
+ # v: The target condition (for example 'c_371')
49
+
50
+ def add_target(v)
51
+ @target = v
52
+ end
53
+
54
+ # Convert self to a json representation
55
+
56
+ def to_json(*a)
57
+ h = {
58
+ 'sex': @sex,
59
+ 'age': @age,
60
+ 'evidence': @symptoms,
61
+ 'extras': @extras,
62
+ }
63
+ h['target'] = @target unless @target.nil?
64
+ h['pursued'] = @pursued unless @pursued.empty?
65
+ h['lab_tests'] = @lab_tests unless @lab_tests.empty?
66
+ h['risk_factors'] = @risk_factors unless @risk_factors.empty?
67
+ h['extras_permanent'] = @extras_permanent unless @extras_permanent.empty?
68
+ h.to_json(*a)
69
+ end
70
+
71
+ end # class Diagnosis
72
+
73
+ end # module
@@ -0,0 +1,16 @@
1
+ module Infermedica
2
+
3
+ # = Info
4
+ #
5
+ # Class holding the response to an /info request
6
+ #
7
+ # This includes the date and version of the API, as well as counts for the
8
+ # various collections available from the API
9
+
10
+ class Info
11
+ include Infermedica::Model
12
+ attr_reader :updated_at, :conditions_count, :symptoms_count,
13
+ :risk_factors_count, :lab_tests_count
14
+ end
15
+
16
+ end
@@ -0,0 +1,12 @@
1
+ module Infermedica
2
+
3
+ # = LabTest
4
+ #
5
+ # Representation of a Lab Test
6
+
7
+ class LabTest
8
+ include Infermedica::Model
9
+ attr_reader :id, :name, :category, :results
10
+ end
11
+
12
+ end
@@ -0,0 +1,16 @@
1
+ module Infermedica
2
+
3
+ # = Model
4
+ # Common methods used by other classes
5
+
6
+ module Model
7
+
8
+ # Common way to initialize an object from an Hash
9
+
10
+ def initialize(h)
11
+ h.keys.each do |k|
12
+ instance_variable_set(:"@#{k}", h[k])
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,12 @@
1
+ module Infermedica
2
+
3
+ # = RiskFactor
4
+ # Represent an Infermedica risk factor object
5
+
6
+ class RiskFactor
7
+ include Infermedica::Model
8
+ attr_accessor :id, :name, :category, :extras, :sex_filter,
9
+ :image_url, :image_source
10
+ end
11
+
12
+ end
@@ -0,0 +1,13 @@
1
+ module Infermedica
2
+
3
+ # = Symptom
4
+ # Represents an Infermedica symptom
5
+
6
+ class Symptom
7
+ include Infermedica::Model
8
+
9
+ attr_accessor :id, :name, :category, :children, :extras,
10
+ :image_source, :image_url, :parent_id,
11
+ :parent_relation, :question, :sex_filter
12
+ end
13
+ end
@@ -0,0 +1,170 @@
1
+ require 'net/http'
2
+ require 'json'
3
+ require 'uri'
4
+
5
+ require_relative 'infermedica/model'
6
+ require_relative 'infermedica/conditions'
7
+ require_relative 'infermedica/diagnosis'
8
+ require_relative 'infermedica/info'
9
+ require_relative 'infermedica/lab_tests'
10
+ require_relative 'infermedica/risk_factors'
11
+ require_relative 'infermedica/symptoms'
12
+ require_relative 'infermedica/connection'
13
+
14
+ # = Infermedica: A ruby interface to the infermedica REST API
15
+ #
16
+ # == Quick Start
17
+ #
18
+ # You will need a valid *api_id* and *api_key*.
19
+ # Get one from https://developer.infermedica.com/docs/api
20
+ #
21
+ # To start using the API, require the infermedica gem and create an
22
+ # Infermedica::Api object, passing the api_id and api_key to the constructor
23
+ #
24
+ # The constructor takes a hash as argument, so you have different options
25
+ # to pass the id and key:
26
+ #
27
+ # require 'infermedica'
28
+ # api = Infermedica::Api.new(api_id: 'xxxxx', api_key: 'xxxxxxxxxxx')
29
+ #
30
+ # or put the key and id in a .yaml file, read it and pass the resulting hash
31
+ #
32
+ # In config.yaml
33
+ # :api:id: xxxxx
34
+ # :api_key: xxxxxxxxxxx
35
+ #
36
+ # In your script
37
+ #
38
+ # require 'infermedica'
39
+ # require 'yaml'
40
+ # access = YAML.load(File.read('./config.yaml'))
41
+ # api = Infermedica::Api.new(access)
42
+
43
+ module Infermedica
44
+
45
+ # Exceptions
46
+
47
+ # HTTP error raised when we don't get the expected result from an API call
48
+ class HttpError < StandardError; end
49
+
50
+ # Missing field or field not set in a request
51
+ class MissingField < StandardError; end
52
+
53
+ # Api defines all operations available from the REST API
54
+
55
+ class Api
56
+
57
+ def get_conditions # return a Hash of known conditions
58
+ get_collection('/conditions')
59
+ end
60
+
61
+ def get_condition(id) # return a Condition object
62
+ response = @connection.get("/conditions/#{id}")
63
+ return Condition.new(response)
64
+ end
65
+
66
+ def get_lab_tests # erturn a Hash of lab_tests
67
+ get_collection('/lab_tests')
68
+ end
69
+
70
+ def get_lab_test(id) # return a LabTest object
71
+ response = @connection.get("/lab_tests/#{id}")
72
+ return LabTest.new(response)
73
+ end
74
+
75
+ def get_risk_factors # return a Hash of risk_factors
76
+ get_collection('/risk_factors')
77
+ end
78
+
79
+ def get_risk_factor(id) # return a RiskFactor object
80
+ response = @connection.get("/risk_factors/#{id}")
81
+ return RiskFactor.new(response)
82
+ end
83
+
84
+ def get_symptoms # return a list of symptoms
85
+ get_collection('/symptoms')
86
+ end
87
+
88
+ def get_symptom(id) # return a Symptom object
89
+ response = @connection.get("/symptoms/#{id}")
90
+ return Symptom.new(response)
91
+ end
92
+
93
+ # Get the Api info (version, date,
94
+ # number of conditions, lab_tests, risk_factors, symptoms
95
+
96
+ def get_info
97
+ response = @connection.get("/info")
98
+ return Info.new(response)
99
+ end
100
+
101
+ # Submit a diagnosis object to get a diagnosis, or a list of additional
102
+ # conditions required to refine the diagnosis
103
+ # See examples/diagnosis.rb for an example
104
+ def diagnosis(diag)
105
+ response = @connection.post('/diagnosis', diag.to_json)
106
+ end
107
+
108
+ # Submit a diagnosis object to get an explanation
109
+ # See examples/explain.rb for an example
110
+ def explain(req, args = {})
111
+ raise Infermedica::MissingField, 'target must be set' if
112
+ req.target.nil?
113
+ response = @connection.post('/explain', req.to_json, args)
114
+ end
115
+
116
+ # Submit a search request, possibly filtered by where to look
117
+ # See examples/search.rb for an example
118
+
119
+ def search(phrase, args = {})
120
+ url = '/search?phrase=' + phrase
121
+ args['max_results'] = 8 unless args.key?('max_results')
122
+ args.each do |k, v|
123
+ puts "'#{k}': #{v.class} #{v}"
124
+ if v.is_a?(Array) && k.to_s == 'filters'
125
+ v.each { |e| url << "&type=#{e}" }
126
+ else
127
+ url << "&#{k}=#{v}"
128
+ end
129
+ end
130
+ puts "url: #{url}"
131
+ response = @connection.get(url)
132
+ end
133
+
134
+ # Create a new Infermedica::Api object.
135
+ # Takes a hash as argument.
136
+ # The *api_id* and *api_key* entries are required.
137
+
138
+ def initialize(args)
139
+ raise ArgumentError,
140
+ 'Infermedica::Api::initialize argument needs to be a Hash)' unless
141
+ args.is_a?(Hash)
142
+ raise ArgumentError, 'api_id is required' unless args.key?(:api_id)
143
+ raise ArgumentError, 'api_key is required' unless args.key?(:api_key)
144
+
145
+ connection_args = { api_id: args[:api_id], api_key: args[:api_key] }
146
+ connection_args[:endpoint] = args[:endpoint] if args.key?(:endpoint)
147
+ @connection = Connection.new(connection_args)
148
+
149
+ # Probably need more argument validation here...
150
+ args.each do |k, v|
151
+ instance_variable_set(:"@#{k}", v)
152
+ end
153
+ end
154
+
155
+ private
156
+
157
+ # Common frontend to the public methods that require collections
158
+
159
+ def get_collection(path) # :nodoc:
160
+ response = @connection.get(path)
161
+ # response is an array
162
+ collection = {}
163
+ response.each do |item|
164
+ collection[item['id']] = item
165
+ end
166
+ collection
167
+ end
168
+
169
+ end # class Api
170
+ end # module
data/test/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ task :default => :test
2
+ task :test do
3
+ Dir.glob('./unit/*.rb').each do |f|
4
+ puts
5
+ puts "Running test on #{f}"
6
+ puts
7
+ ruby f
8
+ end
9
+ end
@@ -0,0 +1,39 @@
1
+ require 'minitest/autorun'
2
+ require 'infermedica'
3
+
4
+ class TestCondition < Minitest::Test
5
+
6
+ def setup
7
+ a_condition = {
8
+ "id"=>"c_537",
9
+ "name"=>"Abdominal obesity",
10
+ "prevalence"=>"common",
11
+ "acuteness"=>"chronic",
12
+ "severity"=>"moderate",
13
+ "sex_filter"=>"both",
14
+ "categories"=>["Internal Medicine"],
15
+ "extras"=> {
16
+ "hint"=>"Please consult your family doctor.",
17
+ "icd10_code"=>"E65"
18
+ },
19
+ }
20
+
21
+ @condition = Infermedica::Condition.new(a_condition)
22
+ end
23
+
24
+
25
+ def test_condition_creation
26
+ assert_equal @condition.id, 'c_537'
27
+ assert_equal @condition.name, 'Abdominal obesity'
28
+ assert_equal @condition.prevalence, 'common'
29
+ assert_equal @condition.acuteness, 'chronic'
30
+ assert_equal @condition.severity, 'moderate'
31
+ assert_equal @condition.sex_filter, 'both'
32
+ assert_equal @condition.categories.class, Array
33
+ assert_equal @condition.categories[0], 'Internal Medicine'
34
+ assert_equal @condition.extras.class, Hash
35
+ assert_includes @condition.extras, 'hint'
36
+ assert_equal @condition.extras['icd10_code'], 'E65'
37
+ end
38
+
39
+ end
@@ -0,0 +1,44 @@
1
+ require 'minitest/autorun'
2
+ require 'infermedica'
3
+
4
+ class TestCondition < Minitest::Test
5
+
6
+ def setup
7
+ @diag = Infermedica::Diagnosis.new(sex: 'male', age: '35')
8
+ end
9
+
10
+ def test_diagnosis_creation
11
+ assert_equal @diag.sex, 'male'
12
+ assert_equal @diag.age, '35'
13
+ end
14
+
15
+ def test_symptom_addition
16
+ assert_equal @diag.symptoms.class, Array
17
+ assert_equal @diag.symptoms.empty?, true
18
+ @diag.add_symptom('s_10', 'present')
19
+ assert_equal @diag.symptoms[0][:id], 's_10'
20
+ assert_equal @diag.symptoms[0][:choice_id], 'present'
21
+ end
22
+
23
+ def test_pursued_addition
24
+ assert_equal @diag.pursued.class, Array
25
+ assert_equal @diag.pursued.empty?, true
26
+ @diag.add_pursued_conditions(['c_33', 'c_49'])
27
+ assert_equal @diag.pursued.size, 2
28
+ assert_equal @diag.pursued[0], 'c_33'
29
+ end
30
+
31
+ def test_target_addition
32
+ assert_equal @diag.target, nil
33
+ @diag.add_target('c_371')
34
+ assert_equal @diag.target, 'c_371'
35
+ end
36
+
37
+ def test_the_to_json_method
38
+ json = @diag.to_json
39
+ assert_equal json.class, String
40
+ match = json =~ /\"age\":\"(\d+)\"/
41
+ assert_equal $1, '35'
42
+ end
43
+
44
+ end
data/test/unit/info.rb ADDED
@@ -0,0 +1,27 @@
1
+ require 'minitest/autorun'
2
+ require 'infermedica'
3
+
4
+ class TestCondition < Minitest::Test
5
+
6
+ def setup
7
+ the_info = {
8
+ updated_at: '2016-11-21T13:26:04Z',
9
+ conditions_count: '504',
10
+ symptoms_count: '1110',
11
+ risk_factors_count: '42',
12
+ lab_tests_count: '457'
13
+ }
14
+
15
+ @info = Infermedica::Info.new(the_info)
16
+ end
17
+
18
+
19
+ def test_info_creation
20
+ assert_equal @info.updated_at, '2016-11-21T13:26:04Z'
21
+ assert_equal @info.conditions_count, '504'
22
+ assert_equal @info.symptoms_count, '1110'
23
+ assert_equal @info.risk_factors_count, '42'
24
+ assert_equal @info.lab_tests_count, '457'
25
+ end
26
+
27
+ end
@@ -0,0 +1,30 @@
1
+ require 'minitest/autorun'
2
+ require 'infermedica'
3
+
4
+ class TestCondition < Minitest::Test
5
+
6
+ def setup
7
+ a_lab_test = {
8
+ 'id': 'lt_81',
9
+ 'name': 'Blood urea nitrogen (BUN)',
10
+ 'category': 'Biochemistry',
11
+ 'results' => [
12
+ {'id' => 'lt_81_1', 'type' => 'low'},
13
+ {'id' => 'lt_81_2', 'type' => 'normal'},
14
+ {'id' => 'lt_81_3', 'type' => 'high'}]}
15
+
16
+ @lab_test = Infermedica::LabTest.new(a_lab_test)
17
+ end
18
+
19
+
20
+ def test_lab_test_creation
21
+ assert_equal @lab_test.id, 'lt_81'
22
+ assert_equal @lab_test.name, 'Blood urea nitrogen (BUN)'
23
+ assert_equal @lab_test.category, 'Biochemistry'
24
+ assert_equal @lab_test.results.class, Array
25
+ assert_equal @lab_test.results[0].class, Hash
26
+ assert_equal @lab_test.results[0]['id'], 'lt_81_1'
27
+ assert_equal @lab_test.results[1]['type'], 'normal'
28
+ end
29
+
30
+ end
@@ -0,0 +1,31 @@
1
+ require 'minitest/autorun'
2
+ require 'infermedica'
3
+
4
+ class TestCondition < Minitest::Test
5
+
6
+ def setup
7
+ a_risk_factor = {
8
+ 'id': 'p_37',
9
+ 'name': 'Mushroom consumption',
10
+ 'category': 'Risk factors',
11
+ 'extras': {},
12
+ 'sex_filter': 'both',
13
+ 'image_url': nil,
14
+ 'image_source': nil
15
+ }
16
+
17
+ @risk_factor = Infermedica::RiskFactor.new(a_risk_factor)
18
+ end
19
+
20
+
21
+ def test_risk_factor_creation
22
+ assert_equal @risk_factor.id, 'p_37'
23
+ assert_equal @risk_factor.name, 'Mushroom consumption'
24
+ assert_equal @risk_factor.category, 'Risk factors'
25
+ assert_equal @risk_factor.extras.class, Hash
26
+ assert_equal @risk_factor.sex_filter, 'both'
27
+ assert_equal @risk_factor.image_url, nil
28
+ assert_equal @risk_factor.image_source, nil
29
+ end
30
+
31
+ end
@@ -0,0 +1,46 @@
1
+ require 'minitest/autorun'
2
+ require 'infermedica'
3
+
4
+ class TestCondition < Minitest::Test
5
+
6
+ def setup
7
+ a_symptom = {
8
+ 'id'=>'s_551',
9
+ 'name'=>'Toothache',
10
+ 'category'=>'Signs and symptoms',
11
+ 'extras'=>{},
12
+ 'children'=> [
13
+ {'id'=>'s_339', 'parent_relation'=>'diminishing_factor'},
14
+ {'id'=>'s_55', 'parent_relation'=>'exacerbating_factor'},
15
+ {'id'=>'s_231', 'parent_relation'=>'exacerbating_factor'},
16
+ {'id'=>'s_56', 'parent_relation'=>'exacerbating_factor'},
17
+ {'id'=>'s_240', 'parent_relation'=>'severity'},
18
+ {'id'=>'s_233', 'parent_relation'=>'severity'},
19
+ {'id'=>'s_279', 'parent_relation'=>'character'},
20
+ {'id'=>'s_267', 'parent_relation'=>'location'}],
21
+ 'sex_filter'=>'both',
22
+ 'image_url'=>nil,
23
+ 'image_source'=>nil,
24
+ 'parent_id'=>nil,
25
+ 'parent_relation'=>nil
26
+ }
27
+
28
+ @symptom = Infermedica::Symptom.new(a_symptom)
29
+ end
30
+
31
+
32
+ def test_symptom_creation
33
+ assert_equal @symptom.id, 's_551'
34
+ assert_equal @symptom.name, 'Toothache'
35
+ assert_equal @symptom.category, 'Signs and symptoms'
36
+ assert_equal @symptom.extras.class, Hash
37
+ assert_equal @symptom.sex_filter, 'both'
38
+ assert_equal @symptom.image_url, nil
39
+ assert_equal @symptom.parent_id, nil
40
+ assert_equal @symptom.parent_relation, nil
41
+ assert_equal @symptom.children.class, Array
42
+ assert_equal @symptom.children[1]['id'], 's_55'
43
+ assert_equal @symptom.children[4]['parent_relation'], 'severity'
44
+ end
45
+
46
+ end
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: infermedica
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Bruno Melli
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-01-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: json
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.8'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 1.8.3
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '1.8'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 1.8.3
33
+ description: A Ruby interface to the Infermedica REST API
34
+ email: mjskier@tegali.com
35
+ executables: []
36
+ extensions: []
37
+ extra_rdoc_files: []
38
+ files:
39
+ - ".gitignore"
40
+ - examples/condition.rb
41
+ - examples/diagnosis.rb
42
+ - examples/explain.rb
43
+ - examples/info.rb
44
+ - examples/lab_test.rb
45
+ - examples/risk_factor.rb
46
+ - examples/search.rb
47
+ - examples/symptom.rb
48
+ - infermedica.gemspec
49
+ - lib/infermedica.rb
50
+ - lib/infermedica/conditions.rb
51
+ - lib/infermedica/connection.rb
52
+ - lib/infermedica/diagnosis.rb
53
+ - lib/infermedica/info.rb
54
+ - lib/infermedica/lab_tests.rb
55
+ - lib/infermedica/model.rb
56
+ - lib/infermedica/risk_factors.rb
57
+ - lib/infermedica/symptoms.rb
58
+ - test/Rakefile
59
+ - test/unit/condition.rb
60
+ - test/unit/diagnosis.rb
61
+ - test/unit/info.rb
62
+ - test/unit/lab_test.rb
63
+ - test/unit/risk_factor.rb
64
+ - test/unit/symptom.rb
65
+ homepage: https://github.com/mjskier/infermedica
66
+ licenses:
67
+ - MIT
68
+ metadata: {}
69
+ post_install_message:
70
+ rdoc_options: []
71
+ require_paths:
72
+ - lib
73
+ required_ruby_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ required_rubygems_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ requirements: []
84
+ rubyforge_project:
85
+ rubygems_version: 2.5.1
86
+ signing_key:
87
+ specification_version: 4
88
+ summary: Provide a Ruby interface to the Infermedica REST API
89
+ test_files: []