easypost 1.1.3 → 2.0.0
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 +27 -0
- data/CHANGELOG +0 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +30 -0
- data/LICENSE +21 -0
- data/README.md +99 -0
- data/Rakefile +0 -0
- data/VERSION +1 -0
- data/bin/easypost-irb +7 -0
- data/easypost.gemspec +24 -0
- data/lib/easypost.rb +105 -34
- data/lib/easypost/address.rb +14 -7
- data/lib/easypost/batch.rb +34 -0
- data/lib/easypost/customs_info.rb +4 -0
- data/lib/easypost/customs_item.rb +4 -0
- data/lib/easypost/{errors/easypost_error.rb → error.rb} +10 -1
- data/lib/easypost/object.rb +120 -0
- data/lib/easypost/parcel.rb +4 -0
- data/lib/easypost/postage_label.rb +4 -0
- data/lib/easypost/rate.rb +4 -0
- data/lib/easypost/refund.rb +4 -0
- data/lib/easypost/resource.rb +67 -0
- data/lib/easypost/scan_form.rb +4 -0
- data/lib/easypost/shipment.rb +82 -0
- data/lib/easypost/util.rb +102 -0
- data/lib/easypost/version.rb +3 -0
- data/spec/address_spec.rb +75 -0
- data/spec/batch_spec.rb +96 -0
- data/spec/refund_spec.rb +65 -0
- data/spec/scan_form_spec.rb +63 -0
- data/spec/shipment_spec.rb +141 -0
- data/spec/spec_helper.rb +84 -0
- metadata +66 -15
- data/lib/easypost/errors/authentication_error.rb +0 -4
- data/lib/easypost/postage.rb +0 -52
data/.gitignore
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
coverage
|
6
|
+
InstalledFiles
|
7
|
+
lib/bundler/man
|
8
|
+
pkg
|
9
|
+
rdoc
|
10
|
+
spec/reports
|
11
|
+
test/tmp
|
12
|
+
test/version_tmp
|
13
|
+
tmp
|
14
|
+
|
15
|
+
# YARD artifacts
|
16
|
+
.yardoc
|
17
|
+
_yardoc
|
18
|
+
doc/
|
19
|
+
|
20
|
+
# iOS
|
21
|
+
.DS_Store
|
22
|
+
.AppleDouble
|
23
|
+
.LSOverride
|
24
|
+
Icon
|
25
|
+
._*
|
26
|
+
.Spotlight-V100
|
27
|
+
.Trashes
|
data/CHANGELOG
ADDED
File without changes
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
easypost (2.0.0)
|
5
|
+
multi_json (>= 1.0.4, < 2)
|
6
|
+
rest-client (~> 1.4)
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: https://rubygems.org/
|
10
|
+
specs:
|
11
|
+
diff-lcs (1.2.4)
|
12
|
+
mime-types (1.23)
|
13
|
+
multi_json (1.7.7)
|
14
|
+
rest-client (1.6.7)
|
15
|
+
mime-types (>= 1.16)
|
16
|
+
rspec (2.13.0)
|
17
|
+
rspec-core (~> 2.13.0)
|
18
|
+
rspec-expectations (~> 2.13.0)
|
19
|
+
rspec-mocks (~> 2.13.0)
|
20
|
+
rspec-core (2.13.1)
|
21
|
+
rspec-expectations (2.13.0)
|
22
|
+
diff-lcs (>= 1.1.3, < 2.0)
|
23
|
+
rspec-mocks (2.13.1)
|
24
|
+
|
25
|
+
PLATFORMS
|
26
|
+
ruby
|
27
|
+
|
28
|
+
DEPENDENCIES
|
29
|
+
easypost!
|
30
|
+
rspec (~> 2.13.0)
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2013 EasyPost (Simpler Postage, Inc)
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
# EasyPost Ruby Client Library
|
2
|
+
|
3
|
+
EasyPost is a simple shipping API. You can sign up for an account at https://easypost.com
|
4
|
+
|
5
|
+
Installation
|
6
|
+
---------------
|
7
|
+
|
8
|
+
Install the gem:
|
9
|
+
|
10
|
+
```
|
11
|
+
gem install
|
12
|
+
```
|
13
|
+
|
14
|
+
Import the EasyPost client in your application:
|
15
|
+
|
16
|
+
```
|
17
|
+
require 'easypost'
|
18
|
+
```
|
19
|
+
|
20
|
+
Example
|
21
|
+
------------------
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
require 'easypost'
|
25
|
+
EasyPost.api_key = 'cueqNZUb3ldeWTNX7MU3Mel8UXtaAMUi'
|
26
|
+
|
27
|
+
to_address = EasyPost::Address.create(
|
28
|
+
:name => 'Sawyer Bateman',
|
29
|
+
:street1 => '1A Larkspur Cres.',
|
30
|
+
:city => 'St. Albert',
|
31
|
+
:state => 'AB',
|
32
|
+
:zip => 't8n2m4',
|
33
|
+
:country => 'CA',
|
34
|
+
:phone => '780-273-8374'
|
35
|
+
)
|
36
|
+
from_address = EasyPost::Address.create(
|
37
|
+
:company => 'Simpler Postage Inc',
|
38
|
+
:street1 => '388 Townsend Street',
|
39
|
+
:street2 => 'Apt 20',
|
40
|
+
:city => 'San Francisco',
|
41
|
+
:state => 'CA',
|
42
|
+
:zip => '94107',
|
43
|
+
:phone => '415-456-7890'
|
44
|
+
)
|
45
|
+
|
46
|
+
parcel = EasyPost::Parcel.create(
|
47
|
+
:width => 15.2,
|
48
|
+
:length => 18,
|
49
|
+
:height => 9.5,
|
50
|
+
:weight => 35.1
|
51
|
+
)
|
52
|
+
|
53
|
+
customs_item = EasyPost::CustomsItem.create(
|
54
|
+
:description => 'EasyPost T-shirts',
|
55
|
+
:quantity => 2,
|
56
|
+
:value => 23.56,
|
57
|
+
:weight => 33,
|
58
|
+
:origin_country => 'us',
|
59
|
+
:hs_tariff_number => 123456
|
60
|
+
)
|
61
|
+
customs_info = EasyPost::CustomsInfo.create(
|
62
|
+
:integrated_form_type => 'form_2976',
|
63
|
+
:customs_certify => true,
|
64
|
+
:customs_signer => 'Dr. Pepper',
|
65
|
+
:contents_type => 'gift',
|
66
|
+
:contents_explanation => '', # only required when contents_type => 'other'
|
67
|
+
:eel_pfc => 'NOEEI 30.37(a)',
|
68
|
+
:non_delivery_option => 'abandon',
|
69
|
+
:restriction_type => 'none',
|
70
|
+
:restriction_comments => '',
|
71
|
+
:customs_items => [customs_item]
|
72
|
+
)
|
73
|
+
|
74
|
+
shipment = EasyPost::Shipment.create(
|
75
|
+
:to_address => to_address,
|
76
|
+
:from_address => from_address,
|
77
|
+
:parcel => parcel,
|
78
|
+
:customs_info => customs_info
|
79
|
+
)
|
80
|
+
|
81
|
+
shipment.buy(
|
82
|
+
:rate => shipment.lowest_rate
|
83
|
+
)
|
84
|
+
|
85
|
+
puts shipment.postage_label.label_url
|
86
|
+
|
87
|
+
```
|
88
|
+
|
89
|
+
Documentation
|
90
|
+
--------------------
|
91
|
+
|
92
|
+
Up-to-date documentation at: https://easypost.com/docs
|
93
|
+
|
94
|
+
Tests
|
95
|
+
--------------------
|
96
|
+
|
97
|
+
```
|
98
|
+
rspec spec
|
99
|
+
```
|
data/Rakefile
ADDED
File without changes
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.0.0
|
data/bin/easypost-irb
ADDED
data/easypost.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'easypost/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'easypost'
|
8
|
+
spec.version = EasyPost::VERSION
|
9
|
+
spec.date = '2013-06-25'
|
10
|
+
spec.summary = 'EasyPost Ruby Client Library'
|
11
|
+
spec.description = 'Client library for accessing the EasyPost shipping API via Ruby.'
|
12
|
+
spec.authors = ['Jon Calhoun', 'Sawyer Bateman']
|
13
|
+
spec.email = 'contact@easypost.com'
|
14
|
+
spec.homepage = 'https://easypost.com/docs'
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split("\n")
|
17
|
+
spec.test_files = `git ls-files -- test/*`.split("\n")
|
18
|
+
spec.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
spec.require_path = 'lib'
|
20
|
+
|
21
|
+
spec.add_dependency('rest-client', '~> 1.4')
|
22
|
+
spec.add_dependency('multi_json', '>= 1.0.4', '< 2')
|
23
|
+
spec.add_development_dependency('rspec', "~> 2.13.0")
|
24
|
+
end
|
data/lib/easypost.rb
CHANGED
@@ -1,13 +1,33 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
1
|
+
require 'cgi'
|
2
|
+
require 'set'
|
3
|
+
require 'openssl'
|
4
|
+
require 'rest_client'
|
5
|
+
require 'multi_json'
|
6
|
+
|
7
|
+
# Resources
|
8
|
+
require 'easypost/util'
|
9
|
+
require 'easypost/object'
|
10
|
+
require 'easypost/resource'
|
11
|
+
require 'easypost/address'
|
12
|
+
require 'easypost/parcel'
|
13
|
+
require 'easypost/customs_item'
|
14
|
+
require 'easypost/customs_info'
|
15
|
+
require 'easypost/shipment'
|
16
|
+
require 'easypost/rate'
|
17
|
+
require 'easypost/postage_label'
|
18
|
+
require 'easypost/scan_form'
|
19
|
+
require 'easypost/refund'
|
20
|
+
require 'easypost/batch'
|
21
|
+
|
22
|
+
require 'easypost/error'
|
3
23
|
|
4
24
|
module EasyPost
|
5
|
-
@@api_key =
|
6
|
-
@@api_base = 'https://
|
25
|
+
@@api_key = nil
|
26
|
+
@@api_base = 'https://api.easypost.com/v2'
|
27
|
+
@@api_version = nil
|
7
28
|
|
8
|
-
def self.api_url(
|
9
|
-
|
10
|
-
return "#{@@api_base}#{args[:type]}/#{args[:action]}"
|
29
|
+
def self.api_url(url='')
|
30
|
+
@@api_base + url
|
11
31
|
end
|
12
32
|
|
13
33
|
def self.api_key=(api_key)
|
@@ -18,40 +38,91 @@ module EasyPost
|
|
18
38
|
@@api_key
|
19
39
|
end
|
20
40
|
|
21
|
-
def self.
|
22
|
-
|
23
|
-
hash[(key.to_sym rescue key) || key] = hash.delete(key)
|
24
|
-
end
|
25
|
-
return hash
|
41
|
+
def self.api_base=(api_base)
|
42
|
+
@@api_base = api_base
|
26
43
|
end
|
27
44
|
|
28
|
-
def self.
|
29
|
-
|
30
|
-
keysym = (key.to_sym rescue key) || key
|
31
|
-
hash[keysym] = hash.delete(key)
|
32
|
-
if hash[keysym].is_a?(Hash)
|
33
|
-
hash[keysym] = symbolize_keys_recursive(hash[keysym])
|
34
|
-
end
|
35
|
-
end
|
36
|
-
return hash
|
45
|
+
def self.api_base
|
46
|
+
@@api_base
|
37
47
|
end
|
38
48
|
|
39
|
-
def self.
|
40
|
-
|
41
|
-
@response = Typhoeus::Request.get(url, params)
|
42
|
-
return EasyPost.symbolize_keys_recursive(JSON.parse(@response.body))
|
49
|
+
def self.api_version=(version)
|
50
|
+
@@api_version = version
|
43
51
|
end
|
44
52
|
|
45
|
-
def self.
|
46
|
-
|
47
|
-
@response = Typhoeus::Request.post(url, params)
|
48
|
-
return EasyPost.symbolize_keys_recursive(JSON.parse(@response.body))
|
53
|
+
def self.api_version
|
54
|
+
@@api_version
|
49
55
|
end
|
50
56
|
|
51
|
-
|
57
|
+
def self.request(method, url, api_key, params={}, headers={})
|
58
|
+
api_key ||= @@api_key
|
59
|
+
raise Error.new('No API key provided.') unless api_key
|
52
60
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
61
|
+
ssl_opts = { :verify_ssl => false }
|
62
|
+
|
63
|
+
params = Util.objects_to_ids(params)
|
64
|
+
url = self.api_url(url)
|
65
|
+
case method.to_s.downcase.to_sym
|
66
|
+
when :get, :head, :delete
|
67
|
+
# Make params into GET parameters
|
68
|
+
if params && params.count > 0
|
69
|
+
query_string = Util.flatten_params(params).collect{|key, value| "#{key}=#{Util.url_encode(value)}"}.join('&')
|
70
|
+
url += "#{URI.parse(url).query ? '&' : '?'}#{query_string}"
|
71
|
+
end
|
72
|
+
payload = nil
|
73
|
+
else
|
74
|
+
payload = Util.flatten_params(params).collect{|(key, value)| "#{key}=#{Util.url_encode(value)}"}.join('&')
|
75
|
+
end
|
76
|
+
|
77
|
+
headers = {
|
78
|
+
:user_agent => "EasyPost/v2 RubyClient/2.0.0",
|
79
|
+
:authorization => "Bearer #{api_key}",
|
80
|
+
:content_type => 'application/x-www-form-urlencoded'
|
81
|
+
}.merge(headers)
|
57
82
|
|
83
|
+
opts = {
|
84
|
+
:method => method,
|
85
|
+
:url => url,
|
86
|
+
:headers => headers,
|
87
|
+
:open_timeout => 30,
|
88
|
+
:payload => payload,
|
89
|
+
:timeout => 60
|
90
|
+
}.merge(ssl_opts)
|
91
|
+
|
92
|
+
begin
|
93
|
+
response = execute_request(opts)
|
94
|
+
rescue RestClient::ExceptionWithResponse => e
|
95
|
+
if response_code = e.http_code and response_body = e.http_body
|
96
|
+
begin
|
97
|
+
response_json = MultiJson.load(response_body, :symbolize_keys => true)
|
98
|
+
rescue MultiJson::DecodeError
|
99
|
+
raise Error.new("Invalid response from API, unable to decode.", response_code, response_body)
|
100
|
+
end
|
101
|
+
begin
|
102
|
+
raise NoMethodError if response_json[:error][:message] == nil
|
103
|
+
raise Error.new(response_json[:error][:message], response_code, response_body, response_json)
|
104
|
+
rescue NoMethodError, TypeError
|
105
|
+
raise Error.new(response_json[:error], response_code, response_body, response_json)
|
106
|
+
end
|
107
|
+
else
|
108
|
+
raise Error.new(e.message)
|
109
|
+
end
|
110
|
+
rescue RestClient::Exception, Errno::ECONNREFUSED => e
|
111
|
+
raise Error.new(e.message)
|
112
|
+
end
|
113
|
+
|
114
|
+
begin
|
115
|
+
response_json = MultiJson.load(response.body, :symbolize_keys => true)
|
116
|
+
rescue MultiJson::DecodeError
|
117
|
+
raise Error.new("Invalid response object from API, unable to decode.", response.code, response.body)
|
118
|
+
end
|
119
|
+
|
120
|
+
return [response_json, api_key]
|
121
|
+
end
|
122
|
+
|
123
|
+
private
|
124
|
+
|
125
|
+
def self.execute_request(opts)
|
126
|
+
RestClient::Request.execute(opts)
|
127
|
+
end
|
128
|
+
end
|
data/lib/easypost/address.rb
CHANGED
@@ -1,13 +1,20 @@
|
|
1
1
|
module EasyPost
|
2
|
-
class Address
|
3
|
-
@@type = "address"
|
2
|
+
class Address < Resource
|
4
3
|
|
5
|
-
def
|
6
|
-
|
7
|
-
|
4
|
+
def verify(params={})
|
5
|
+
response, api_key = EasyPost.request(:get, url + '/verify', @api_key, params)
|
6
|
+
|
7
|
+
if response.has_key?(:address)
|
8
|
+
if response.has_key?(:message)
|
9
|
+
response[:address][:message] = response[:message]
|
10
|
+
end
|
11
|
+
verified_address = EasyPost::Util::convert_to_easypost_object(response[:address], api_key)
|
12
|
+
return verified_address
|
13
|
+
else
|
14
|
+
raise Error.new("Unable to verify address.")
|
15
|
+
end
|
8
16
|
|
9
|
-
|
10
|
-
@verified_address = EasyPost.get(EasyPost.api_url(:type => @@type, :action => "verify"), :address => address)
|
17
|
+
return self
|
11
18
|
end
|
12
19
|
|
13
20
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module EasyPost
|
2
|
+
class Batch < Resource
|
3
|
+
|
4
|
+
def self.create_and_buy(params={})
|
5
|
+
wrapped_params = {}
|
6
|
+
wrapped_params[self.class_name().to_sym] = params
|
7
|
+
response, api_key = EasyPost.request(:post, url + '/create_and_buy', @api_key, wrapped_params)
|
8
|
+
|
9
|
+
return Util.convert_to_easypost_object(response, api_key)
|
10
|
+
end
|
11
|
+
|
12
|
+
def label(params={})
|
13
|
+
response, api_key = EasyPost.request(:post, url + '/label', @api_key, params)
|
14
|
+
self.refresh_from(response, @api_key, true)
|
15
|
+
|
16
|
+
return self
|
17
|
+
end
|
18
|
+
|
19
|
+
def remove_shipments(params={})
|
20
|
+
response, api_key = EasyPost.request(:post, url + '/remove_shipments', @api_key, params)
|
21
|
+
self.refresh_from(response, @api_key, true)
|
22
|
+
|
23
|
+
return self
|
24
|
+
end
|
25
|
+
|
26
|
+
def add_shipments(params={})
|
27
|
+
response, api_key = EasyPost.request(:post, url + '/add_shipments', @api_key, params)
|
28
|
+
self.refresh_from(response, @api_key, true)
|
29
|
+
|
30
|
+
return self
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|