defmodule Pxshot do @moduledoc """ Official Elixir SDK for the Pxshot screenshot API. ## Configuration Configure your API key in `config/config.exs`: config :pxshot, api_key: "px_your_api_key" Or pass it directly when creating a client: client = Pxshot.client(api_key: "px_your_api_key") ## Usage # Take a screenshot {:ok, image_binary} = Pxshot.screenshot(client, url: "https://example.com") # Store screenshot and get URL {:ok, result} = Pxshot.screenshot(client, url: "https://example.com", store: true) IO.puts(result.url) # Check usage {:ok, usage} = Pxshot.usage(client) ## Bang Variants All functions have bang variants that raise on error: image = Pxshot.screenshot!(client, url: "https://example.com") """ alias Pxshot.{Client, Error, Response} @type client :: Client.t() @type screenshot_opt :: {:url, String.t()} | {:format, String.t()} | {:quality, integer()} | {:width, integer()} | {:height, integer()} | {:full_page, boolean()} | {:wait_until, String.t()} | {:wait_for_selector, String.t()} | {:wait_for_timeout, integer()} | {:device_scale_factor, number()} | {:store, boolean()} | {:block_ads, boolean()} @doc """ Creates a new Pxshot client. ## Options * `:api_key` - Your Pxshot API key (required unless configured globally) * `:base_url` - API base URL (default: "https://api.pxshot.com") * `:timeout` - Request timeout in milliseconds (default: 30_000) ## Examples # Using global config client = Pxshot.client() # With explicit API key client = Pxshot.client(api_key: "px_your_api_key") # With custom options client = Pxshot.client(api_key: "px_key", timeout: 60_000) """ @spec client(keyword()) :: client() def client(opts \\ []) do Client.new(opts) end @doc """ Takes a screenshot of the given URL. ## Options * `:url` - URL to screenshot (required) * `:format` - Image format: "png", "jpeg", "webp" (default: "png") * `:quality` - JPEG/WebP quality 1-100 (default: 80) * `:width` - Viewport width in pixels (default: 1920) * `:height` - Viewport height in pixels (default: 1080) * `:full_page` - Capture full scrollable page (default: false) * `:wait_until` - Wait condition: "load", "domcontentloaded", "networkidle" (default: "load") * `:wait_for_selector` - CSS selector to wait for before capture * `:wait_for_timeout` - Additional wait time in ms after page load * `:device_scale_factor` - Device scale factor for retina (default: 1) * `:store` - Store image and return URL instead of binary (default: false) * `:block_ads` - Block ads and trackers (default: false) ## Returns * `{:ok, binary}` - Image data when `store: false` * `{:ok, %Pxshot.Response.StoredScreenshot{}}` - When `store: true` * `{:error, %Pxshot.Error{}}` - On failure ## Examples # Basic screenshot {:ok, png_data} = Pxshot.screenshot(client, url: "https://example.com") # Full page JPEG {:ok, jpeg_data} = Pxshot.screenshot(client, url: "https://example.com", format: "jpeg", quality: 90, full_page: true ) # Store and get URL {:ok, result} = Pxshot.screenshot(client, url: "https://example.com", store: true) IO.puts(result.url) """ @spec screenshot(client(), [screenshot_opt()]) :: {:ok, binary() | Response.StoredScreenshot.t()} | {:error, Error.t()} def screenshot(client, opts) do Client.screenshot(client, opts) end @doc """ Takes a screenshot, raising on error. See `screenshot/2` for options. """ @spec screenshot!(client(), [screenshot_opt()]) :: binary() | Response.StoredScreenshot.t() def screenshot!(client, opts) do case screenshot(client, opts) do {:ok, result} -> result {:error, error} -> raise error end end @doc """ Gets current usage statistics. ## Returns * `{:ok, %Pxshot.Response.Usage{}}` - Usage statistics * `{:error, %Pxshot.Error{}}` - On failure ## Examples {:ok, usage} = Pxshot.usage(client) IO.puts("Used \#{usage.screenshots_used} of \#{usage.screenshots_limit} screenshots") """ @spec usage(client()) :: {:ok, Response.Usage.t()} | {:error, Error.t()} def usage(client) do Client.usage(client) end @doc """ Gets current usage statistics, raising on error. """ @spec usage!(client()) :: Response.Usage.t() def usage!(client) do case usage(client) do {:ok, result} -> result {:error, error} -> raise error end end @doc """ Checks API health status. ## Returns * `{:ok, %Pxshot.Response.Health{}}` - Health status * `{:error, %Pxshot.Error{}}` - On failure ## Examples {:ok, health} = Pxshot.health(client) if health.status == "ok", do: IO.puts("API is healthy!") """ @spec health(client()) :: {:ok, Response.Health.t()} | {:error, Error.t()} def health(client) do Client.health(client) end @doc """ Checks API health status, raising on error. """ @spec health!(client()) :: Response.Health.t() def health!(client) do case health(client) do {:ok, result} -> result {:error, error} -> raise error end end end