peddler 0.9.2 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +35 -29
- data/lib/peddler/client.rb +32 -36
- data/lib/peddler/marketplace.rb +55 -0
- data/lib/peddler/version.rb +1 -1
- data/test/unit/peddler/test_client.rb +16 -8
- data/test/unit/peddler/test_marketplace.rb +23 -0
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 07a989e34449ab73ff6adc3cd7299ac218394f9e
|
4
|
+
data.tar.gz: cc04a47b2d89407875b67728a0067b84fa8e1e72
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 631af106e16507f94106ac30855787fc8b4dba465859863ee7fe5d057aef1ba8273aaefe8c34e985884d4ad14ce1332fad7730a19166e763072b7941a15f9cbd
|
7
|
+
data.tar.gz: b6db581788899e2da6f3aa24f16d9aa7a085eefc09d90ea38cbddb852f3aa8475bbd85104ac1d682d311a77a6a266ebdd7037e35c5307c130573e94b6db98b83
|
data/README.md
CHANGED
@@ -11,40 +11,46 @@ To use Amazon MWS, you must have an eligible seller account.
|
|
11
11
|
|
12
12
|
![Peddler](http://f.cl.ly/items/231z2m0r1Q2o2q1n0w1N/peddler.jpg)
|
13
13
|
|
14
|
-
## Scope
|
15
|
-
|
16
|
-
**Peddler** maps one on one to the MWS APIs and their various operations. It treats required request parameters as ordinary arguments and optional ones as keyword arguments. It parses XML responses with [**MultiXml**](https://github.com/sferik/multi_xml), which helps cast the result nodes into Ruby Hashes. Tab-delimited files are handled with Standard Library's [**CSV**](https://github.com/ruby/ruby/blob/trunk/lib/csv.rb).
|
17
|
-
|
18
|
-
Further abstraction is not in the scope of this project. See [**MWS Orders**](https://github.com/hakanensari/mws-orders) for a richer interface to the same-named API, built on **Peddler**.
|
19
|
-
|
20
14
|
## Quick Start
|
21
15
|
|
22
16
|
```ruby
|
23
17
|
require 'peddler'
|
24
18
|
|
25
19
|
client = MWS.orders
|
26
|
-
parser = client.
|
20
|
+
parser = client.get_service_status
|
27
21
|
parser.parse
|
28
22
|
```
|
29
23
|
|
24
|
+
You can handle HTTP client errors by rescuing API calls individually or defining a global handler on the client level:
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
client.on_error do |request, response|
|
28
|
+
if response.status == 503
|
29
|
+
# handle throttling by backing off and retrying
|
30
|
+
end
|
31
|
+
end
|
32
|
+
```
|
33
|
+
|
34
|
+
## Credentials
|
35
|
+
|
30
36
|
You can set up credentials when instantiating:
|
31
37
|
|
32
38
|
```ruby
|
33
39
|
client = MWS.orders(
|
34
|
-
marketplace_id: "
|
35
|
-
merchant_id: "
|
36
|
-
aws_access_key_id: "
|
37
|
-
aws_secret_access_key: "
|
40
|
+
marketplace_id: "...",
|
41
|
+
merchant_id: "...",
|
42
|
+
aws_access_key_id: "...",
|
43
|
+
aws_secret_access_key: "..."
|
38
44
|
)
|
39
45
|
```
|
40
46
|
|
41
|
-
Alternatively,
|
47
|
+
Alternatively, use environment variables:
|
42
48
|
|
43
49
|
```sh
|
44
|
-
export MWS_MARKETPLACE_ID
|
45
|
-
export MWS_MERCHANT_ID
|
46
|
-
export AWS_ACCESS_KEY_ID
|
47
|
-
export AWS_SECRET_ACCESS_KEY
|
50
|
+
export MWS_MARKETPLACE_ID=...
|
51
|
+
export MWS_MERCHANT_ID=...
|
52
|
+
export AWS_ACCESS_KEY_ID=...
|
53
|
+
export AWS_SECRET_ACCESS_KEY=...
|
48
54
|
```
|
49
55
|
|
50
56
|
## Usage
|
@@ -53,31 +59,31 @@ export AWS_SECRET_ACCESS_KEY=YOUR_AWS_SECRET_ACCESS_KEY
|
|
53
59
|
|
54
60
|
With the MWS Cart Information API, you can retrieve shopping carts that your Amazon Webstore customers have created. The Cart Information API enables you to programmatically integrate Amazon Webstore cart information with your CRM systems, marketing applications, and other systems that require cart data.
|
55
61
|
|
56
|
-
[Read the API](http://rubydoc.info/
|
62
|
+
[Read the API](http://www.rubydoc.info/gems/peddler/MWS/CartInformation/Client)
|
57
63
|
|
58
64
|
### Customer Information
|
59
65
|
|
60
66
|
With the MWS Customer Information API, you can retrieve information from the customer accounts of your Amazon Webstore customers. This customer information includes customer name, contact information, customer account type, and associated Amazon Webstore marketplaces. The Customer Information API enables you to programmatically integrate Amazon Webstore customer account information with your CRM systems, marketing applications, and other systems that require customer data.
|
61
67
|
|
62
|
-
[Read the API](http://rubydoc.info/
|
68
|
+
[Read the API](http://www.rubydoc.info/gems/peddler/MWS/CustomerInformation/Client)
|
63
69
|
|
64
70
|
### Feeds
|
65
71
|
|
66
72
|
The MWS Feeds API lets you upload inventory and order data to Amazon. You can also use this API to get information about the processing of feeds.
|
67
73
|
|
68
|
-
[Read the API](http://rubydoc.info/
|
74
|
+
[Read the API](http://www.rubydoc.info/gems/peddler/MWS/Feeds/Client)
|
69
75
|
|
70
76
|
### Fulfillment Inbound Shipment
|
71
77
|
|
72
78
|
With the MWS Fulfillment Inbound Shipment API, you can create and update inbound shipments of inventory in the Amazon Fulfillment Network. You can also also request lists of inbound shipments or inbound shipment items based on criteria that you specify.
|
73
79
|
|
74
|
-
[Read the API](http://rubydoc.info/
|
80
|
+
[Read the API](http://www.rubydoc.info/gems/peddler/MWS/FulfillmentInboundShipment/Client)
|
75
81
|
|
76
82
|
### Fulfillment Inventory
|
77
83
|
|
78
84
|
The MWS Fulfillment Inventory API can help you stay up-to-date on the availability of your inventory in the Amazon Fulfillment Network. The Fulfillment Inventory API reports real-time availability information for your Amazon Fulfillment Network inventory regardless of whether you are selling your inventory on Amazon's retail web site or through other retail channels.
|
79
85
|
|
80
|
-
[Read the API](http://rubydoc.info/
|
86
|
+
[Read the API](http://www.rubydoc.info/gems/peddler/MWS/FulfillmentInventory/Client)
|
81
87
|
|
82
88
|
### Fulfillment Outbound Shipment
|
83
89
|
|
@@ -85,7 +91,7 @@ The MWS Fulfillment Outbound Shipment API enables you to fulfill orders placed t
|
|
85
91
|
|
86
92
|
Support for creating and cancelling fulfillment orders has been implemented, but the rest of the API is not supported yet.
|
87
93
|
|
88
|
-
[Read the API](http://rubydoc.info/
|
94
|
+
[Read the API](http://www.rubydoc.info/gems/peddler/MWS/FulfillmentOutboundShipment/Client)
|
89
95
|
|
90
96
|
### Off Amazon Payments
|
91
97
|
|
@@ -97,40 +103,40 @@ You can switch the client to the sandbox environment:
|
|
97
103
|
client = MWS.off_amazon_payments.sandbox
|
98
104
|
```
|
99
105
|
|
100
|
-
[Read the API](http://rubydoc.info/
|
106
|
+
[Read the API](http://www.rubydoc.info/gems/peddler/MWS/OffAmazonPayments/Client)
|
101
107
|
|
102
108
|
### Orders
|
103
109
|
|
104
110
|
With the MWS Orders API, you can list orders created or updated during a time frame you specify or retrieve information about specific orders.
|
105
111
|
|
106
|
-
[Read the API](http://rubydoc.info/
|
112
|
+
[Read the API](http://www.rubydoc.info/gems/peddler/MWS/Orders/Client)
|
107
113
|
|
108
114
|
### Products
|
109
115
|
|
110
116
|
The MWS Products API helps you get information to match your products to existing product listings on Amazon Marketplace websites and to make sourcing and pricing decisions for listing those products on Amazon Marketplace websites.
|
111
117
|
|
112
|
-
[Read the API](http://rubydoc.info/
|
118
|
+
[Read the API](http://www.rubydoc.info/gems/peddler/MWS/Products/Client)
|
113
119
|
|
114
120
|
### Recommendations
|
115
121
|
|
116
122
|
The Recommendations API enables you to programmatically retrieve Amazon Selling Coach recommendations by recommendation category. A recommendation is an actionable, timely, and personalized opportunity to increase your sales and performance.
|
117
123
|
|
118
|
-
[Read the API](http://rubydoc.info/
|
124
|
+
[Read the API](http://www.rubydoc.info/gems/peddler/MWS/Recommendations/Client)
|
119
125
|
|
120
126
|
### Reports
|
121
127
|
|
122
128
|
The Reports API lets you request reports about your inventory and orders.
|
123
129
|
|
124
|
-
[Read the API](http://rubydoc.info/
|
130
|
+
[Read the API](http://www.rubydoc.info/gems/peddler/MWS/Reports/Client)
|
125
131
|
|
126
132
|
### Sellers
|
127
133
|
|
128
134
|
The Sellers API lets sellers retrieve information about their seller account, such as the marketplaces they participate in.
|
129
135
|
|
130
|
-
[Read the API](http://rubydoc.info/
|
136
|
+
[Read the API](http://www.rubydoc.info/gems/peddler/MWS/Sellers/Client)
|
131
137
|
|
132
138
|
### Subscriptions
|
133
139
|
|
134
140
|
The Amazon MWS Subscriptions API section enables you to subscribe to receive notifications that are relevant to your business with Amazon. With the operations in the Subscriptions API section, you can register to receive important information from Amazon without having to poll the Amazon MWS service. Instead, the information is sent directly to you when an event occurs to which you are subscribed.
|
135
141
|
|
136
|
-
[Read the API](http://rubydoc.info/
|
142
|
+
[Read the API](http://www.rubydoc.info/gems/peddler/MWS/Subscriptions/Client)
|
data/lib/peddler/client.rb
CHANGED
@@ -1,33 +1,22 @@
|
|
1
|
+
require 'forwardable'
|
1
2
|
require 'jeff'
|
3
|
+
require 'peddler/marketplace'
|
2
4
|
require 'peddler/operation'
|
3
5
|
require 'peddler/parser'
|
4
6
|
|
5
7
|
module Peddler
|
6
8
|
# @abstract Subclass to implement an MWS API section.
|
7
9
|
class Client
|
10
|
+
extend Forwardable
|
8
11
|
include Jeff
|
9
12
|
|
10
|
-
|
11
|
-
|
12
|
-
HOSTS = {
|
13
|
-
'A2EUQ1WTGCTBG2' => 'mws.amazonservices.ca',
|
14
|
-
'AAHKV2X7AFYLW' => 'mws.amazonservices.com.cn',
|
15
|
-
'A1PA6795UKMFR9' => 'mws-eu.amazonservices.com',
|
16
|
-
'A1RKKUPIHCS9HS' => 'mws-eu.amazonservices.com',
|
17
|
-
'A13V1IB3VIYZZH' => 'mws-eu.amazonservices.com',
|
18
|
-
'A1F83G8C2ARO7P' => 'mws-eu.amazonservices.com',
|
19
|
-
'A21TJRUUN4KGV' => 'mws.amazonservices.in',
|
20
|
-
'APJ6JRA9NG5V4' => 'mws-eu.amazonservices.com',
|
21
|
-
'A1VC38T7YXB528' => 'mws.amazonservices.jp',
|
22
|
-
'ATVPDKIKX0DER' => 'mws.amazonservices.com'
|
23
|
-
}
|
24
|
-
|
25
|
-
attr_accessor :path
|
26
|
-
attr_writer :merchant_id, :marketplace_id
|
13
|
+
attr_writer :merchant_id, :marketplace_id, :path
|
27
14
|
attr_reader :body
|
28
15
|
|
29
16
|
alias_method :configure, :tap
|
30
17
|
|
18
|
+
def_delegators :marketplace, :host, :encoding
|
19
|
+
|
31
20
|
params('SellerId' => -> { merchant_id })
|
32
21
|
|
33
22
|
def self.parser
|
@@ -51,7 +40,7 @@ module Peddler
|
|
51
40
|
end
|
52
41
|
|
53
42
|
def aws_endpoint
|
54
|
-
"https://#{host}#{path
|
43
|
+
"https://#{host}#{path}"
|
55
44
|
end
|
56
45
|
|
57
46
|
def marketplace_id
|
@@ -62,6 +51,10 @@ module Peddler
|
|
62
51
|
@merchant_id ||= ENV['MWS_MERCHANT_ID']
|
63
52
|
end
|
64
53
|
|
54
|
+
def marketplace
|
55
|
+
@marketplace ||= find_marketplace
|
56
|
+
end
|
57
|
+
|
65
58
|
def defaults
|
66
59
|
@defaults ||= { expects: 200 }
|
67
60
|
end
|
@@ -70,11 +63,19 @@ module Peddler
|
|
70
63
|
@headers ||= {}
|
71
64
|
end
|
72
65
|
|
66
|
+
def path
|
67
|
+
@path ||= self.class.path
|
68
|
+
end
|
69
|
+
|
73
70
|
def body=(str)
|
74
71
|
headers['Content-Type'] = content_type(str)
|
75
72
|
@body = str
|
76
73
|
end
|
77
74
|
|
75
|
+
def on_error(&blk)
|
76
|
+
@error_handler = blk
|
77
|
+
end
|
78
|
+
|
78
79
|
def operation(action = nil)
|
79
80
|
action ? @operation = Operation.new(action) : @operation
|
80
81
|
end
|
@@ -85,35 +86,25 @@ module Peddler
|
|
85
86
|
opts.store(:response_block, blk) if block_given?
|
86
87
|
res = post(opts)
|
87
88
|
|
88
|
-
parser.parse(res,
|
89
|
+
parser.parse(res, encoding)
|
90
|
+
rescue Excon::Errors::Error => ex
|
91
|
+
handle_error(ex) or raise
|
89
92
|
end
|
90
93
|
|
91
94
|
private
|
92
95
|
|
96
|
+
def find_marketplace
|
97
|
+
Marketplace.new(marketplace_id)
|
98
|
+
end
|
99
|
+
|
93
100
|
def content_type(str)
|
94
101
|
if str.start_with?('<?xml')
|
95
102
|
'text/xml'
|
96
103
|
else
|
97
|
-
"text/tab-separated-values; charset=#{
|
104
|
+
"text/tab-separated-values; charset=#{encoding}"
|
98
105
|
end
|
99
106
|
end
|
100
107
|
|
101
|
-
def host_encoding
|
102
|
-
if host.end_with?('jp')
|
103
|
-
# Caveat: I've had one instance in the past where Shift_JIS didn't
|
104
|
-
# work but Windows-31J did when parsing a report.
|
105
|
-
'Shift_JIS'
|
106
|
-
elsif host.end_with?('cn')
|
107
|
-
'UTF-16'
|
108
|
-
else
|
109
|
-
'ISO-8859-1'
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
def host
|
114
|
-
HOSTS.fetch(marketplace_id) { raise BadMarketplaceId }
|
115
|
-
end
|
116
|
-
|
117
108
|
def extract_options(args)
|
118
109
|
args.last.is_a?(Hash) ? args.pop : {}
|
119
110
|
end
|
@@ -121,5 +112,10 @@ module Peddler
|
|
121
112
|
def parser
|
122
113
|
self.class.parser
|
123
114
|
end
|
115
|
+
|
116
|
+
def handle_error(ex)
|
117
|
+
return false unless @error_handler
|
118
|
+
@error_handler.call(ex.request, ex.response)
|
119
|
+
end
|
124
120
|
end
|
125
121
|
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Peddler
|
2
|
+
# @api private
|
3
|
+
class Marketplace
|
4
|
+
HOSTS = {
|
5
|
+
'A2EUQ1WTGCTBG2' => 'mws.amazonservices.ca',
|
6
|
+
'AAHKV2X7AFYLW' => 'mws.amazonservices.com.cn',
|
7
|
+
'A1PA6795UKMFR9' => 'mws-eu.amazonservices.com',
|
8
|
+
'A1RKKUPIHCS9HS' => 'mws-eu.amazonservices.com',
|
9
|
+
'A13V1IB3VIYZZH' => 'mws-eu.amazonservices.com',
|
10
|
+
'A1F83G8C2ARO7P' => 'mws-eu.amazonservices.com',
|
11
|
+
'A21TJRUUN4KGV' => 'mws.amazonservices.in',
|
12
|
+
'APJ6JRA9NG5V4' => 'mws-eu.amazonservices.com',
|
13
|
+
'A1VC38T7YXB528' => 'mws.amazonservices.jp',
|
14
|
+
'ATVPDKIKX0DER' => 'mws.amazonservices.com'
|
15
|
+
}
|
16
|
+
|
17
|
+
BadId = Class.new(StandardError)
|
18
|
+
|
19
|
+
attr_reader :id
|
20
|
+
|
21
|
+
def initialize(id)
|
22
|
+
@id = id
|
23
|
+
end
|
24
|
+
|
25
|
+
def host
|
26
|
+
@host ||= find_host
|
27
|
+
end
|
28
|
+
|
29
|
+
def encoding
|
30
|
+
if japanese?
|
31
|
+
# Caveat: I've had one instance in the past where Shift_JIS didn't
|
32
|
+
# work but Windows-31J did when parsing a report.
|
33
|
+
'Shift_JIS'
|
34
|
+
elsif chinese?
|
35
|
+
'UTF-16'
|
36
|
+
else
|
37
|
+
'ISO-8859-1'
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def find_host
|
44
|
+
HOSTS.fetch(id) { raise BadId }
|
45
|
+
end
|
46
|
+
|
47
|
+
def japanese?
|
48
|
+
host.end_with?('jp')
|
49
|
+
end
|
50
|
+
|
51
|
+
def chinese?
|
52
|
+
host.end_with?('cn')
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
data/lib/peddler/version.rb
CHANGED
@@ -64,14 +64,6 @@ class TestPeddlerClient < MiniTest::Test
|
|
64
64
|
assert_equal '123', client.aws_access_key_id
|
65
65
|
end
|
66
66
|
|
67
|
-
def test_guards_against_bad_marketplace_id
|
68
|
-
assert_raises(Peddler::Client::BadMarketplaceId) do
|
69
|
-
client = Peddler::Client.new
|
70
|
-
client.marketplace_id = '123'
|
71
|
-
client.get
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
67
|
def test_sets_content_type_header_for_latin_flat_file_body
|
76
68
|
@client.body = 'foo'
|
77
69
|
content_type = @client.headers.fetch('Content-Type')
|
@@ -133,4 +125,20 @@ class TestPeddlerClient < MiniTest::Test
|
|
133
125
|
|
134
126
|
assert headers.has_key?('User-Agent')
|
135
127
|
end
|
128
|
+
|
129
|
+
def test_error_callback
|
130
|
+
Excon.stub({}, { status: 503 })
|
131
|
+
|
132
|
+
assert_raises(Excon::Errors::ServiceUnavailable) do
|
133
|
+
@client.run
|
134
|
+
end
|
135
|
+
|
136
|
+
@client.on_error do |_, res|
|
137
|
+
assert_equal 503, res.status
|
138
|
+
end
|
139
|
+
|
140
|
+
@client.run
|
141
|
+
|
142
|
+
Excon.stubs.clear
|
143
|
+
end
|
136
144
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'peddler/marketplace'
|
3
|
+
|
4
|
+
class TestPeddlerMarketplace < MiniTest::Test
|
5
|
+
def setup
|
6
|
+
@marketplace = Peddler::Marketplace.new('ATVPDKIKX0DER')
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_has_a_host
|
10
|
+
assert @marketplace.host
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_has_an_encoding
|
14
|
+
assert @marketplace.encoding
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_guards_against_bad_marketplace_ids
|
18
|
+
assert_raises(Peddler::Marketplace::BadId) do
|
19
|
+
marketplace = Peddler::Marketplace.new('123')
|
20
|
+
marketplace.host
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: peddler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Hakan Ensari
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-10-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: jeff
|
@@ -77,6 +77,7 @@ files:
|
|
77
77
|
- lib/peddler.rb
|
78
78
|
- lib/peddler/client.rb
|
79
79
|
- lib/peddler/flat_file_parser.rb
|
80
|
+
- lib/peddler/marketplace.rb
|
80
81
|
- lib/peddler/operation.rb
|
81
82
|
- lib/peddler/parser.rb
|
82
83
|
- lib/peddler/structured_list.rb
|
@@ -104,6 +105,7 @@ files:
|
|
104
105
|
- test/unit/mws/test_products_client.rb
|
105
106
|
- test/unit/peddler/test_client.rb
|
106
107
|
- test/unit/peddler/test_flat_file_parser.rb
|
108
|
+
- test/unit/peddler/test_marketplace.rb
|
107
109
|
- test/unit/peddler/test_operation.rb
|
108
110
|
- test/unit/peddler/test_parser.rb
|
109
111
|
- test/unit/peddler/test_structured_list.rb
|
@@ -142,7 +144,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
142
144
|
version: '0'
|
143
145
|
requirements: []
|
144
146
|
rubyforge_project:
|
145
|
-
rubygems_version: 2.
|
147
|
+
rubygems_version: 2.2.2
|
146
148
|
signing_key:
|
147
149
|
specification_version: 4
|
148
150
|
summary: Wraps the Amazon MWS APIs
|
@@ -169,6 +171,7 @@ test_files:
|
|
169
171
|
- test/unit/mws/test_products_client.rb
|
170
172
|
- test/unit/peddler/test_client.rb
|
171
173
|
- test/unit/peddler/test_flat_file_parser.rb
|
174
|
+
- test/unit/peddler/test_marketplace.rb
|
172
175
|
- test/unit/peddler/test_operation.rb
|
173
176
|
- test/unit/peddler/test_parser.rb
|
174
177
|
- test/unit/peddler/test_structured_list.rb
|