Class: MisarBlog::Client
- Inherits:
-
Object
- Object
- MisarBlog::Client
- Defined in:
- lib/misarblog/client.rb
Instance Attribute Summary collapse
-
#account ⇒ Object
readonly
Returns the value of attribute account.
-
#ai ⇒ Object
readonly
Returns the value of attribute ai.
-
#analytics ⇒ Object
readonly
Returns the value of attribute analytics.
-
#articles ⇒ Object
readonly
Returns the value of attribute articles.
-
#comments ⇒ Object
readonly
Returns the value of attribute comments.
-
#follows ⇒ Object
readonly
Returns the value of attribute follows.
-
#images ⇒ Object
readonly
Returns the value of attribute images.
-
#reactions ⇒ Object
readonly
Returns the value of attribute reactions.
-
#series ⇒ Object
readonly
Returns the value of attribute series.
Instance Method Summary collapse
-
#initialize(api_key:, base_url: BASE_URL, timeout: 30, max_retries: 3) ⇒ Client
constructor
A new instance of Client.
-
#request(method, path, data = {}) ⇒ Hash
Decoded JSON body (empty Hash for 204/no-content).
Constructor Details
#initialize(api_key:, base_url: BASE_URL, timeout: 30, max_retries: 3) ⇒ Client
Returns a new instance of Client.
246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 |
# File 'lib/misarblog/client.rb', line 246 def initialize(api_key:, base_url: BASE_URL, timeout: 30, max_retries: 3) raise ArgumentError, "api_key is required" if api_key.nil? || api_key.empty? @api_key = api_key @base_url = base_url.chomp("/") @timeout = timeout @max_retries = [max_retries, 1].max @ai = AiResource.new(self) @articles = ArticlesResource.new(self) @images = ImagesResource.new(self) @reactions = ReactionsResource.new(self) @series = SeriesResource.new(self) @account = AccountResource.new(self) @analytics = AnalyticsResource.new(self) @comments = CommentsResource.new(self) @follows = FollowsResource.new(self) end |
Instance Attribute Details
#account ⇒ Object (readonly)
Returns the value of attribute account.
239 240 241 |
# File 'lib/misarblog/client.rb', line 239 def account @account end |
#ai ⇒ Object (readonly)
Returns the value of attribute ai.
239 240 241 |
# File 'lib/misarblog/client.rb', line 239 def ai @ai end |
#analytics ⇒ Object (readonly)
Returns the value of attribute analytics.
239 240 241 |
# File 'lib/misarblog/client.rb', line 239 def analytics @analytics end |
#articles ⇒ Object (readonly)
Returns the value of attribute articles.
239 240 241 |
# File 'lib/misarblog/client.rb', line 239 def articles @articles end |
#comments ⇒ Object (readonly)
Returns the value of attribute comments.
239 240 241 |
# File 'lib/misarblog/client.rb', line 239 def comments @comments end |
#follows ⇒ Object (readonly)
Returns the value of attribute follows.
239 240 241 |
# File 'lib/misarblog/client.rb', line 239 def follows @follows end |
#images ⇒ Object (readonly)
Returns the value of attribute images.
239 240 241 |
# File 'lib/misarblog/client.rb', line 239 def images @images end |
#reactions ⇒ Object (readonly)
Returns the value of attribute reactions.
239 240 241 |
# File 'lib/misarblog/client.rb', line 239 def reactions @reactions end |
#series ⇒ Object (readonly)
Returns the value of attribute series.
239 240 241 |
# File 'lib/misarblog/client.rb', line 239 def series @series end |
Instance Method Details
#request(method, path, data = {}) ⇒ Hash
Returns decoded JSON body (empty Hash for 204/no-content).
270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 |
# File 'lib/misarblog/client.rb', line 270 def request(method, path, data = {}) url = URI.parse(@base_url + "/" + path.delete_prefix("/")) has_body = !data.empty? && %i[post put patch].include?(method) json_body = has_body ? JSON.generate(data) : nil last_status = 0 @max_retries.times do |attempt| final = attempt == @max_retries - 1 begin http = Net::HTTP.new(url.host, url.port) http.use_ssl = url.scheme == "https" http.open_timeout = 10 http.read_timeout = @timeout req = build_request(method, url, json_body) resp = http.request(req) last_status = resp.code.to_i # Retry on transient statuses — but on the FINAL attempt, still # return/raise from the real response (never swallow the send). # A plan-limit 429 is not "slow down" — retrying cannot help until # the allowance resets or the plan changes, so fall straight through # to parse_response and raise instead of burning the retry budget. if RETRYABLE.include?(last_status) && !final && !plan_limit?(resp) sleep(RETRY_BASE_S * (2**attempt)) next end return parse_response(resp, last_status) rescue Net::OpenTimeout, Net::ReadTimeout, Errno::ECONNREFUSED, Errno::ECONNRESET, SocketError => e raise NetworkError.new(e., e) if final sleep(RETRY_BASE_S * (2**attempt)) next end end raise ApiError.new(last_status, "Max retries exceeded") end |