api_consumer_json 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/api_consumer.rb +168 -0
  3. metadata +87 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a6134edeadbdf29c8db50d9332336f7783bb145c
4
+ data.tar.gz: 9a47d5fc99efcd05adbdbebb6f07bc74b9dfe8e4
5
+ SHA512:
6
+ metadata.gz: dfd9b248619b527aee67a10fb04ed25d0d0f4ff97178fc59080ebfdaaf940f62f73b807f6b6108ef25213f7881515668ef9af4800fa03cb803299ac0308b1c0f
7
+ data.tar.gz: c5f2381441b8af68279e6d21697cb9ab14c5aac0c4f38d75521e7d52dd1c680eb3cdaac9c707ef08b7141fb6c383b3422982f2fdd879c5b52e13fac2e6f125ae
@@ -0,0 +1,168 @@
1
+ class APIConsumer
2
+ require 'yaml'
3
+ require 'net/https'
4
+ require 'uri'
5
+ require 'json'
6
+ require 'uber_cache'
7
+ require 'logger'
8
+
9
+ class << self
10
+ @settings = {}
11
+ def inherited(subclass)
12
+ configs = YAML.load_file("config/#{snake_case(subclass)}.yml")
13
+ configs[snake_case(subclass)].each{ |k,v| subclass.set(k.to_sym, v) }
14
+ subclass.set_logger(Logger.new(subclass.settings[:log_file] || "./log/#{snake_case(subclass)}_api.log"), subclass.settings[:log_level])
15
+ super
16
+ end
17
+
18
+ def set_logger(logger, level=nil)
19
+ @logger = logger.nil? ? Logger.new(STDERR) : logger
20
+ set_log_level(level)
21
+ end
22
+
23
+ def log
24
+ @logger
25
+ end
26
+
27
+ def set_log_level(level=nil)
28
+ if level.nil?
29
+ level = if([nil, "development", "test"].include?(ENV['RACK_ENV']))
30
+ :info
31
+ else
32
+ :warn
33
+ end
34
+ end
35
+ @logger.level = case level.to_sym
36
+ when :debug
37
+ Logger::DEBUG
38
+ when :info
39
+ Logger::INFO
40
+ when :error
41
+ Logger::ERROR
42
+ when :fatal
43
+ Logger::FATAL
44
+ else #warn
45
+ Logger::WARN
46
+ end
47
+ end
48
+
49
+ def memcache?
50
+ settings[:use_memcache]
51
+ end
52
+
53
+ def memcache_hosts
54
+ settings[:memcache_hosts]
55
+ end
56
+
57
+ def set(key, val)
58
+ settings[key] = val
59
+ end
60
+
61
+ def settings
62
+ @settings ||= {}
63
+ end
64
+
65
+ DEFAULT_REQUEST_OPTS = {
66
+ :method => :get,
67
+ :headers => {
68
+ "Accept" => "application/json",
69
+ "Content-Type" => "application/json",
70
+ "User-Agent" => "API-CONSUMER-#{ENV['RACK_ENV'] || 'dev'}"
71
+ },
72
+ :ttl => 300
73
+ }
74
+ def do_request(path, conn, opts = {}, &blk)
75
+ if(opts[:verbose])
76
+ log.debug("Sending request to: #{conn.address}#{':' + conn.port.to_s if conn.port}#{path}")
77
+ end
78
+ if opts[:key] # cache if key sent
79
+ read_val = nil
80
+ return read_val if !opts[:reload] && read_val = cache.obj_read(opts[:key])
81
+ opts[:ttl] ||= settings[:ttl] || DEFAULT_REQUEST_OPTS[:ttl]
82
+ end
83
+ opts[:headers] = DEFAULT_REQUEST_OPTS[:headers].merge(opts[:headers] || {})
84
+ opts[:method] = opts[:method] || DEFAULT_REQUEST_OPTS[:method]
85
+
86
+ req = if( opts[:method] == :get)
87
+ Net::HTTP::Get.new(path)
88
+ elsif( opts[:method] == :post)
89
+ Net::HTTP::Post.new(path)
90
+ elsif( opts[:method] == :delete)
91
+ Net::HTTP::Delete.new(path)
92
+ elsif( opts[:method] == :put)
93
+ Net::HTTP::Put.new(path)
94
+ else
95
+ log.error "BUG - method=>(#{opts[:method]})"
96
+ end
97
+ opts[:headers].each { |k,v| req[k] = v }
98
+ settings[:headers].each { |k,v| req[k] = v } if settings[:headers]
99
+ req.basic_auth settings[:api_user], settings[:api_password] if settings[:api_user] && settings[:api_password]
100
+ req["connection"] = 'keep-alive'
101
+ req.body = opts[:body] if opts[:body]
102
+
103
+ response = nil
104
+ begin
105
+ log.debug "CONN:" + conn.inspect
106
+ log.debug "REQ:" + req.inspect
107
+ response = conn.request(req)
108
+
109
+ results = JSON.parse(response.body)
110
+ if ![200, 201].include?(response.code.to_i)
111
+ results = error_code(response.code, opts[:errors], results)
112
+ end
113
+ results = blk.call(results) if blk
114
+ cache.obj_write(opts[:key], results, :ttl => opts[:ttl]) if opts[:key]
115
+ return results
116
+ rescue Exception => exception
117
+ log.error exception.message
118
+ log.error exception.backtrace
119
+ return error_code(response ? response.code : "NO CODE" , opts[:errors])
120
+ end
121
+ data = response.body
122
+ data = blk.call(data) if blk
123
+ cache.obj_write(opts[:key], data, :ttl => opts[:ttl]) if opts[:key]
124
+ return data
125
+ end
126
+
127
+ def connection(connection_flag = :normal)
128
+ @connections ||= {}
129
+ return @connections[connection_flag] if @connections[connection_flag]
130
+ @connections[connection_flag] = create_connection
131
+ end
132
+
133
+ def create_connection(debug = false)
134
+ if @uri.nil? || @uri.port.nil?
135
+ log.info "CONNECTING TO: #{settings[:url]}"
136
+ @uri = URI.parse("#{settings[:url]}/")
137
+ end
138
+ http = Net::HTTP.new(@uri.host, @uri.port)
139
+ if settings[:ssl] == true
140
+ http.use_ssl = true
141
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
142
+ end
143
+ http.set_debug_output $stderr if debug
144
+ http.open_timeout = 7
145
+ http.read_timeout = 15
146
+ http
147
+ end
148
+
149
+ def cache
150
+ @cache ||= UberCache.new(settings[:cache_prefix], settings[:memcache_hosts])
151
+ end
152
+
153
+ private
154
+ def snake_case(camel_cased_word)
155
+ camel_cased_word.to_s.gsub(/::/, '_').
156
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
157
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
158
+ tr("-", "_").
159
+ downcase
160
+ end
161
+
162
+ def error_code(code, errors = nil, response = nil)
163
+ ret_val = {:error => true, :message => (errors && errors[code.to_s] ? errors[code.to_s] : "API error: #{code}" )}
164
+ ret_val[:response] = response if response
165
+ return ret_val
166
+ end
167
+ end
168
+ end
metadata ADDED
@@ -0,0 +1,87 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: api_consumer_json
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Chris Reister
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-10-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: uber_cache
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '0.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.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '3.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '3.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: fakeweb
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '1.3'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '1.3'
55
+ description: Easy to use API consumer - Setup your API connection in a yaml file,
56
+ and use the helper methods to make easy access APIs calls
57
+ email: chris@chrisreister.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - lib/api_consumer.rb
63
+ homepage: https://github.com/chrisftw/api_consumer_json
64
+ licenses:
65
+ - MIT
66
+ metadata: {}
67
+ post_install_message:
68
+ rdoc_options: []
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ required_rubygems_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - '>='
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ requirements: []
82
+ rubyforge_project:
83
+ rubygems_version: 2.4.2
84
+ signing_key:
85
+ specification_version: 4
86
+ summary: Consume all the APIs
87
+ test_files: []