Module: Pictify

Defined in:
lib/pictify.rb,
lib/pictify/types.rb,
lib/pictify/client.rb,
lib/pictify/errors.rb,
lib/pictify/version.rb

Overview

Pictify Ruby SDK

Official SDK for generating images, PDFs, and GIFs from raw HTML, live URLs, and reusable templates using the Pictify API.

Examples:

Render raw HTML to a PNG

client = Pictify::Client.new(api_key: "your-api-key")
image = client.render_html(html: "<div>Hello World</div>", width: 1200, height: 630)
puts image.url

Render a template

result = client.render(
  template_id: "your-template-uid",
  variables: { name: "Ada", company: "Pictify" }
)
puts result.url

Defined Under Namespace

Classes: AuthenticationError, BatchItemStatus, BatchRenderResult, BatchResults, Client, Error, GenerateVideoTemplateResult, GifRenderResult, ImageResult, ListTemplatesResult, NetworkError, Pagination, QuotaExceededError, RateLimitError, RenderError, RenderErrorEntry, RenderResult, RenderResultItem, ServerError, Template, TemplateNotFoundError, TemplateVariableDefinition, TimeoutError, VideoRenderResult, VideoTemplate, VideoTemplateVariables

Constant Summary collapse

FORMATS =

Image output formats supported by Pictify renders.

The /image endpoint accepts these via format (mapped to fileExtension); template renders accept them via format (including pdf).

%i[png jpg jpeg webp pdf].freeze
GIF_QUALITIES =

GIF quality presets accepted by the /gif endpoint.

%i[low medium high].freeze
VIDEO_FORMATS =

Video output formats supported by video template renders.

gif produces a palette-optimised animated GIF capped at 15fps / 720px wide — the same render, encoded for places an MP4 cannot autoplay.

%i[mp4 gif].freeze
VERSION =
"1.1.0"

Class Method Summary collapse

Class Method Details

.error_from_response(status_code, body) ⇒ Object

Map an HTTP error response to a typed Pictify error.

The Pictify API has no unified error envelope: image/GIF endpoints return { error, code } while template/CRUD endpoints return { message } or { message, errors }. Message precedence is error then message then the joined errors strings (the video compile gate's 422 shape, where the strings are the fix instructions) then a fallback.

Status mapping:

- 401            -> AuthenticationError
- 402            -> QuotaExceededError
- 404            -> TemplateNotFoundError
- 422            -> RenderError (validation; includes +errors+)
- 429            -> QuotaExceededError when code == "quota_exceeded", else RateLimitError
- other 4xx      -> RenderError
- 5xx            -> ServerError


144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/pictify/errors.rb', line 144

def self.error_from_response(status_code, body)
  body ||= {}
  # The video compile gate returns 422 { errors: ["..."] } with no
  # message/error key — those strings ARE the fix instructions, so they
  # join into the message rather than leaving a generic fallback.
  errors = body["errors"]
  joined_errors = if errors.is_a?(Array) && !errors.empty? && errors.all? { |e| e.is_a?(String) }
                    errors.join("; ")
                  end
  message = body["error"] || body["message"] || joined_errors || "An unexpected error occurred"

  case status_code
  when 401
    AuthenticationError.new(message, status_code: status_code, response_body: body)
  when 402
    QuotaExceededError.new(message, status_code: status_code, response_body: body)
  when 404
    TemplateNotFoundError.new(message, status_code: status_code, response_body: body)
  when 422
    RenderError.new(message, status_code: status_code, response_body: body, errors: body["errors"])
  when 429
    if body["code"] == "quota_exceeded"
      QuotaExceededError.new(message, status_code: status_code, response_body: body)
    else
      RateLimitError.new(message, status_code: status_code, response_body: body, retry_after: body["retry_after"])
    end
  else
    if status_code >= 500
      ServerError.new(message, status_code: status_code, response_body: body)
    else
      RenderError.new(message, status_code: status_code, response_body: body, errors: body["errors"])
    end
  end
end