paapi 0.1.8 → 0.1.11

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 40f433f95c408becd287ae9cfa62596852bdf95f7819321c3c14bea9e9b45e52
4
- data.tar.gz: 21fab0c1b0502c992f72f4cc5844396d96757cb6fa807fd7ac0f6c80c2c97835
3
+ metadata.gz: 11e336d12ee1e47e2a5e0721d03e36b8a0ef93c85cafa1f614cac918afc9562b
4
+ data.tar.gz: 45b7564fcdf20b532538adeb6dfe1187ffc084ee1cb3788da4c61cf36bc81d05
5
5
  SHA512:
6
- metadata.gz: e43c529bfa5bf168d605af7f2b32bd5d6910acbb41047cddfeabe7c2566f3b43a9e99ea2ca3b8046d9f7ec1e06ae0e889c2a4dc4dfb840eee20c5cbf4c1dc43a
7
- data.tar.gz: 98f0ee7c98a77d301d82128c101e5108d57c20d3d096ebc8ea095f9c478289a0fcc676eb9646c4672238ba71d546d389aa07dd9279e03415bd0ada2fdae7c9b3
6
+ metadata.gz: 793a70fd48443cc4a459aa2ec81507e7430810a1eb49a2446741dfb02135780bb7868c38a2adf87f1f4e4c99783669c55370eb6495a03657e332cf1d20ce812d
7
+ data.tar.gz: ca199ef19cadde87923b8bc8708ab8887bf91c0b61e63faf522b8ecdc91eea4ef25215a296ba9fe00dc6ccd9221c9dc8d20551fb87eea4c9d5cb282996cbbdf7
data/CHANGELOG.md CHANGED
@@ -1,4 +1,8 @@
1
- ## 0.1.7 ( Unreleased )
1
+ ## 0.1.9 (Unreleased)
2
+ - Fix bug allowing non-title case Request Parameters
3
+ - Add the required PartnerTag and PartnerType key values to the search body request
4
+
5
+ ## 0.1.7
2
6
  - Add gem 'net-http-persistent' for connection persistance
3
7
  - Remove the code which would use other http clients if available
4
8
  ## 0.1.3
data/lib/paapi/client.rb CHANGED
@@ -1,89 +1,94 @@
1
- require 'net/http/persistent'
2
- require 'aws-sigv4'
1
+ require "net/http/persistent"
2
+ require "aws-sigv4"
3
3
 
4
4
  module Paapi
5
5
  class Client
6
-
7
6
  attr_accessor :partner_tag, :marketplace, :resources, :condition
8
7
  attr_reader :partner_type, :access_key, :secret_key, :market, :http
9
8
 
10
- def initialize(access_key: Paapi.access_key,
11
- secret_key: Paapi.secret_key,
12
- partner_tag: Paapi.partner_tag,
13
- market: Paapi.market || DEFAULT_MARKET,
14
- condition: Paapi.condition || DEFAULT_CONDITION,
15
- resources: Paapi.resources || DEFAULT_RESOURCES,
16
- partner_type: DEFAULT_PARTNER_TYPE
17
- )
18
- raise ArgumentError unless MARKETPLACES.keys.include?(market.to_sym)
9
+ def initialize(
10
+ access_key: Paapi.access_key,
11
+ secret_key: Paapi.secret_key,
12
+ partner_tag: Paapi.partner_tag,
13
+ market: Paapi.market || DEFAULT_MARKET,
14
+ condition: Paapi.condition || DEFAULT_CONDITION,
15
+ resources: Paapi.resources || DEFAULT_RESOURCES,
16
+ partner_type: DEFAULT_PARTNER_TYPE
17
+ )
18
+ raise ArgumentError unless MARKETPLACES.key?(market.to_sym)
19
19
 
20
20
  @access_key = access_key
21
21
  @secret_key = secret_key
22
22
  @partner_type = partner_type
23
23
  @resources = resources unless resources.nil?
24
- @condition = condition
24
+ @condition = condition
25
25
  self.market = market
26
26
  @partner_tag = partner_tag if !partner_tag.nil?
27
27
 
28
- @http = Net::HTTP::Persistent.new name: 'paapi'
28
+ @http = Net::HTTP::Persistent.new(name: "paapi").tap do |c|
29
+ c.open_timeout = 2
30
+ c.read_timeout = 5
31
+ c.write_timeout = 5
32
+ end
29
33
  end
30
34
 
31
35
  def market=(a_market)
32
36
  @market = a_market
33
37
  @marketplace = MARKETPLACES[market.to_sym]
34
- if !Paapi.partner_market.nil?
35
- @partner_tag = Paapi.partner_market.dig(a_market.to_sym) || @partner_tag
36
- end
38
+ return if Paapi.partner_market.nil?
39
+
40
+ @partner_tag = Paapi.partner_market[a_market.to_sym] || @partner_tag
37
41
  end
38
42
 
39
43
  def get_items(item_ids:, **options)
40
- payload = { ItemIds: Array(item_ids), Resources: @resources }.merge(options)
44
+ payload = {"PartnerTag" => partner_tag, "PartnerType" => "Associates", ItemIds: Array(item_ids), Resources: @resources}.merge(options)
41
45
  request(op: :get_items, payload: payload)
42
46
  end
43
47
 
44
- def get_variations(asin:, **options )
45
- payload = { ASIN: asin, Resources: @resources }.merge(options)
48
+ def get_variations(asin:, **options)
49
+ payload = {ASIN: asin, Resources: @resources}.merge(options)
46
50
  request(op: :get_variations, payload: payload)
47
51
  end
48
52
 
49
53
  # TODO: Currently we assume Keywords, but we need one of the following: [Keywords Actor Artist Author Brand Title ]
50
- def search_items(keywords: nil, **options )
51
- raise ArgumentError("Missing keywords") unless (options.keys | SEARCH_PARAMS).length.positive?
54
+ def search_items(**options)
55
+ options.transform_keys!(&:to_s)
56
+ raise ArgumentError.new("Missing keywords") unless (options.keys & SEARCH_PARAMS).length.positive?
52
57
 
53
- search_index = options.dig(:SearchIndex) ||'All'
58
+ search_index = options.dig(:SearchIndex) || "All"
54
59
 
55
- payload = { Keywords: keywords, Resources: @resources, ItemCount: 10, ItemPage: 1, SearchIndex: search_index }.merge(options)
60
+ payload = {"PartnerTag" => partner_tag, "PartnerType" => "Associates", "Resources" => @resources, "ItemCount" => 10, "ItemPage" => 1, "SearchIndex" => search_index}.merge(options)
56
61
 
57
62
  request(op: :search_items, payload: payload)
58
63
  end
59
64
 
60
65
  def get_browse_nodes(browse_node_ids:, **options)
61
- payload = { BrowseNodeIds: Array(browse_node_ids), Resources: @resources }.merge(options)
66
+ payload = {BrowseNodeIds: Array(browse_node_ids), Resources: @resources}.merge(options)
62
67
  request(op: :get_browse_nodes, payload: payload)
63
68
  end
64
-
69
+
65
70
  private
66
-
67
- def request(op:, payload:)
68
- raise ArguemntError unless Paapi::OPERATIONS.keys.include?(op)
69
-
71
+
72
+ def request(op:, payload:)
73
+ raise ArguemntError unless Paapi::OPERATIONS.key?(op)
74
+
70
75
  operation = OPERATIONS[op]
71
76
 
72
77
  headers = {
73
- 'X-Amz-Target' => "com.amazon.paapi5.v1.ProductAdvertisingAPIv1.#{operation.target_name}",
74
- 'Content-Encoding' => 'amz-1.0',
78
+ "X-Amz-Target" => "com.amazon.paapi5.v1.ProductAdvertisingAPIv1.#{operation.target_name}",
79
+ "Content-Encoding" => "amz-1.0"
75
80
  }
76
81
 
77
82
  default_payload = {
78
- 'Condition' => condition,
79
- 'PartnerTag' => partner_tag,
80
- 'PartnerType' => partner_type,
81
- 'Marketplace' => marketplace.site
83
+ "Condition" => condition,
84
+ "PartnerTag" => partner_tag,
85
+ "PartnerType" => partner_type,
86
+ "Marketplace" => marketplace.site
82
87
  }
83
88
 
84
89
  payload = default_payload.merge(payload)
85
-
86
- endpoint = "https://#{marketplace.host}/paapi5/#{operation.endpoint_suffix}"
90
+ puts payload
91
+ endpoint = "https://#{marketplace.host}/paapi5/#{operation.endpoint_suffix}"
87
92
 
88
93
  signer = Aws::Sigv4::Signer.new(
89
94
  service: operation.service,
@@ -96,21 +101,21 @@ module Paapi
96
101
 
97
102
  signature = signer.sign_request(http_method: operation.http_method, url: endpoint, headers: headers, body: payload.to_json)
98
103
 
99
- headers['Host'] = marketplace.host
100
- headers['X-Amz-Date'] = signature.headers['x-amz-date']
101
- headers['X-Amz-Content-Sha256']= signature.headers['x-amz-content-sha256']
102
- headers['Authorization'] = signature.headers['authorization']
103
- headers['Content-Type'] = 'application/json; charset=utf-8'
104
+ headers["Host"] = marketplace.host
105
+ headers["X-Amz-Date"] = signature.headers["x-amz-date"]
106
+ headers["X-Amz-Content-Sha256"] = signature.headers["x-amz-content-sha256"]
107
+ headers["Authorization"] = signature.headers["authorization"]
108
+ headers["Content-Type"] = "application/json; charset=utf-8"
104
109
 
105
- Response.new( post(url: endpoint, body: payload, headers: headers))
110
+ Response.new(post(url: endpoint, body: payload, headers: headers))
106
111
  end
107
112
 
108
113
  def post(url:, body:, headers:)
109
114
  uri = URI.parse(url)
110
115
 
111
116
  post_request = Net::HTTP::Post.new(uri.path)
112
- post_request.content_type = 'application/json; charset=UTF-8'
113
-
117
+ post_request.content_type = "application/json; charset=UTF-8"
118
+
114
119
  headers.each { |k, v| post_request[k] = v }
115
120
  post_request.body = body.to_json
116
121
 
data/lib/paapi/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Paapi
2
- VERSION = '0.1.8'
2
+ VERSION = '0.1.11'
3
3
  end
data/lib/paapi.rb CHANGED
@@ -1,81 +1,82 @@
1
- require 'paapi/version'
1
+ require "paapi/version"
2
2
 
3
- require 'paapi/client'
4
- require 'paapi/item'
5
- require 'paapi/listing'
6
- require 'paapi/response'
3
+ require "paapi/client"
4
+ require "paapi/item"
5
+ require "paapi/listing"
6
+ require "paapi/response"
7
7
 
8
8
  module Paapi
9
9
  class Error < StandardError; end
10
+
10
11
  class NotImplemented < StandardError; end
11
- SEARCH_PARAMS = %i[keywords actor, artist, author, brand title].freeze
12
- DEFAULT_PARTNER_TYPE = 'Associates'
12
+ SEARCH_PARAMS = %w[Keywords Actor Artist Author Brand Title].freeze
13
+ DEFAULT_PARTNER_TYPE = "Associates"
13
14
  DEFAULT_MARKET = :us
14
- DEFAULT_CONDITION = 'Any'
15
+ DEFAULT_CONDITION = "Any"
15
16
  DEFAULT_RESOURCES = [
16
- 'Images.Primary.Large',
17
- 'ItemInfo.ByLineInfo',
18
- 'ItemInfo.ContentInfo',
19
- 'ItemInfo.ExternalIds',
20
- 'ItemInfo.Features',
21
- 'ItemInfo.ManufactureInfo',
22
- 'ItemInfo.ProductInfo',
23
- 'ItemInfo.TechnicalInfo', # Includes format when Kindle
24
- 'ItemInfo.Title',
25
- 'ItemInfo.TradeInInfo',
26
- 'Offers.Listings.Availability.Message',
27
- 'Offers.Listings.Condition',
28
- 'Offers.Listings.Condition.SubCondition',
29
- 'Offers.Listings.DeliveryInfo.IsAmazonFulfilled',
30
- 'Offers.Listings.DeliveryInfo.IsFreeShippingEligible',
31
- 'Offers.Listings.DeliveryInfo.IsPrimeEligible',
32
- 'Offers.Listings.MerchantInfo',
33
- 'Offers.Listings.Price',
34
- 'Offers.Listings.SavingBasis'
17
+ "Images.Primary.Large",
18
+ "ItemInfo.ByLineInfo",
19
+ "ItemInfo.ContentInfo",
20
+ "ItemInfo.ExternalIds",
21
+ "ItemInfo.Features",
22
+ "ItemInfo.ManufactureInfo",
23
+ "ItemInfo.ProductInfo",
24
+ "ItemInfo.TechnicalInfo", # Includes format when Kindle
25
+ "ItemInfo.Title",
26
+ "ItemInfo.TradeInInfo",
27
+ "Offers.Listings.Availability.Message",
28
+ "Offers.Listings.Condition",
29
+ "Offers.Listings.Condition.SubCondition",
30
+ "Offers.Listings.DeliveryInfo.IsAmazonFulfilled",
31
+ "Offers.Listings.DeliveryInfo.IsFreeShippingEligible",
32
+ "Offers.Listings.DeliveryInfo.IsPrimeEligible",
33
+ "Offers.Listings.MerchantInfo",
34
+ "Offers.Listings.Price",
35
+ "Offers.Listings.SavingBasis"
35
36
  ].freeze
36
37
 
37
38
  Locale = Struct.new(:key, :name, :host, :region) do
38
39
  def site
39
- host.sub('webservices', 'www')
40
+ host.sub("webservices", "www")
40
41
  end
41
42
  end
42
43
 
43
44
  MARKETPLACES = {
44
- au: Locale.new(:au, 'Australia', 'webservices.amazon.com.au', 'us-west-2'),
45
- br: Locale.new(:br, 'Brazil', 'webservices.amazon.com.br', 'us-east-1'),
46
- ca: Locale.new(:ca, 'Canada', 'webservices.amazon.ca', 'us-east-1'),
47
- fr: Locale.new(:fr, 'France', 'webservices.amazon.fr', 'eu-west-1'),
48
- de: Locale.new(:de, 'Germany', 'webservices.amazon.de', 'eu-west-1'),
49
- in: Locale.new(:in, 'India', 'webservices.amazon.in', 'eu-west-1'),
50
- it: Locale.new(:it, 'Italy', 'webservices.amazon.it', 'eu-west-1'),
51
- jp: Locale.new(:jp, 'Japan', 'webservices.amazon.co.jp', 'us-west-2'),
52
- mx: Locale.new(:mx, 'Mexico', 'webservices.amazon.com.mx', 'us-east-1'),
53
- es: Locale.new(:es, 'Spain', 'webservices.amazon.es', 'eu-west-1'),
54
- tr: Locale.new(:tk, 'Turkey', 'webservices.amazon.com.tr', 'eu-west-1'),
55
- ae: Locale.new(:ae, 'United Arab Emirates', 'webservices.amazon.ae', 'eu-west-1'),
56
- uk: Locale.new(:uk, 'United Kingdom', 'webservices.amazon.co.uk', 'eu-west-1'),
57
- us: Locale.new(:us, 'United States', 'webservices.amazon.com', 'us-east-1'),
45
+ au: Locale.new(:au, "Australia", "webservices.amazon.com.au", "us-west-2"),
46
+ br: Locale.new(:br, "Brazil", "webservices.amazon.com.br", "us-east-1"),
47
+ ca: Locale.new(:ca, "Canada", "webservices.amazon.ca", "us-east-1"),
48
+ fr: Locale.new(:fr, "France", "webservices.amazon.fr", "eu-west-1"),
49
+ de: Locale.new(:de, "Germany", "webservices.amazon.de", "eu-west-1"),
50
+ in: Locale.new(:in, "India", "webservices.amazon.in", "eu-west-1"),
51
+ it: Locale.new(:it, "Italy", "webservices.amazon.it", "eu-west-1"),
52
+ jp: Locale.new(:jp, "Japan", "webservices.amazon.co.jp", "us-west-2"),
53
+ mx: Locale.new(:mx, "Mexico", "webservices.amazon.com.mx", "us-east-1"),
54
+ es: Locale.new(:es, "Spain", "webservices.amazon.es", "eu-west-1"),
55
+ tr: Locale.new(:tk, "Turkey", "webservices.amazon.com.tr", "eu-west-1"),
56
+ ae: Locale.new(:ae, "United Arab Emirates", "webservices.amazon.ae", "eu-west-1"),
57
+ uk: Locale.new(:uk, "United Kingdom", "webservices.amazon.co.uk", "eu-west-1"),
58
+ us: Locale.new(:us, "United States", "webservices.amazon.com", "us-east-1")
58
59
  }.freeze
59
60
 
60
- Operation = Struct.new(:target_name, :endpoint_suffix, :http_method, :service )
61
+ Operation = Struct.new(:target_name, :endpoint_suffix, :http_method, :service)
61
62
 
62
63
  OPERATIONS = {
63
- get_browse_nodes: Operation.new( 'GetBrowseNodes', 'getbrowsenodes', 'POST', 'ProductAdvertisingAPI' ),
64
- get_items: Operation.new( 'GetItems', 'getitems', 'POST', 'ProductAdvertisingAPI' ),
65
- get_variations: Operation.new( 'GetVariations', 'getvariations', 'POST', 'ProductAdvertisingAPI' ),
66
- search_items: Operation.new( 'SearchItems', 'searchitems', 'POST', 'ProductAdvertisingAPI' )
64
+ get_browse_nodes: Operation.new("GetBrowseNodes", "getbrowsenodes", "POST", "ProductAdvertisingAPI"),
65
+ get_items: Operation.new("GetItems", "getitems", "POST", "ProductAdvertisingAPI"),
66
+ get_variations: Operation.new("GetVariations", "getvariations", "POST", "ProductAdvertisingAPI"),
67
+ search_items: Operation.new("SearchItems", "searchitems", "POST", "ProductAdvertisingAPI")
67
68
  }.freeze
68
69
 
69
70
  class << self
70
71
  attr_accessor :access_key,
71
- :secret_key,
72
- :partner_tag,
73
- :partner_type,
74
- :market,
75
- :partner_market,
76
- :condition,
77
- :resources,
78
- :test_mode
72
+ :secret_key,
73
+ :partner_tag,
74
+ :partner_type,
75
+ :market,
76
+ :partner_market,
77
+ :condition,
78
+ :resources,
79
+ :test_mode
79
80
 
80
81
  def configure
81
82
  yield self
@@ -85,7 +86,6 @@ module Paapi
85
86
  end
86
87
 
87
88
  def symbolize_keys(hash)
88
- Hash[hash.map{|k,v| v.is_a?(Hash) ? [k.to_sym, symbolize_keys(v)] : [k.to_sym, v] }]
89
+ hash.map { |k, v| v.is_a?(Hash) ? [k.to_sym, symbolize_keys(v)] : [k.to_sym, v] }.to_h
89
90
  end
90
91
  end
91
-
data/paapi.gemspec CHANGED
@@ -29,6 +29,7 @@ Gem::Specification.new do |spec|
29
29
  spec.add_development_dependency 'rake', '>= 12.3.r3'
30
30
  spec.add_development_dependency 'minitest', '~> 5.0'
31
31
  spec.add_development_dependency 'byebug', '~> 11'
32
+ spec.add_development_dependency 'standard'
32
33
 
33
34
  spec.add_dependency 'aws-sigv4', '~> 1'
34
35
  spec.add_dependency 'net-http-persistent', '~> 4.0', '>= 4.0.1'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: paapi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.8
4
+ version: 0.1.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dan Milne
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-04-20 00:00:00.000000000 Z
11
+ date: 2024-08-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '11'
69
+ - !ruby/object:Gem::Dependency
70
+ name: standard
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'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: aws-sigv4
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -145,7 +159,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
145
159
  - !ruby/object:Gem::Version
146
160
  version: '0'
147
161
  requirements: []
148
- rubygems_version: 3.4.12
162
+ rubygems_version: 3.5.17
149
163
  signing_key:
150
164
  specification_version: 4
151
165
  summary: Client library for Amazon's Product Advertising API v5