Class: ScreenshotFreeAPI::HttpClient

Inherits:
Object
  • Object
show all
Defined in:
lib/screenshotfreeapi/http_client.rb

Overview

Low-level HTTP client responsible for:

- Building requests with correct headers
- Parsing JSON responses
- Mapping HTTP error statuses to typed exceptions
- Retrying transient failures (429, 5xx) with exponential backoff

Constant Summary collapse

DEFAULT_BASE_URL =
"https://api.screenshotfreeapi.com"
DEFAULT_TIMEOUT =
30
DEFAULT_RETRIES =
3
DEFAULT_DELAY =

seconds — doubles on each retry: 1s, 2s, 4s

1

Instance Method Summary collapse

Constructor Details

#initialize(api_key:, base_url: DEFAULT_BASE_URL, timeout: DEFAULT_TIMEOUT, max_retries: DEFAULT_RETRIES, retry_delay: DEFAULT_DELAY) ⇒ HttpClient

Returns a new instance of HttpClient.

Parameters:

  • api_key (String)

    Bearer token (API key or JWT)

  • base_url (String) (defaults to: DEFAULT_BASE_URL)

    Override for testing / staging

  • timeout (Integer) (defaults to: DEFAULT_TIMEOUT)

    Open/read timeout in seconds

  • max_retries (Integer) (defaults to: DEFAULT_RETRIES)

    Maximum number of retry attempts (not counting the first try)

  • retry_delay (Numeric) (defaults to: DEFAULT_DELAY)

    Base delay in seconds; doubles each retry

Raises:

  • (ArgumentError)


24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/screenshotfreeapi/http_client.rb', line 24

def initialize(
  api_key:,
  base_url:    DEFAULT_BASE_URL,
  timeout:     DEFAULT_TIMEOUT,
  max_retries: DEFAULT_RETRIES,
  retry_delay: DEFAULT_DELAY
)
  raise ArgumentError, "api_key is required" if api_key.nil? || api_key.to_s.strip.empty?

  @api_key     = api_key
  @base_url    = base_url.to_s.chomp("/")
  @timeout     = timeout
  @max_retries = max_retries
  @retry_delay = retry_delay
end

Instance Method Details

#request(method, path, body: nil, query: {}, auth_header: nil) ⇒ Hash

Perform an HTTP request with automatic retry on transient errors.

Parameters:

  • method (Symbol)

    :get, :post, :patch, :delete

  • path (String)

    Path starting with “/”

  • body (Hash, nil) (defaults to: nil)

    Request body; serialised to JSON automatically

  • query (Hash) (defaults to: {})

    Query-string parameters

  • auth_header (String, nil) (defaults to: nil)

    Override the Authorization header value

Returns:

  • (Hash)

    Parsed JSON response body



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/screenshotfreeapi/http_client.rb', line 49

def request(method, path, body: nil, query: {}, auth_header: nil)
  uri = build_uri(path, query)

  attempts = 0
  delay    = @retry_delay

  begin
    attempts += 1
    response = execute(uri, method, body, auth_header)
    handle_response(response)
  rescue RateLimitError => e
    # Respect Retry-After if present; always retry rate-limit errors up to max_retries
    if attempts <= @max_retries
      wait = e.retry_after || delay
      sleep(wait)
      delay *= 2
      retry
    end
    raise
  rescue ScreenshotFreeAPIError => e
    # Retry 5xx errors with exponential backoff
    if e.status_code.to_i >= 500 && attempts <= @max_retries
      sleep(delay)
      delay *= 2
      retry
    end
    raise
  end
end