lib/peddler/api.rb in peddler-3.0.0.beta1 vs lib/peddler/api.rb in peddler-3.0.0
- old
+ new
@@ -1,59 +1,82 @@
# frozen_string_literal: true
require "http"
+require "peddler/endpoint"
require "peddler/error"
-require "peddler/region"
+require "peddler/version"
module Peddler
# Wraps an Amazon Selling Partner API (SP-API)
class API
- # @return [Peddler::Region]
- attr_reader :region
+ class CannotSandbox < StandardError; end
+ class MustSandbox < StandardError; end
+ # @return [Peddler::Endpoint]
+ attr_reader :endpoint
+
# @return [String]
attr_reader :access_token
# @param [String] aws_region
# @param [String] access_token
def initialize(aws_region, access_token)
- @region = Region.new(aws_region)
+ @endpoint = Endpoint.find(aws_region)
@access_token = access_token
+ @sandbox = false
end
- def endpoint
- @endpoint ||= region.endpoint
+ # @return [URI::HTTPS]
+ def endpoint_uri
+ sandbox? ? endpoint.sandbox : endpoint.production
end
# @see https://developer-docs.amazon.com/sp-api/docs/the-selling-partner-api-sandbox
# @return [self]
def sandbox
- @endpoint = endpoint.sub(/(?:sandbox.)?sellingpartnerapi/, "sandbox.sellingpartnerapi")
+ @sandbox = true
self
end
+ # @return [Boolean]
+ def sandbox?
+ @sandbox
+ end
+
+ # @raise [CannotSandbox] if in a sandbox environment
+ def cannot_sandbox!
+ raise CannotSandbox, "cannot run in a sandbox" if sandbox?
+ end
+
+ # @raise [MustSandbox] unless in a sandbox environment
+ def must_sandbox!
+ raise MustSandbox, "must run in a sandbox" unless sandbox?
+ end
+
# @see https://developer-docs.amazon.com/sp-api/docs/include-a-user-agent-header-in-all-requests
# @see https://developer-docs.amazon.com/amazon-shipping/docs/connecting-to-the-selling-partner-api#step-3-add-headers-to-the-uri
# @return [HTTP::Client]
def http
@http ||= HTTP.headers(
- "Host" => endpoint_host,
+ "Host" => endpoint_uri.host,
"User-Agent" => user_agent,
"X-Amz-Access-Token" => access_token,
"X-Amz-Date" => timestamp,
)
end
- # Retries with a rate limit when the API returns a 429
+ # Throttles with a rate limit and retries when the API returns a 429
#
- # @param [Float] delay The delay in seconds before retrying
+ # @param [Float] rate_limit The delay in seconds before retrying
# @return [self]
- def rate_limit(rate)
- # HTTP v6.0 will implement retriable
+ def meter(rate_limit)
+ # HTTP v6.0 will implement retriable. Until then, point to their GitHub repo, or it's a no-op.
# https://github.com/httprb/http/pull/790
- retriable(delay: 1.0 / rate, retry_statuses: [429]) if @http.respond_to?(:retriable)
+ delay = sandbox? ? 0.2 : 1.0 / rate_limit
+ retriable(delay: delay, retry_statuses: [429]) if @http.respond_to?(:retriable)
+
self
end
# @!method use(*features)
# Turn on [HTTP](https://github.com/httprb/http) features
@@ -85,25 +108,25 @@
define_method(method) do |path, **options|
if options[:body] && !options[:body].is_a?(String)
options[:json] = options.delete(:body)
end
- response = http.send(method, [endpoint, path].join, **options)
+ uri = endpoint_uri.tap do |uri|
+ uri.path = path
+ end
+ response = http.send(method, uri, **options)
+
if response.status.client_error?
error = Error.build(response)
raise error if error
end
response
end
end
private
-
- def endpoint_host
- URI.parse(endpoint).host
- end
def user_agent
"Peddler/#{Peddler::VERSION} (Language=Ruby; #{Socket.gethostname})"
end