Class: TesoteSdk::Transport

Inherits:
Object
  • Object
show all
Defined in:
lib/tesote_sdk/transport.rb

Constant Summary collapse

DEFAULT_BASE_URL =
'https://equipo.tesote.com/api'.freeze
DEFAULT_OPEN_TIMEOUT =
5
DEFAULT_READ_TIMEOUT =
30
DEFAULT_MAX_ATTEMPTS =
3
DEFAULT_BASE_DELAY =
0.250
DEFAULT_MAX_DELAY =
8.0
MUTATING_METHODS =
%w[POST PUT PATCH DELETE].freeze
RETRYABLE_STATUSES =
[429, 502, 503, 504].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(api_key:, version_segment:, base_url: DEFAULT_BASE_URL, user_agent: nil, open_timeout: DEFAULT_OPEN_TIMEOUT, read_timeout: DEFAULT_READ_TIMEOUT, max_attempts: DEFAULT_MAX_ATTEMPTS, base_delay: DEFAULT_BASE_DELAY, max_delay: DEFAULT_MAX_DELAY, logger: nil, cache_backend: nil, sleeper: nil, randomizer: nil) ⇒ Transport

Returns a new instance of Transport.

Raises:



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/tesote_sdk/transport.rb', line 73

def initialize(api_key:,
               version_segment:,
               base_url: DEFAULT_BASE_URL,
               user_agent: nil,
               open_timeout: DEFAULT_OPEN_TIMEOUT,
               read_timeout: DEFAULT_READ_TIMEOUT,
               max_attempts: DEFAULT_MAX_ATTEMPTS,
               base_delay: DEFAULT_BASE_DELAY,
               max_delay: DEFAULT_MAX_DELAY,
               logger: nil,
               cache_backend: nil,
               sleeper: nil,
               randomizer: nil)
  raise ConfigError, 'api_key is required' if api_key.nil? || api_key.to_s.empty?
  raise ConfigError, 'version_segment is required' if version_segment.nil? || version_segment.to_s.empty?

  @api_key = api_key.to_s
  @version_segment = version_segment.to_s
  @base_url = base_url.to_s.sub(%r{/+\z}, '')
  @user_agent = user_agent || default_user_agent
  @open_timeout = open_timeout
  @read_timeout = read_timeout
  @max_attempts = max_attempts
  @base_delay = base_delay
  @max_delay = max_delay
  @logger = logger
  @cache_backend = cache_backend
  @sleeper = sleeper || ->(seconds) { sleep(seconds) }
  @randomizer = randomizer || ->(max) { Kernel.rand(max) }
  @last_rate_limit = nil
  @last_request_id = nil
end

Instance Attribute Details

#api_keyObject (readonly)

Returns the value of attribute api_key.



67
68
69
# File 'lib/tesote_sdk/transport.rb', line 67

def api_key
  @api_key
end

#base_delayObject (readonly)

Returns the value of attribute base_delay.



67
68
69
# File 'lib/tesote_sdk/transport.rb', line 67

def base_delay
  @base_delay
end

#base_urlObject (readonly)

Returns the value of attribute base_url.



67
68
69
# File 'lib/tesote_sdk/transport.rb', line 67

def base_url
  @base_url
end

#cache_backendObject (readonly)

Returns the value of attribute cache_backend.



67
68
69
# File 'lib/tesote_sdk/transport.rb', line 67

def cache_backend
  @cache_backend
end

#last_rate_limitObject

Returns the value of attribute last_rate_limit.



71
72
73
# File 'lib/tesote_sdk/transport.rb', line 71

def last_rate_limit
  @last_rate_limit
end

#last_request_idObject

Returns the value of attribute last_request_id.



71
72
73
# File 'lib/tesote_sdk/transport.rb', line 71

def last_request_id
  @last_request_id
end

#loggerObject (readonly)

Returns the value of attribute logger.



67
68
69
# File 'lib/tesote_sdk/transport.rb', line 67

def logger
  @logger
end

#max_attemptsObject (readonly)

Returns the value of attribute max_attempts.



67
68
69
# File 'lib/tesote_sdk/transport.rb', line 67

def max_attempts
  @max_attempts
end

#max_delayObject (readonly)

Returns the value of attribute max_delay.



67
68
69
# File 'lib/tesote_sdk/transport.rb', line 67

def max_delay
  @max_delay
end

#open_timeoutObject (readonly)

Returns the value of attribute open_timeout.



67
68
69
# File 'lib/tesote_sdk/transport.rb', line 67

def open_timeout
  @open_timeout
end

#read_timeoutObject (readonly)

Returns the value of attribute read_timeout.



67
68
69
# File 'lib/tesote_sdk/transport.rb', line 67

def read_timeout
  @read_timeout
end

#user_agentObject (readonly)

Returns the value of attribute user_agent.



67
68
69
# File 'lib/tesote_sdk/transport.rb', line 67

def user_agent
  @user_agent
end

#version_segmentObject (readonly)

Returns the value of attribute version_segment.



67
68
69
# File 'lib/tesote_sdk/transport.rb', line 67

def version_segment
  @version_segment
end

Instance Method Details

#request(method, path, query: nil, body: nil, opts: {}) ⇒ Object

opts:

:idempotency_key      → forwarded as Idempotency-Key (auto-gen for mutations)
:cache                → false to bypass; { ttl: int } to enable TTL cache
:extra_headers        → hash of additional headers


110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/tesote_sdk/transport.rb', line 110

def request(method, path, query: nil, body: nil, opts: {})
  method_upper = method.to_s.upcase
  uri = build_uri(path, query)
  cache_key = cache_key_for(method_upper, uri, opts)
  cached = cache_lookup(method_upper, cache_key, opts)
  return cached unless cached.nil?

  request_summary = build_request_summary(method_upper, uri, body)
  response, body_str, attempts = perform_with_retries(method_upper, uri, body, opts, request_summary)

  record_rate_limit(response)
  @last_request_id = response['x-request-id'] || response['X-Request-Id']

  status = response.code.to_i
  if status >= 200 && status < 300
    parsed = parse_json(body_str)
    cache_store(method_upper, cache_key, parsed, opts)
    bust_cache_for_mutation(method_upper, uri)
    return parsed
  end

  raise ApiError.from_response(response, body_str, request_summary, attempts: attempts)
end