appnexusapi 0.0.5 → 0.0.6

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: dcb81e6d6e3e396e606b8f5f34133564bb1e23d4
4
+ data.tar.gz: c818e90587d6ea29f0732b4e0d26e6b4632c2a73
5
+ SHA512:
6
+ metadata.gz: fbf3d7e3efe189261e35340b03ed7b06f34c5e99f8a11a3c3b1d0de6a93738a034dab5f7cbc867419dc03a027a01e97c2da35dbfbe53c762e7ad47c0ff69a467
7
+ data.tar.gz: 4a09f2255dc0e823f18b4c436ea959959afd087842389f125d5785dec9a18816a5fa5ad7396fb99091db7fd16c7761146cb5f16da58bdc0511fbecfb80d2f7a4
data/README.md CHANGED
@@ -20,13 +20,14 @@ Or install it yourself as:
20
20
 
21
21
  Establish a connection:
22
22
 
23
- connection = AppnexusApi::Connection.new({
24
- # optionally pass a uri for the staging site
25
- # defaults to "http://api.adnxs.com/"
26
- # uri => "http://api.sand-08.adnxs.net",
27
- "username" => 'username',
28
- "password" => 'password'
29
- })
23
+ connection = AppnexusApi::Connection.new(
24
+ 'username' => 'username',
25
+ 'password' => 'password'
26
+
27
+ # Defaults to connecting to https://api.appnexus.com/ but you can optionally pass a uri to
28
+ # connect to another endpoint, e.g. the staging site could be
29
+ # uri: 'http://api.sand-08.adnxs.net'
30
+ )
30
31
 
31
32
  Use a Service:
32
33
 
@@ -47,6 +48,16 @@ Use a Service:
47
48
  creative = creative_service.create(new_creative)
48
49
  creative.update("campaign" => "Testing")
49
50
 
51
+ ## Debugging
52
+
53
+ The APPNEXUS_API_DEBUG environment variable will trigger full printouts of Faraday's debug output to STDERR.
54
+
55
+ ```bash
56
+ cd /my/app
57
+ export APPNEXUS_API_DEBUG=true
58
+ bundle exec rails whatever
59
+ ```
60
+
50
61
  ## Contributing
51
62
 
52
63
  1. Fork it
@@ -15,7 +15,10 @@ Gem::Specification.new do |gem|
15
15
  gem.require_paths = ["lib"]
16
16
  gem.version = AppnexusApi::VERSION
17
17
 
18
- gem.add_dependency 'faraday', '~>0.8.7'
19
- gem.add_dependency "multi_json", "~> 1.7.2"
18
+ gem.add_dependency 'faraday', '~> 0.9'
19
+ gem.add_dependency 'faraday_middleware'
20
+ gem.add_dependency 'multi_json'
21
+ gem.add_dependency 'pester'
22
+
20
23
  gem.add_development_dependency 'bundler', '>= 1.2.0'
21
24
  end
@@ -1,4 +1,4 @@
1
- class AppnexusApi::BidderProfileResource < AppnexusApi::Service
1
+ class AppnexusApi::BidderProfileService < AppnexusApi::Service
2
2
 
3
3
  def initialize(connection, bidder_id)
4
4
  @bidder_id = bidder_id
@@ -14,7 +14,7 @@ class AppnexusApi::BidderProfileResource < AppnexusApi::Service
14
14
  end
15
15
 
16
16
  def uri_suffix
17
- "bidder-profile/#{@bidder_id}"
17
+ "profile/#{@bidder_id}"
18
18
  end
19
19
 
20
20
  def delete(id)
@@ -1,16 +1,19 @@
1
- require 'appnexusapi/faraday/encode_json'
2
- require 'appnexusapi/faraday/parse_json'
1
+ require 'faraday_middleware'
3
2
  require 'appnexusapi/faraday/raise_http_error'
4
3
 
5
4
  class AppnexusApi::Connection
6
5
  def initialize(config)
7
- config["uri"] = "http://api.adnxs.com/" unless config.has_key?("uri")
8
6
  @config = config
9
- @connection = Faraday::Connection.new(:url => config["uri"]) do |builder|
10
- builder.use AppnexusApi::Faraday::Request::JsonEncode
11
- builder.use AppnexusApi::Faraday::Response::RaiseHttpError
12
- builder.use AppnexusApi::Faraday::Response::ParseJson
13
- builder.adapter Faraday.default_adapter
7
+ @config['uri'] ||= 'https://api.appnexus.com/'
8
+ @connection = Faraday.new(@config['uri']) do |conn|
9
+ if ENV['APPNEXUS_API_DEBUG'].to_s =~ /^(true|1)$/i
10
+ conn.response :logger, Logger.new(STDERR), bodies: true
11
+ end
12
+
13
+ conn.request :json
14
+ conn.response :json, :content_type => /\bjson$/
15
+ conn.use AppnexusApi::Faraday::Response::RaiseHttpError
16
+ conn.adapter Faraday.default_adapter
14
17
  end
15
18
  end
16
19
 
@@ -19,8 +22,11 @@ class AppnexusApi::Connection
19
22
  end
20
23
 
21
24
  def login
22
- response = @connection.run_request(:post, 'auth', { "auth" => { "username" => @config["username"], "password" => @config["password"] } }, {})
23
- @token = response.body["token"]
25
+ response = @connection.run_request(:post, 'auth', { 'auth' => { 'username' => @config['username'], 'password' => @config['password'] } }, {})
26
+ if response.body['response']['error_code']
27
+ fail "#{response.body['response']['error_code']}/#{response.body['response']['error_description']}"
28
+ end
29
+ @token = response.body['response']['token']
24
30
  end
25
31
 
26
32
  def logout
@@ -29,25 +35,25 @@ class AppnexusApi::Connection
29
35
 
30
36
  def get(route, params={}, headers={})
31
37
  params = params.delete_if {|key, value| value.nil? }
32
- run_request(:get, @connection.build_url(route, params), nil, headers).body
38
+ run_request(:get, @connection.build_url(route, params), nil, headers)
33
39
  end
34
40
 
35
41
  def post(route, body=nil, headers={})
36
- run_request(:post, route, body, headers).body
42
+ run_request(:post, route, body, headers)
37
43
  end
38
44
 
39
45
  def put(route, body=nil, headers={})
40
- run_request(:put, route, body, headers).body
46
+ run_request(:put, route, body, headers)
41
47
  end
42
48
 
43
49
  def delete(route, body=nil, headers={})
44
- run_request(:delete, route, body, headers).body
50
+ run_request(:delete, route, body, headers)
45
51
  end
46
52
 
47
53
  def run_request(method, route, body, headers)
48
54
  login if !is_authorized?
49
55
  begin
50
- @connection.run_request(method, route, body, { "Authorization" => @token }.merge(headers))
56
+ @connection.run_request(method, route, body, { 'Authorization' => @token }.merge(headers))
51
57
  rescue AppnexusApi::Unauthorized => e
52
58
  if @retry == true
53
59
  raise AppnexusApi::Unauthorized, e
@@ -57,7 +63,7 @@ class AppnexusApi::Connection
57
63
  run_request(method, route, body, headers)
58
64
  end
59
65
  rescue Faraday::Error::TimeoutError => e
60
- raise AppnexusApi::Timeout, "Timeout"
66
+ raise AppnexusApi::Timeout, 'Timeout'
61
67
  ensure
62
68
  @retry = false
63
69
  end
@@ -0,0 +1,2 @@
1
+ class AppnexusApi::CreativeTemplateResource < AppnexusApi::Resource
2
+ end
@@ -0,0 +1,18 @@
1
+ class AppnexusApi::CreativeTemplateService < AppnexusApi::Service
2
+ def name
3
+ "template"
4
+ end
5
+
6
+ def resource_class
7
+ AppnexusApi::CreativeTemplateResource
8
+ end
9
+
10
+ def uri_suffix
11
+ "template"
12
+ end
13
+
14
+ def delete(id)
15
+ raise AppnexusApi::NotImplemented
16
+ end
17
+
18
+ end
@@ -0,0 +1,68 @@
1
+ class AppnexusApi::LogLevelDataDownloadService < AppnexusApi::Service
2
+ class BadChecksumException < Exception
3
+ end
4
+
5
+ def initialize(connection, options = {})
6
+ @read_only = true
7
+ @downloaded_files_path = options[:downloaded_files_path] || '.'
8
+ super(connection)
9
+ end
10
+
11
+ def download_location(params = {})
12
+ @connection.get(uri_suffix, params).headers['location']
13
+ end
14
+
15
+ # Parameter is a LogLevelDataResource
16
+ # Downloads a gzipped file
17
+ # Returns an array of paths to downloaded files
18
+ def download_resource(data_resource)
19
+ data_resource.download_params.map do |params|
20
+ uri = URI.parse(download_location(params.reject { |k,v| k == :checksum }))
21
+ filename = File.join(@downloaded_files_path, "#{params[:siphon_name]}_#{params[:hour]}_#{params[:split_part]}.gz")
22
+ Pester.retry_with_exponential_backoff do
23
+ download_file(uri, filename)
24
+ calculated_checksum = Digest::MD5.hexdigest(File.read(filename))
25
+ if calculated_checksum != params[:checksum]
26
+ error_message = "Calculated checksum of #{calculated_checksum} doesn't match API provided checksum #{params[:checksum]}"
27
+ puts error_message
28
+ fail(BadChecksumException, error_message)
29
+ end
30
+ end
31
+
32
+ filename
33
+ end
34
+ end
35
+
36
+ def get
37
+ fail(AppnexusApi::NotImplemented, 'This service is designed to work through download_location method.')
38
+ end
39
+
40
+ def uri_name
41
+ 'siphon-download'
42
+ end
43
+
44
+ private
45
+
46
+ def download_file(uri, filename)
47
+ puts "Starting HTTP download for: #{uri.to_s}..."
48
+ http_object = Net::HTTP.new(uri.host, uri.port)
49
+ http_object.use_ssl = true if uri.scheme == 'https'
50
+ begin
51
+ http_object.start do |http|
52
+ request = Net::HTTP::Get.new(uri.request_uri)
53
+ http.read_timeout = 500
54
+ http.request(request) do |response|
55
+ open(filename, 'wb') do |io|
56
+ response.read_body do |chunk|
57
+ io.write(chunk)
58
+ end
59
+ end
60
+ end
61
+ end
62
+ rescue StandardError => e
63
+ puts "=> Exception: '#{e}'. Skipping download."
64
+ return
65
+ end
66
+ puts "Stored download as #{filename}"
67
+ end
68
+ end
@@ -0,0 +1,20 @@
1
+ class AppnexusApi::LogLevelDataResource < AppnexusApi::Resource
2
+ # Extract an array of hashes of params to pass to the LogLevelDownloadService
3
+ def download_params
4
+ fail 'Missing necessaray information!' unless name && hour && timestamp && splits
5
+ splits.map do |split_part|
6
+ if split_part['checksum'].blank?
7
+ # In the case of regenerated files, there can be no checksum. These replaced hourly files should not be downloaded.
8
+ nil
9
+ else
10
+ {
11
+ split_part: split_part['part'],
12
+ siphon_name: name,
13
+ timestamp: timestamp,
14
+ hour: hour,
15
+ checksum: split_part['checksum']
16
+ }
17
+ end
18
+ end.compact
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ class AppnexusApi::LogLevelDataService < AppnexusApi::Service
2
+ def initialize(connection, options = {})
3
+ @read_only = true
4
+ @siphon_name = options[:siphon_name]
5
+
6
+ super(connection)
7
+ end
8
+
9
+ def since(time = nil)
10
+ params = {}
11
+ params[:siphon_name] = @siphon_name if @siphon_name
12
+ params[:updated_since] = time.strftime('%Y_%m_%d_%H') if time
13
+
14
+ get(params)
15
+ end
16
+
17
+ def uri_name
18
+ 'siphon'
19
+ end
20
+ end
@@ -21,15 +21,15 @@ class AppnexusApi::Service
21
21
  AppnexusApi.const_get(resource_name + "Resource")
22
22
  end
23
23
  end
24
-
24
+
25
25
  def uri_name
26
26
  name.gsub('_', '-')
27
27
  end
28
-
28
+
29
29
  def plural_uri_name
30
30
  uri_name + 's'
31
31
  end
32
-
32
+
33
33
  def uri_suffix
34
34
  uri_name
35
35
  end
@@ -40,7 +40,7 @@ class AppnexusApi::Service
40
40
  "num_elements" => 100,
41
41
  "start_element" => 0
42
42
  }.merge(params)
43
- response = @connection.get(uri_suffix, params)
43
+ response = @connection.get(uri_suffix, params).body['response']
44
44
  if return_response
45
45
  response
46
46
  elsif response.has_key?(plural_name) || response.has_key?(plural_uri_name)
@@ -57,20 +57,28 @@ class AppnexusApi::Service
57
57
  def create(attributes={})
58
58
  raise(AppnexusApi::NotImplemented, "Service is read-only.") if @read_only
59
59
  attributes = { name => attributes }
60
- response = @connection.post(uri_suffix, attributes)
60
+ response = @connection.post(uri_suffix, attributes).body['response']
61
+ if response['error_id']
62
+ response.delete('dbg')
63
+ raise AppnexusApi::BadRequest.new(response.inspect)
64
+ end
61
65
  get("id" => response["id"]).first
62
66
  end
63
67
 
64
68
  def update(id, attributes={})
65
69
  raise(AppnexusApi::NotImplemented, "Service is read-only.") if @read_only
66
70
  attributes = { name => attributes }
67
- response = @connection.put([uri_suffix, id].join('/'), attributes)
71
+ response = @connection.put([uri_suffix, id].join('/'), attributes).body['response']
72
+ if response['error_id']
73
+ response.delete('dbg')
74
+ raise AppnexusApi::BadRequest.new(response.inspect)
75
+ end
68
76
  get("id" => response["id"]).first
69
77
  end
70
78
 
71
79
  def delete(id)
72
80
  raise(AppnexusApi::NotImplemented, "Service is read-only.") if @read_only
73
- @connection.delete([uri_suffix, id].join('/'))
81
+ @connection.delete([uri_suffix, id].join('/')).body['response']
74
82
  end
75
83
 
76
84
  end
@@ -1,3 +1,3 @@
1
1
  module AppnexusApi
2
- VERSION = "0.0.5"
2
+ VERSION = "0.0.6"
3
3
  end
metadata CHANGED
@@ -1,49 +1,85 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: appnexusapi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
5
- prerelease:
4
+ version: 0.0.6
6
5
  platform: ruby
7
6
  authors:
8
7
  - Brandon Aaron
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-04-10 00:00:00.000000000Z
11
+ date: 2016-06-16 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: faraday
16
- requirement: &2168053620 !ruby/object:Gem::Requirement
17
- none: false
15
+ requirement: !ruby/object:Gem::Requirement
18
16
  requirements:
19
- - - ~>
17
+ - - "~>"
20
18
  - !ruby/object:Gem::Version
21
- version: 0.8.7
19
+ version: '0.9'
22
20
  type: :runtime
23
21
  prerelease: false
24
- version_requirements: *2168053620
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.9'
27
+ - !ruby/object:Gem::Dependency
28
+ name: faraday_middleware
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'
25
41
  - !ruby/object:Gem::Dependency
26
42
  name: multi_json
27
- requirement: &2168052460 !ruby/object:Gem::Requirement
28
- none: false
43
+ requirement: !ruby/object:Gem::Requirement
29
44
  requirements:
30
- - - ~>
45
+ - - ">="
31
46
  - !ruby/object:Gem::Version
32
- version: 1.7.2
47
+ version: '0'
33
48
  type: :runtime
34
49
  prerelease: false
35
- version_requirements: *2168052460
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: pester
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
36
69
  - !ruby/object:Gem::Dependency
37
70
  name: bundler
38
- requirement: &2168051640 !ruby/object:Gem::Requirement
39
- none: false
71
+ requirement: !ruby/object:Gem::Requirement
40
72
  requirements:
41
- - - ! '>='
73
+ - - ">="
42
74
  - !ruby/object:Gem::Version
43
75
  version: 1.2.0
44
76
  type: :development
45
77
  prerelease: false
46
- version_requirements: *2168051640
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: 1.2.0
47
83
  description: ''
48
84
  email:
49
85
  - brandon.aaron@gmail.com
@@ -51,7 +87,7 @@ executables: []
51
87
  extensions: []
52
88
  extra_rdoc_files: []
53
89
  files:
54
- - .gitignore
90
+ - ".gitignore"
55
91
  - Gemfile
56
92
  - LICENSE
57
93
  - README.md
@@ -77,11 +113,11 @@ files:
77
113
  - lib/appnexusapi/content_category_service.rb
78
114
  - lib/appnexusapi/creative_resource.rb
79
115
  - lib/appnexusapi/creative_service.rb
116
+ - lib/appnexusapi/creative_template_resource.rb
117
+ - lib/appnexusapi/creative_template_service.rb
80
118
  - lib/appnexusapi/domain_list_resource.rb
81
119
  - lib/appnexusapi/domain_list_service.rb
82
120
  - lib/appnexusapi/error.rb
83
- - lib/appnexusapi/faraday/encode_json.rb
84
- - lib/appnexusapi/faraday/parse_json.rb
85
121
  - lib/appnexusapi/faraday/raise_http_error.rb
86
122
  - lib/appnexusapi/inventory_attribute_resource.rb
87
123
  - lib/appnexusapi/inventory_attribute_service.rb
@@ -91,6 +127,9 @@ files:
91
127
  - lib/appnexusapi/language_service.rb
92
128
  - lib/appnexusapi/line_item_resource.rb
93
129
  - lib/appnexusapi/line_item_service.rb
130
+ - lib/appnexusapi/log_level_data_download_service.rb
131
+ - lib/appnexusapi/log_level_data_resource.rb
132
+ - lib/appnexusapi/log_level_data_service.rb
94
133
  - lib/appnexusapi/member_resource.rb
95
134
  - lib/appnexusapi/member_service.rb
96
135
  - lib/appnexusapi/operating_system_service.rb
@@ -109,27 +148,26 @@ files:
109
148
  - lib/appnexusapi/version.rb
110
149
  homepage: http://simpli.fi
111
150
  licenses: []
151
+ metadata: {}
112
152
  post_install_message:
113
153
  rdoc_options: []
114
154
  require_paths:
115
155
  - lib
116
156
  required_ruby_version: !ruby/object:Gem::Requirement
117
- none: false
118
157
  requirements:
119
- - - ! '>='
158
+ - - ">="
120
159
  - !ruby/object:Gem::Version
121
160
  version: '0'
122
161
  required_rubygems_version: !ruby/object:Gem::Requirement
123
- none: false
124
162
  requirements:
125
- - - ! '>='
163
+ - - ">="
126
164
  - !ruby/object:Gem::Version
127
165
  version: '0'
128
166
  requirements: []
129
167
  rubyforge_project:
130
- rubygems_version: 1.8.10
168
+ rubygems_version: 2.2.3
131
169
  signing_key:
132
- specification_version: 3
170
+ specification_version: 4
133
171
  summary: Unofficial Ruby API Wrapper for Appnexus
134
172
  test_files: []
135
173
  has_rdoc:
@@ -1,15 +0,0 @@
1
- module AppnexusApi
2
- module Faraday
3
- module Request
4
- class JsonEncode < ::Faraday::Middleware
5
- def call(env)
6
- if env[:request_headers]["Content-Type"] == nil
7
- env[:body] = MultiJson.encode(env[:body]) if env[:body] != nil
8
- env[:request_headers]["Content-Type"] = "application/json"
9
- end
10
- @app.call(env)
11
- end
12
- end
13
- end
14
- end
15
- end
@@ -1,61 +0,0 @@
1
- module AppnexusApi
2
- module Faraday
3
- module Response
4
- class ParseJson < ::Faraday::Middleware
5
- dependency 'multi_json'
6
-
7
- def call(env)
8
- @app.call(env).on_complete do
9
- if env[:response_headers]["content-type"].include?("application/json")
10
- env[:body] = convert_to_json(env[:body])["response"]
11
- check_for_error(env)
12
- end
13
- end
14
- end
15
-
16
- protected
17
-
18
- def convert_to_json(body)
19
- case body.strip
20
- when ''
21
- nil
22
- when 'true'
23
- true
24
- when 'false'
25
- false
26
- else
27
- begin
28
- ::MultiJson.decode(body)
29
- rescue Exception => exception
30
- raise AppnexusApi::InvalidJson
31
- end
32
- end
33
- end
34
-
35
- def check_for_error(env)
36
- if env[:body].has_key?("error")
37
- case env[:body]["error_id"]
38
- when "NOAUTH"
39
- raise AppnexusApi::Unauthorized, error_message(env)
40
- when "UNAUTH"
41
- raise AppnexusApi::Forbidden, error_message(env)
42
- when "SYNTAX"
43
- raise AppnexusApi::UnprocessableEntity, error_message(env)
44
- when "SYSTEM"
45
- raise AppnexusApi::InternalServerError, error_message(env)
46
- when "INTEGRITY"
47
- raise AppnexusApi::UnprocessableEntity, error_message(env)
48
- else
49
- raise AppnexusApi::Error, error_message(env)
50
- end
51
- end
52
- end
53
-
54
- def error_message(env)
55
- "#{env[:method].to_s.upcase} #{env[:url].to_s} (#{env[:body]["error_id"]}): #{env[:body]["error"]}"
56
- end
57
-
58
- end
59
- end
60
- end
61
- end