Module: Smartbill::Sdk::Transport
- Defined in:
- lib/smartbill/sdk/transport.rb,
lib/smartbill/sdk/transport/request.rb,
lib/smartbill/sdk/transport/rate_limiter.rb
Overview
Shared transport logic for the SmartBill clients.
The SmartBill API uses HTTP Basic Auth with username:token and returns JSON envelopes whose root key depends on the endpoint (sbcResponse, Response, sbcInvoicePaymentStatusResponse, sbcSeries, sbcTaxes, stocks, Fault). This module centralises request building, auth, envelope unwrapping and error mapping so the clients stay DRY.
Defined Under Namespace
Classes: RateLimiter, Request
Constant Summary collapse
- DEFAULT_BASE_URL =
"https://ws.smartbill.ro/SBORO/api/"- DEFAULT_TIMEOUT =
30.0- ENVELOPE_KEYS =
Envelope root keys used by SmartBill responses.
%w[ sbcResponse Response sbcInvoicePaymentStatusResponse sbcSeries sbcTaxes stocks Fault ].freeze
- ERROR_FIELDS =
Fields that may carry an error message inside an envelope.
%w[errorText errorTextError].freeze
Instance Attribute Summary collapse
-
#body Serialized request body (may be nil).(Serializedrequestbody(may be nil)) ⇒ Object
readonly
A request value object built by Transport.build_request and sent by an adapter.
-
#headers Hash of HTTP headers.(HashofHTTPheaders.) ⇒ Object
readonly
A request value object built by Transport.build_request and sent by an adapter.
-
#http_method HTTP method ("GET", "POST", ...).(HTTPmethod("GET", "POST", ...)) ⇒ Object
readonly
A request value object built by Transport.build_request and sent by an adapter.
-
#query Hash of query parameters (may be nil).(Hashofqueryparameters(may be nil)) ⇒ Object
readonly
A request value object built by Transport.build_request and sent by an adapter.
-
#url Full URL (without query string).(FullURL(without query string)) ⇒ Object
readonly
A request value object built by Transport.build_request and sent by an adapter.
Class Method Summary collapse
-
.build_auth(username, token) ⇒ Object
Alias kept for parity with the Python SDK.
-
.build_auth_header(username, token) ⇒ Object
Build the Authorization: Basic … header value for
username:token. -
.build_request(method:, base_url:, path:, params: nil, json_body: nil, accept: "application/json", content_type: "application/json", auth_header: nil) ⇒ Object
Construct a Request with SmartBill default headers.
-
.extract_error(envelope) ⇒ Object
Extract (error_text, message) from an envelope.
-
.handle_response(response, binary: false) ⇒ Object
Validate a Response and return its parsed payload.
-
.parse_envelope(payload) ⇒ Object
Unwrap the SmartBill response envelope and return its inner object.
Instance Attribute Details
#body Serialized request body (may be nil).(Serializedrequestbody(may be nil)) ⇒ Object (readonly)
A request value object built by Smartbill::Sdk::Transport.build_request and sent by an adapter.
14 |
# File 'lib/smartbill/sdk/transport/request.rb', line 14 Request = Struct.new(:http_method, :url, :headers, :query, :body, keyword_init: true) |
#headers Hash of HTTP headers.(HashofHTTPheaders.) ⇒ Object (readonly)
A request value object built by Smartbill::Sdk::Transport.build_request and sent by an adapter.
14 |
# File 'lib/smartbill/sdk/transport/request.rb', line 14 Request = Struct.new(:http_method, :url, :headers, :query, :body, keyword_init: true) |
#http_method HTTP method ("GET", "POST", ...).(HTTPmethod("GET", "POST", ...)) ⇒ Object (readonly)
A request value object built by Smartbill::Sdk::Transport.build_request and sent by an adapter.
14 |
# File 'lib/smartbill/sdk/transport/request.rb', line 14 Request = Struct.new(:http_method, :url, :headers, :query, :body, keyword_init: true) |
#query Hash of query parameters (may be nil).(Hashofqueryparameters(may be nil)) ⇒ Object (readonly)
A request value object built by Smartbill::Sdk::Transport.build_request and sent by an adapter.
14 |
# File 'lib/smartbill/sdk/transport/request.rb', line 14 Request = Struct.new(:http_method, :url, :headers, :query, :body, keyword_init: true) |
#url Full URL (without query string).(FullURL(without query string)) ⇒ Object (readonly)
A request value object built by Smartbill::Sdk::Transport.build_request and sent by an adapter.
14 |
# File 'lib/smartbill/sdk/transport/request.rb', line 14 Request = Struct.new(:http_method, :url, :headers, :query, :body, keyword_init: true) |
Class Method Details
.build_auth(username, token) ⇒ Object
Alias kept for parity with the Python SDK.
40 41 42 |
# File 'lib/smartbill/sdk/transport.rb', line 40 def self.build_auth(username, token) build_auth_header(username, token) end |
.build_auth_header(username, token) ⇒ Object
Build the Authorization: Basic … header value for username:token.
35 36 37 |
# File 'lib/smartbill/sdk/transport.rb', line 35 def self.build_auth_header(username, token) "Basic #{Base64.strict_encode64("#{username}:#{token}")}" end |
.build_request(method:, base_url:, path:, params: nil, json_body: nil, accept: "application/json", content_type: "application/json", auth_header: nil) ⇒ Object
Construct a Request with SmartBill default headers.
45 46 47 48 49 50 51 52 53 |
# File 'lib/smartbill/sdk/transport.rb', line 45 def self.build_request(method:, base_url:, path:, params: nil, json_body: nil, accept: "application/json", content_type: "application/json", auth_header: nil) url = path.start_with?("http") ? path : "#{base_url.chomp("/")}/#{path.delete_prefix("/")}" headers = { "Accept" => accept, "Content-Type" => content_type } headers["Authorization"] = auth_header if auth_header body = json_body ? JSON.generate(json_body) : nil Request.new(http_method: method.upcase, url: url, headers: headers, query: params, body: body) end |
.extract_error(envelope) ⇒ Object
Extract (error_text, message) from an envelope.
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/smartbill/sdk/transport.rb', line 78 def self.extract_error(envelope) return ["", nil] unless envelope.is_a?(Hash) error_text = "" ERROR_FIELDS.each do |field| value = envelope[field] next unless value.is_a?(String) && !value.strip.empty? error_text = value break end = envelope["message"] = nil unless .is_a?(String) [error_text, ] end |
.handle_response(response, binary: false) ⇒ Object
99 100 101 102 103 104 105 106 107 108 |
# File 'lib/smartbill/sdk/transport.rb', line 99 def self.handle_response(response, binary: false) status = response.status raise auth_error(response) if status == 401 raise rate_limit_error if status == 403 return response.body if binary && (200..299).cover?(status) return handle_success(response, status, binary: binary) if (200..299).cover?(status) raise api_error_from(response, status) end |
.parse_envelope(payload) ⇒ Object
Unwrap the SmartBill response envelope and return its inner object.
If the payload is a Hash whose only key is one of the known envelope keys, the value under that key is returned. Otherwise the payload is returned unchanged.
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/smartbill/sdk/transport.rb', line 60 def self.parse_envelope(payload) return payload unless payload.is_a?(Hash) if payload.size == 1 key, value = payload.first return value if ENVELOPE_KEYS.include?(key) end # Some envelopes nest under a known key with sibling fields. ENVELOPE_KEYS.each do |key| next unless payload.key?(key) inner = payload[key] return inner if inner.is_a?(Hash) end payload end |