Class: Posthubify::Transport

Inherits:
Object
  • Object
show all
Defined in:
lib/posthubify/http.rb

Overview

HTTP transport layer — standard library only (net/http). Bearer auth, JSON body, multipart upload, ‘{ “data” => … }` envelope unwrapping, non-2xx → Posthubify::Error.

Constant Summary collapse

DEFAULT_BASE =
'http://localhost:8787/v1'
USER_AGENT =
'posthubify-ruby/0.1.0'

Instance Method Summary collapse

Constructor Details

#initialize(api_key:, base_url: DEFAULT_BASE, timeout: 30) ⇒ Transport

Returns a new instance of Transport.

Raises:

  • (ArgumentError)


15
16
17
18
19
20
21
# File 'lib/posthubify/http.rb', line 15

def initialize(api_key:, base_url: DEFAULT_BASE, timeout: 30)
  raise ArgumentError, 'api_key required (sk_…)' if api_key.nil? || api_key.empty?

  @key = api_key
  @base = base_url.sub(%r{/\z}, '')
  @timeout = timeout
end

Instance Method Details

#data(method, path, query: nil, body: nil, files: nil, idempotency_key: nil) ⇒ Object

Unwraps the ‘{ “data” => … }` envelope.



52
53
54
55
# File 'lib/posthubify/http.rb', line 52

def data(method, path, query: nil, body: nil, files: nil, idempotency_key: nil)
  result = req(method, path, query: query, body: body, files: files, idempotency_key: idempotency_key)
  result.is_a?(Hash) && result.key?('data') ? result['data'] : result
end

#req(method, path, query: nil, body: nil, files: nil, idempotency_key: nil) ⇒ Object

Raw request: 2xx → parsed body, otherwise Posthubify::Error. files: [field_name, bytes, file_name] — multipart upload (media.upload).



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/posthubify/http.rb', line 25

def req(method, path, query: nil, body: nil, files: nil, idempotency_key: nil)
  uri = URI("#{@base}#{path}")
  unless query.nil?
    pairs = query.reject { |_k, v| v.nil? }
    uri.query = URI.encode_www_form(pairs) unless pairs.empty?
  end

  request = build_request(method, uri, body, files, idempotency_key)
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = uri.scheme == 'https'
  http.read_timeout = @timeout
  http.open_timeout = @timeout

  response = http.request(request)
  parsed = parse(response.body)
  status = response.code.to_i
  unless (200..299).cover?(status)
    message = (parsed.is_a?(Hash) && parsed['error']) || "HTTP #{status}"
    code = parsed.is_a?(Hash) ? parsed['code'] : nil
    raise Posthubify::Error.new(status, message, code, parsed)
  end
  parsed
rescue SocketError, Errno::ECONNREFUSED, Net::OpenTimeout, Net::ReadTimeout => e
  raise Posthubify::Error.new(0, "Network error: #{e.message}")
end