Class: Shotwolf::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/shotwolf/client.rb

Overview

Client for the ShotWolf API. Pass an API key (+sw_live_...+) or set the SHOTWOLF_API_KEY environment variable.

sw = Shotwolf::Client.new
shot = sw.capture(url: "https://example.com", device: "iphone_15_pro")
puts shot["image_url"]

Constant Summary collapse

DEFAULT_BASE_URL =
"https://shotwolf.com"
RETRYABLE_STATUSES =
[429, 500, 502, 503, 504].freeze

Instance Method Summary collapse

Constructor Details

#initialize(api_key = nil, base_url: DEFAULT_BASE_URL, timeout: 60, max_retries: 2, retry_backoff: 0.5, transport: nil) ⇒ Client

Returns a new instance of Client.



21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/shotwolf/client.rb', line 21

def initialize(api_key = nil, base_url: DEFAULT_BASE_URL, timeout: 60, max_retries: 2,
               retry_backoff: 0.5, transport: nil)
  @api_key = api_key || ENV.fetch("SHOTWOLF_API_KEY", nil)
  if @api_key.nil? || @api_key.empty?
    raise Error.new("Missing API key. Pass api_key or set SHOTWOLF_API_KEY.", type: "unauthorized")
  end

  @base_url = base_url.sub(%r{/+\z}, "")
  @timeout = timeout
  @max_retries = max_retries
  @retry_backoff = retry_backoff
  @transport = transport || method(:net_http_transport)
end

Instance Method Details

#account(timeout: nil) ⇒ Object

Get balance, tier and webhook secret. GET /api/v1/account



76
77
78
# File 'lib/shotwolf/client.rb', line 76

def (timeout: nil)
  request("GET", "/api/v1/account", timeout: timeout)
end

#batch(idempotency_key: nil, timeout: nil, **params) ⇒ Object

Render one URL across 2-6 devices. POST /api/v1/capture/batch



46
47
48
# File 'lib/shotwolf/client.rb', line 46

def batch(idempotency_key: nil, timeout: nil, **params)
  request("POST", "/api/v1/capture/batch", body: params, idempotency_key: idempotency_key, timeout: timeout)
end

#capture(idempotency_key: nil, timeout: nil, **params) ⇒ Object

Capture a URL or HTML synchronously. POST /api/v1/captures



36
37
38
# File 'lib/shotwolf/client.rb', line 36

def capture(idempotency_key: nil, timeout: nil, **params)
  request("POST", "/api/v1/captures", body: params, idempotency_key: idempotency_key, timeout: timeout)
end

#capture_async(idempotency_key: nil, timeout: nil, **params) ⇒ Object

Queue a capture and return immediately. POST /api/v1/captures/async



41
42
43
# File 'lib/shotwolf/client.rb', line 41

def capture_async(idempotency_key: nil, timeout: nil, **params)
  request("POST", "/api/v1/captures/async", body: params, idempotency_key: idempotency_key, timeout: timeout)
end

#diff(idempotency_key: nil, timeout: nil, **params) ⇒ Object

Pixel-diff two screenshots. POST /api/v1/diffs



66
67
68
# File 'lib/shotwolf/client.rb', line 66

def diff(idempotency_key: nil, timeout: nil, **params)
  request("POST", "/api/v1/diffs", body: params, idempotency_key: idempotency_key, timeout: timeout)
end

#get_screenshot(id, timeout: nil) ⇒ Object

Retrieve a single screenshot by ID. GET /api/v1/screenshots/:id



71
72
73
# File 'lib/shotwolf/client.rb', line 71

def get_screenshot(id, timeout: nil)
  request("GET", "/api/v1/screenshots/#{id.to_i}", timeout: timeout)
end

#mockup(idempotency_key: nil, timeout: nil, **params) ⇒ Object

Render a URL inside a device/social mockup. POST /api/v1/mockups



51
52
53
# File 'lib/shotwolf/client.rb', line 51

def mockup(idempotency_key: nil, timeout: nil, **params)
  request("POST", "/api/v1/mockups", body: params, idempotency_key: idempotency_key, timeout: timeout)
end

#og(idempotency_key: nil, timeout: nil, **params) ⇒ Object

Generate an Open Graph card from a template. POST /api/v1/og



56
57
58
# File 'lib/shotwolf/client.rb', line 56

def og(idempotency_key: nil, timeout: nil, **params)
  request("POST", "/api/v1/og", body: params, idempotency_key: idempotency_key, timeout: timeout)
end

#pdf(idempotency_key: nil, timeout: nil, **params) ⇒ Object

Convert a URL or HTML string to PDF. POST /api/v1/pdf



61
62
63
# File 'lib/shotwolf/client.rb', line 61

def pdf(idempotency_key: nil, timeout: nil, **params)
  request("POST", "/api/v1/pdf", body: params, idempotency_key: idempotency_key, timeout: timeout)
end

#wait_for(id, interval: 2.0, timeout: 120.0) ⇒ Object

Poll get_screenshot until the shot is done or failed. Returns the final screenshot Hash; raises Shotwolf::Error on render failure or Shotwolf::TimeoutError if the deadline passes.



83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/shotwolf/client.rb', line 83

def wait_for(id, interval: 2.0, timeout: 120.0)
  deadline = monotonic + timeout
  loop do
    shot = get_screenshot(id)
    return shot if shot["status"] == "done"
    if shot["status"] == "failed"
      raise Error.new("Screenshot #{id} failed to render", type: "render_failed", status: 422)
    end
    raise TimeoutError.new(timeout) if monotonic + interval > deadline

    sleep(interval)
  end
end