pictomancer

package module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 19, 2026 License: MIT Imports: 10 Imported by: 0

README

pictomancer go-sdk

Go SDK for Pictomancer.ai - a thin client for the REST API at https://api.pictomancer.ai, built on withttp.

Install

go get github.com/pictomancer/go-sdk

Usage

package main

import (
	"context"
	"os"

	pictomancer "github.com/pictomancer/go-sdk"
)

func main() {
	client := pictomancer.NewClient(
		pictomancer.WithAPIKey("your-api-key"),
	)
	ctx := context.Background()

	info, err := client.Info(ctx)
	if err != nil {
		panic(err)
	}
	_ = info

	meta, err := client.Analyze(ctx, "https://example.com/image.jpg")
	if err != nil {
		panic(err)
	}
	_ = meta.SizeBytes

	result, err := client.Compress(ctx, "https://example.com/image.jpg", pictomancer.CompressParams{
		Format: "webp",
		Q:      80,
		Strip:  true,
	})
	if err != nil {
		panic(err)
	}
	if err := os.WriteFile("out.webp", result.Bytes, 0o644); err != nil {
		panic(err)
	}
}

Sources can be an image URL, a base64 string, or a data: URI. For local files, readers, or in-memory bytes:

source, err := pictomancer.SourceFromPath("photo.jpg")
source, err = pictomancer.SourceFromReader(file)
source = pictomancer.SourceFromBytes(data)

Timeouts and cancellation flow through context.Context.

Operations
client.Info(ctx)
client.Usage(ctx)
client.Analyze(ctx, source)
client.Resize(ctx, source, pictomancer.ResizeParams{Scale: 0.5, Format: "webp"})
client.Compress(ctx, source, pictomancer.CompressParams{Q: 80})
client.Convert(ctx, source, "avif", pictomancer.ConvertParams{Q: 50, Effort: pictomancer.Int(2)})
client.Crop(ctx, source, 0, 0, 100, 100, pictomancer.CropParams{Format: "png"})
client.Pipeline(ctx, source, []pictomancer.PipelineOperation{
	{Type: "resize", Params: map[string]string{"scale": "0.5"}},
	{Type: "convert", Params: map[string]string{"format": "webp"}},
}, nil)

Operations return an OpResult: Bytes holds the optimized image for inline delivery, Receipt holds the JSON receipt for put_url/callback deliveries.

Delivery targets
// Presigned PUT (S3/R2/GCS/Azure). No cloud credentials reach Pictomancer.
result, err := client.Compress(ctx, source, pictomancer.CompressParams{
	Format:   "webp",
	Delivery: pictomancer.NewPutURLDelivery(presignedURL),
})

// POST to your endpoint, HMAC-signed (X-Pig-Signature: sha256=<hex>).
result, err = client.Convert(ctx, source, "avif", pictomancer.ConvertParams{
	Delivery: pictomancer.NewCallbackDelivery(
		"https://hooks.example.com/pig?token=...",
		pictomancer.WithDeliverySecret(secret),
	),
})
Options
pictomancer.WithAPIKey("...")        // Bearer token
pictomancer.WithBaseURL("...")       // defaults to https://api.pictomancer.ai
pictomancer.WithAgentWallet("0x...") // X-Agent-Wallet for x402 tracking
pictomancer.WithAdapter(withttp.Fasthttp()) // swap the HTTP backend
Errors

Non-2xx responses return *pictomancer.APIError:

var apiErr *pictomancer.APIError
if errors.As(err, &apiErr) && apiErr.Status == 402 {
	// free tier exhausted: pay per request (x402) or use an API key
}

Development

go test ./...

License

MIT

Documentation

Index

Constants

View Source
const DefaultBaseURL = "https://api.pictomancer.ai"
View Source
const Version = "0.2.0"

Variables

This section is empty.

Functions

func Int

func Int(v int) *int

Int returns a pointer to v, for optional int params such as ConvertParams.Effort.

func SourceFromBytes added in v0.2.0

func SourceFromBytes(data []byte) string

SourceFromBytes encodes in-memory image bytes as the raw base64 source string the API accepts.

func SourceFromPath added in v0.2.0

func SourceFromPath(path string) (string, error)

SourceFromPath reads a local image file and encodes it.

func SourceFromReader added in v0.2.0

func SourceFromReader(r io.Reader) (string, error)

SourceFromReader reads the whole image from r and encodes it.

Types

type APIError

type APIError struct {
	Status int
	Detail string
}

APIError is returned for any non-2xx response from the API.

func (*APIError) Error

func (e *APIError) Error() string

type AnalyzeResponse

type AnalyzeResponse struct {
	SizeBytes int64 `json:"size_bytes"`
}

AnalyzeResponse is the metadata of a fetched image. Always free.

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client is a thin client for the Pictomancer.ai REST API.

func NewClient

func NewClient(opts ...Option) *Client

func (*Client) Analyze

func (c *Client) Analyze(ctx context.Context, source string) (AnalyzeResponse, error)

func (*Client) Compress

func (c *Client) Compress(ctx context.Context, source string, params CompressParams) (OpResult, error)

func (*Client) Convert

func (c *Client) Convert(ctx context.Context, source, format string, params ConvertParams) (OpResult, error)

func (*Client) Crop

func (c *Client) Crop(ctx context.Context, source string, x, y, width, height int, params CropParams) (OpResult, error)

func (*Client) Info

func (c *Client) Info(ctx context.Context) (InfoResponse, error)

func (*Client) Pipeline

func (c *Client) Pipeline(ctx context.Context, source string, operations []PipelineOperation, delivery *Delivery) (OpResult, error)

func (*Client) Resize

func (c *Client) Resize(ctx context.Context, source string, params ResizeParams) (OpResult, error)

func (*Client) Usage

func (c *Client) Usage(ctx context.Context) (UsageResponse, error)

type CompressParams

type CompressParams struct {
	Format   string         `json:"format,omitempty"`
	Q        int            `json:"q,omitempty"`
	Strip    bool           `json:"strip,omitempty"`
	Extra    map[string]any `json:"-"`
	Delivery *Delivery      `json:"delivery,omitempty"`
}

CompressParams tunes the compress operation. Zero values are omitted.

type ConvertParams

type ConvertParams struct {
	Q        int            `json:"q,omitempty"`
	Strip    bool           `json:"strip,omitempty"`
	Lossless bool           `json:"lossless,omitempty"`
	Effort   *int           `json:"effort,omitempty"`
	Extra    map[string]any `json:"-"`
	Delivery *Delivery      `json:"delivery,omitempty"`
}

ConvertParams tunes the convert operation. Zero values are omitted. Effort is a pointer because 0 is a valid AVIF encoder value distinct from unset (API default 2); use Int to build it.

type CropParams

type CropParams struct {
	Format   string         `json:"format,omitempty"`
	Extra    map[string]any `json:"-"`
	Delivery *Delivery      `json:"delivery,omitempty"`
}

CropParams tunes the crop operation. Zero values are omitted.

type Delivery

type Delivery struct {
	Mode        string            `json:"mode"`
	PutURL      string            `json:"put_url,omitempty"`
	CallbackURL string            `json:"callback_url,omitempty"`
	Headers     map[string]string `json:"headers,omitempty"`
	Secret      string            `json:"secret,omitempty"`
}

Delivery selects where the optimized bytes go. Inline (the default) returns them in the response; put_url uploads to a customer-signed presigned PUT URL; callback_url POSTs them to a customer endpoint with an X-Pig-Sha256 integrity header and optional HMAC signature.

func NewCallbackDelivery

func NewCallbackDelivery(url string, opts ...DeliveryOption) *Delivery

func NewInlineDelivery

func NewInlineDelivery() *Delivery

func NewPutURLDelivery

func NewPutURLDelivery(url string, opts ...DeliveryOption) *Delivery

type DeliveryOption

type DeliveryOption func(*Delivery)

func WithDeliveryHeaders

func WithDeliveryHeaders(headers map[string]string) DeliveryOption

WithDeliveryHeaders forwards extra signed headers (x-amz-*, x-goog-*, x-ms-*) that the presigned URL or endpoint expects.

func WithDeliverySecret

func WithDeliverySecret(secret string) DeliveryOption

WithDeliverySecret enables HMAC-SHA256 signing of callback bodies: the request carries X-Pig-Signature: sha256=<hex>, recomputable on the receiving end with the same secret. Used per request, never stored.

type FormatOption

type FormatOption struct {
	Name        string `json:"name"`
	Kind        string `json:"kind"`
	DefaultStr  string `json:"default_str"`
	Description string `json:"description"`
	Min         *int   `json:"min,omitempty"`
	Max         *int   `json:"max,omitempty"`
}

FormatOption describes one tunable knob of an output format.

type FormatSpec

type FormatSpec struct {
	ID      string         `json:"id"`
	Suffix  string         `json:"suffix"`
	Options []FormatOption `json:"options"`
}

FormatSpec describes one output format (id, file suffix, options).

type InfoResponse

type InfoResponse struct {
	Formats []FormatSpec `json:"formats"`
}

InfoResponse lists the supported output formats and their options.

type OpResult

type OpResult struct {
	Bytes   []byte
	Receipt map[string]any
}

OpResult is the outcome of an image operation. Exactly one field is populated: Bytes for inline delivery, Receipt (etag, sha256, bytes_written, ...) for put_url/callback deliveries.

type Option

type Option func(*Client)

func WithAPIKey

func WithAPIKey(key string) Option

WithAPIKey sets the Bearer token (Authorization: Bearer ...).

func WithAdapter

func WithAdapter(adapter withttp.Client) Option

WithAdapter swaps the HTTP backend (e.g. withttp.Fasthttp()). Defaults to net/http.

func WithAgentWallet

func WithAgentWallet(wallet string) Option

WithAgentWallet sets the X-Agent-Wallet identity for x402 tracking.

func WithBaseURL

func WithBaseURL(url string) Option

WithBaseURL overrides the default https://api.pictomancer.ai.

type PipelineOperation

type PipelineOperation struct {
	Type   string            `json:"type"`
	Params map[string]string `json:"params"`
}

PipelineOperation is one step of a multi-op pipeline. Params values are strings, matching the API contract (e.g. {"scale": "0.5"}).

type ResizeParams

type ResizeParams struct {
	Scale    float64        `json:"scale,omitempty"`
	ScaleX   float64        `json:"scale_x,omitempty"`
	ScaleY   float64        `json:"scale_y,omitempty"`
	Format   string         `json:"format,omitempty"`
	Extra    map[string]any `json:"-"`
	Delivery *Delivery      `json:"delivery,omitempty"`
}

ResizeParams tunes the resize operation. Zero values are omitted. Use Scale for uniform scaling or ScaleX/ScaleY for independent axes.

type UsageResponse

type UsageResponse struct {
	Identity      string `json:"identity"`
	RequestsUsed  int    `json:"requests_used"`
	FreeTierLimit int    `json:"free_tier_limit"`
	FreeRemaining int    `json:"free_remaining"`
	IsFree        bool   `json:"is_free"`
}

UsageResponse reports request usage and free tier status for the caller's identity (wallet header or IP fallback).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL