ruby-mws 0.0.3 → 0.0.4
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.
- data/.gitignore +2 -1
- data/README.markdown +32 -29
- data/bin/ruby-mws +3 -0
- data/lib/ruby-mws/api/base.rb +5 -13
- data/lib/ruby-mws/api/order.rb +4 -3
- data/lib/ruby-mws/api/response.rb +20 -1
- data/lib/ruby-mws/exceptions.rb +5 -0
- data/lib/ruby-mws/version.rb +1 -1
- data/spec/ruby-mws/api/inventory_spec.rb +1 -1
- data/spec/ruby-mws/api/order_spec.rb +5 -3
- data/spec/spec_helper.rb +1 -1
- metadata +56 -19
- data/.rvmrc +0 -1
data/.gitignore
CHANGED
data/README.markdown
CHANGED
@@ -1,41 +1,48 @@
|
|
1
1
|
ruby-mws
|
2
2
|
========
|
3
3
|
|
4
|
-
|
5
|
-
-----------------
|
4
|
+
by Erik Lyngved
|
6
5
|
|
7
|
-
|
6
|
+
### Read me!
|
8
7
|
|
9
|
-
|
8
|
+
ruby-mws is a Ruby gem that wraps the Amazon Marketplace Web Service (MWS) API. Right now it only supports Amazon's Order and Inventory APIs.
|
9
|
+
|
10
|
+
I made this gem for my own purposes, and it's not fully featured. Pull requests or bug reports are always welcome.
|
10
11
|
|
11
12
|
Quick Start
|
12
13
|
-----------
|
13
14
|
|
14
|
-
|
15
|
+
To quickly test your connection to the service without credentials, you can ping the server, which returns server time in UTC:
|
16
|
+
|
17
|
+
MWS::Base.server_time
|
18
|
+
|
19
|
+
### Initialization
|
15
20
|
|
16
21
|
Pass in your developer account credentials. All four params below are required.
|
17
22
|
|
18
|
-
mws = MWS.new
|
23
|
+
mws = MWS.new (:aws_access_key_id => "AKIAIFKEXAMPLE4WZHHA",
|
19
24
|
:secret_access_key => "abc123def456/SECRET/+ghi789jkl",
|
20
25
|
:seller_id => "A27WEXAMPLEBXY",
|
21
|
-
:marketplace_id => "ATVPDKIKX0DER"
|
26
|
+
:marketplace_id => "ATVPDKIKX0DER")
|
22
27
|
|
23
|
-
###
|
28
|
+
### Requests
|
24
29
|
|
25
|
-
|
30
|
+
We'll use the Orders API to retrieve recently updated orders.
|
26
31
|
|
27
32
|
# Retrieve all orders updated within the last 4 hours
|
28
|
-
response = mws.orders.list_orders :last_updated_after =>
|
33
|
+
response = mws.orders.list_orders :last_updated_after => 4.hours.ago # ActiveSupport time helper
|
29
34
|
|
30
35
|
(All datetime fields accept Time or DateTime objects, as well as strings in iso8601 format.)
|
31
36
|
|
32
|
-
###
|
37
|
+
### Responses
|
33
38
|
|
34
|
-
|
39
|
+
Response objects inherit [Hashie](http://github.com/intridea/hashie) for easy access and [Rash](http://github.com/tcocca/rash) to convert Amazon's CamelCase convention to underscore. So you're just left with plain ol' Ruby goodness.
|
40
|
+
|
41
|
+
Let's parse our response to view the orders and any other data returned.
|
35
42
|
|
36
43
|
response.orders.first # => { "amazon_order_id" => "002-EXAMPLE-0031387",
|
37
|
-
|
38
|
-
|
44
|
+
# "purchase_date" => "2012-01-13T19:11:46.000Z",
|
45
|
+
# ... }
|
39
46
|
|
40
47
|
Response objects are accessible in Hash or method notation.
|
41
48
|
|
@@ -50,35 +57,31 @@ Use `keys` and `has_key?` to discover what's in the response.
|
|
50
57
|
|
51
58
|
For responses with long lists of data, results are returned from the service in pages (usually 100 per page). Example:
|
52
59
|
|
53
|
-
response = mws.orders.list_orders :last_updated_after =>
|
60
|
+
response = mws.orders.list_orders :last_updated_after => 1.week.ago # returns 100 orders & next_token
|
54
61
|
|
55
62
|
Here, there are more orders to be returned. You can call `has_next?` on the same API instance to see if the last response returned has a next page. If so, calling `next` will make the request for the next page.
|
56
63
|
|
57
64
|
mws.orders.has_next? # => true
|
58
65
|
next_response = mws.orders.next # returns next page of orders
|
59
66
|
|
60
|
-
You can keep calling `next` on the API instance as long as `has_next?` returns true.
|
61
|
-
|
62
|
-
You can always go about the manual way as per Amazon's docs:
|
63
|
-
|
64
|
-
next_response = mws.orders.list_orders_by_next_response :next_token => response.next_token
|
67
|
+
Repeat as necessary. You can keep calling `next` on the API instance as long as `has_next?` returns true.
|
65
68
|
|
66
|
-
|
69
|
+
Or if you need to, you can save the next_token and go about the manual way as per Amazon's docs:
|
67
70
|
|
68
|
-
|
71
|
+
next_response = mws.orders.list_orders_by_next_token :next_token => response.next_token
|
69
72
|
|
70
|
-
|
71
|
-
|
73
|
+
API
|
74
|
+
---
|
72
75
|
|
73
|
-
@mws = MWS.new(authentication_hash) # initialize the connection object
|
76
|
+
@mws = MWS.new(authentication_hash) # initialize the connection object (see above)
|
74
77
|
|
75
78
|
This object can be used to access all API services. Below are examples on how to make the different requests that are available so far. Refer to the [Amazon MWS Reference Docs](https://developer.amazonservices.com/) for available fields for each request.
|
76
79
|
|
77
80
|
### Orders API
|
78
81
|
|
79
|
-
* ListOrders - gets orders by time
|
82
|
+
* ListOrders - gets orders by time range and other parameters
|
80
83
|
|
81
|
-
`@mws.orders.list_orders :last_updated_after => Time.now-4.hours`
|
84
|
+
`@mws.orders.list_orders :last_updated_after => Time.now-4.hours, :order_status => 'Shipped'`
|
82
85
|
|
83
86
|
* GetOrder - gets orders by Amazon order ID
|
84
87
|
|
@@ -86,7 +89,7 @@ This object can be used to access all API services. Below are examples on how to
|
|
86
89
|
|
87
90
|
`:amazon_order_id` can be an array to retrieve multiple orders.
|
88
91
|
|
89
|
-
* ListOrderItems - gets order items for one order ID
|
92
|
+
* ListOrderItems - gets order items for one order ID (only one order at a time here)
|
90
93
|
|
91
94
|
`@mws.orders.list_order_items :amazon_order_id => "002-EXAMPLE-0031387"`
|
92
95
|
|
@@ -94,5 +97,5 @@ This object can be used to access all API services. Below are examples on how to
|
|
94
97
|
|
95
98
|
* ListInventorySupply - returns availability of inventory, only returns items based on list of SKUs or last change date
|
96
99
|
|
97
|
-
`@mws.inventory.list_inventory_supply :seller_skus =>
|
100
|
+
`@mws.inventory.list_inventory_supply :seller_skus => ['PF-5VZN-04XR', 'V4-03EY-LAL1', 'OC-TUKC-031P']`
|
98
101
|
`@mws.inventory.list_inventory_supply :query_start_date_time => Time.now-1.day`
|
data/bin/ruby-mws
ADDED
data/lib/ruby-mws/api/base.rb
CHANGED
@@ -22,9 +22,8 @@ module MWS
|
|
22
22
|
|
23
23
|
def self.def_request(requests, *options)
|
24
24
|
[requests].flatten.each do |name|
|
25
|
-
# class variable = a way to store options splat to pass into pseudomethod
|
26
|
-
self.class_variable_set("@@#{name}_options", options.first)
|
27
25
|
self.class_eval %Q{
|
26
|
+
@@#{name}_options = options.first
|
28
27
|
def #{name}(params={})
|
29
28
|
send_request(:#{name}, params, @@#{name}_options)
|
30
29
|
end
|
@@ -47,18 +46,11 @@ module MWS
|
|
47
46
|
params[:lists][:marketplace_id] = "MarketplaceId.Id"
|
48
47
|
|
49
48
|
query = Query.new params
|
50
|
-
@response = Response.
|
51
|
-
|
52
|
-
|
53
|
-
res = @response.send("#{name}_response").send("#{name}_result")
|
54
|
-
if @next[:token] = res.next_token # modifying, not comparing
|
55
|
-
@next[:action] = params[:next_action] || (name.match(/_by_next_token/) ? name : "#{name}_by_next_token")
|
56
|
-
end
|
57
|
-
params[:mods].each {|mod| mod.call(res) } if params[:mods]
|
58
|
-
res
|
59
|
-
rescue NoMethodError
|
60
|
-
@response
|
49
|
+
@response = Response.parse self.class.send(params[:verb], query.request_uri), name, params
|
50
|
+
if @response.respond_to?(:next_token) and @next[:token] = @response.next_token # modifying, not comparing
|
51
|
+
@next[:action] = name.match(/_by_next_token/) ? name : "#{name}_by_next_token"
|
61
52
|
end
|
53
|
+
@response
|
62
54
|
end
|
63
55
|
|
64
56
|
def has_next?
|
data/lib/ruby-mws/api/order.rb
CHANGED
@@ -2,14 +2,15 @@ module MWS
|
|
2
2
|
module API
|
3
3
|
|
4
4
|
class Order < Base
|
5
|
-
|
6
|
-
|
7
5
|
def_request [:list_orders, :list_orders_by_next_token],
|
8
6
|
:verb => :get,
|
9
7
|
:uri => '/Orders/2011-01-01',
|
10
8
|
:version => '2011-01-01',
|
9
|
+
:lists => {
|
10
|
+
:order_status => "OrderStatus.Status"
|
11
|
+
},
|
11
12
|
:mods => [
|
12
|
-
lambda {|r| r.orders = r.orders.order}
|
13
|
+
lambda {|r| r.orders = r.orders.order if r.orders}
|
13
14
|
]
|
14
15
|
|
15
16
|
def_request [:list_order_items, :list_order_items_by_next_token],
|
@@ -2,7 +2,26 @@ module MWS
|
|
2
2
|
module API
|
3
3
|
|
4
4
|
class Response < Hashie::Rash
|
5
|
-
|
5
|
+
|
6
|
+
def self.parse(hash, name, params)
|
7
|
+
rash = self.new(hash)
|
8
|
+
handle_error_response(rash["error_response"]["error"]) unless rash["error_response"].nil?
|
9
|
+
raise BadResponseError, "received non-matching response type #{rash.keys}" if rash["#{name}_response"].nil?
|
10
|
+
rash = rash["#{name}_response"]
|
11
|
+
|
12
|
+
if rash = rash["#{name}_result"]
|
13
|
+
# only runs mods if correct result is present
|
14
|
+
params[:mods].each {|mod| mod.call(rash) } if params[:mods]
|
15
|
+
rash
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.handle_error_response(error)
|
20
|
+
msg = "#{error.code}: #{error.message}"
|
21
|
+
msg << " -- #{error.detail}" unless error.detail.nil?
|
22
|
+
raise ErrorResponse, msg
|
23
|
+
end
|
24
|
+
|
6
25
|
end
|
7
26
|
|
8
27
|
end
|
data/lib/ruby-mws/exceptions.rb
CHANGED
data/lib/ruby-mws/version.rb
CHANGED
@@ -5,16 +5,16 @@ describe MWS::API::Order do
|
|
5
5
|
before :all do
|
6
6
|
EphemeralResponse.activate
|
7
7
|
@mws = MWS.new(auth_params)
|
8
|
-
@timestamp = "2012-
|
8
|
+
@timestamp = "2012-04-25T21:42:55-04:00"
|
9
9
|
end
|
10
10
|
|
11
11
|
context "requests" do
|
12
12
|
describe "list_orders" do
|
13
|
-
it "should receive a
|
13
|
+
it "should receive a list of orders" do
|
14
14
|
orders = @mws.orders.list_orders :last_updated_after => "2012-01-15T13:07:26-05:00" ,
|
15
15
|
:timestamp => @timestamp
|
16
16
|
orders.orders.should be_an_instance_of Array
|
17
|
-
orders.should
|
17
|
+
orders.orders.first.should have_key :amazon_order_id
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
@@ -23,6 +23,7 @@ describe MWS::API::Order do
|
|
23
23
|
orders = @mws.orders.list_orders_by_next_token :timestamp => @timestamp,
|
24
24
|
:next_token => "zwR7fTkqiKp/YYuZQbKv1QafEPREmauvizt1MIhPYZZl3LSdPSOgN1byEfyVqilNBpcRD1uxgRxTg2dsYWmzKd8ytOVgN7d/KyNtf5fepe2OEd7gVZif6X81/KsTyqd1e64rGQd1TyCS68vI7Bqws+weLxD7b1CVZciW6QBe7o2FizcdzSXGSiKsUkM4/6QGllhc4XvGqg5e0zIeaOVNezxWEXvdeDL7eReo//Hc3LMRF18hF5ZYNntoCB8irbDGcVkxA+q0fZYwE7+t4NjazyEZY027dXAVTSGshRBy6ZTthhfBGj6Dwur8WCwcU8Vc25news0zC1w6gK1h3EdXw7a3u+Q12Uw9ZROnI57RGr4CrtRODNGKSRdGvNrxcHpI2aLZKrJa2MgKRa+KsojCckrDiHqb8mBEJ88g6izJN42dQcLTGQRwBej+BBOOHYP4"
|
25
25
|
orders.orders.should be_an_instance_of Array
|
26
|
+
orders.orders.first.should have_key :amazon_order_id
|
26
27
|
end
|
27
28
|
end
|
28
29
|
|
@@ -40,6 +41,7 @@ describe MWS::API::Order do
|
|
40
41
|
:timestamp => @timestamp
|
41
42
|
orders.orders.should be_an_instance_of Array
|
42
43
|
orders.orders.size.should == 2
|
44
|
+
orders.orders.first.should have_key :amazon_order_id
|
43
45
|
end
|
44
46
|
end
|
45
47
|
|
data/spec/spec_helper.rb
CHANGED
@@ -14,12 +14,12 @@ RSpec.configure do |config|
|
|
14
14
|
@mws_object ||= MWS.new(auth_params)
|
15
15
|
end
|
16
16
|
|
17
|
+
# To test, create spec/credentials.yml or fill in below
|
17
18
|
def auth_params
|
18
19
|
@auth_params ||=
|
19
20
|
begin
|
20
21
|
hsh = YAML.load(File.open(File.join(File.expand_path(File.dirname(__FILE__)), 'credentials.yml'))).symbolize_keys!
|
21
22
|
rescue
|
22
|
-
# some fake auth values
|
23
23
|
{
|
24
24
|
:aws_access_key_id => 'access',
|
25
25
|
:secret_access_key => 'super_secret',
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-mws
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-01-13 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
16
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,15 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
25
30
|
- !ruby/object:Gem::Dependency
|
26
31
|
name: ephemeral_response
|
27
|
-
requirement:
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
28
33
|
none: false
|
29
34
|
requirements:
|
30
35
|
- - ! '>='
|
@@ -32,10 +37,15 @@ dependencies:
|
|
32
37
|
version: '0'
|
33
38
|
type: :development
|
34
39
|
prerelease: false
|
35
|
-
version_requirements:
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
36
46
|
- !ruby/object:Gem::Dependency
|
37
47
|
name: httparty
|
38
|
-
requirement:
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
39
49
|
none: false
|
40
50
|
requirements:
|
41
51
|
- - ! '>='
|
@@ -43,10 +53,15 @@ dependencies:
|
|
43
53
|
version: '0'
|
44
54
|
type: :runtime
|
45
55
|
prerelease: false
|
46
|
-
version_requirements:
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
47
62
|
- !ruby/object:Gem::Dependency
|
48
63
|
name: nokogiri
|
49
|
-
requirement:
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
50
65
|
none: false
|
51
66
|
requirements:
|
52
67
|
- - ! '>='
|
@@ -54,10 +69,15 @@ dependencies:
|
|
54
69
|
version: '0'
|
55
70
|
type: :runtime
|
56
71
|
prerelease: false
|
57
|
-
version_requirements:
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
58
78
|
- !ruby/object:Gem::Dependency
|
59
79
|
name: ruby-hmac
|
60
|
-
requirement:
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
61
81
|
none: false
|
62
82
|
requirements:
|
63
83
|
- - ! '>='
|
@@ -65,10 +85,15 @@ dependencies:
|
|
65
85
|
version: '0'
|
66
86
|
type: :runtime
|
67
87
|
prerelease: false
|
68
|
-
version_requirements:
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
69
94
|
- !ruby/object:Gem::Dependency
|
70
95
|
name: hashie
|
71
|
-
requirement:
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
72
97
|
none: false
|
73
98
|
requirements:
|
74
99
|
- - ! '>='
|
@@ -76,10 +101,15 @@ dependencies:
|
|
76
101
|
version: '0'
|
77
102
|
type: :runtime
|
78
103
|
prerelease: false
|
79
|
-
version_requirements:
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
80
110
|
- !ruby/object:Gem::Dependency
|
81
111
|
name: rash
|
82
|
-
requirement:
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
83
113
|
none: false
|
84
114
|
requirements:
|
85
115
|
- - ! '>='
|
@@ -87,21 +117,27 @@ dependencies:
|
|
87
117
|
version: '0'
|
88
118
|
type: :runtime
|
89
119
|
prerelease: false
|
90
|
-
version_requirements:
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
91
126
|
description: (Under development) This gem serves as a wrapper for Amazon.com's Marketplace
|
92
127
|
Web Service (MWS) API. Visit http://github.com/elyngved/ruby-mws for documentation.
|
93
128
|
email:
|
94
129
|
- elyngved@gmail.com
|
95
|
-
executables:
|
130
|
+
executables:
|
131
|
+
- ruby-mws
|
96
132
|
extensions: []
|
97
133
|
extra_rdoc_files: []
|
98
134
|
files:
|
99
135
|
- .gitignore
|
100
|
-
- .rvmrc
|
101
136
|
- Gemfile
|
102
137
|
- LICENSE
|
103
138
|
- README.markdown
|
104
139
|
- Rakefile
|
140
|
+
- bin/ruby-mws
|
105
141
|
- lib/ruby-mws.rb
|
106
142
|
- lib/ruby-mws/api/base.rb
|
107
143
|
- lib/ruby-mws/api/inventory.rb
|
@@ -142,7 +178,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
142
178
|
version: '0'
|
143
179
|
requirements: []
|
144
180
|
rubyforge_project: ruby-mws
|
145
|
-
rubygems_version: 1.8.
|
181
|
+
rubygems_version: 1.8.23
|
146
182
|
signing_key:
|
147
183
|
specification_version: 3
|
148
184
|
summary: RubyMWS Gem
|
@@ -156,3 +192,4 @@ test_files:
|
|
156
192
|
- spec/ruby-mws/base_spec.rb
|
157
193
|
- spec/ruby-mws/connection_spec.rb
|
158
194
|
- spec/spec_helper.rb
|
195
|
+
has_rdoc:
|
data/.rvmrc
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
rvm use ruby-1.9.3-p0@ruby-mws
|