Calco

Ruby

The Ruby connector uses only the standard library (net/http). Render methods return the raw document bytes as a string.

Add the connector

There's no published gem to install (yet) — the client is a single, standard-library-only file. Copy calco.rb into your project (for example under lib/) and require it:

ruby
require "calco"

If it isn't on the load path, use require_relative with the path to the file.

Quick start

ruby
require "calco"

client = Calco::Client.new("http://localhost:8080", api_key: "dc_live_...")

The key is sent as Authorization: Bearer <key> on every request.

Converting a file

ruby
pdf_bytes = client.convert(
  file:      "path/to/report.xlsx",
  format:    "pdf",
  data_json: '{"company": "Acme"}',
  sheet:     "Summary",
  title:     "Q4 Report"
)
File.binwrite("report.pdf", pdf_bytes)

Extract the placeholder map with scaffold:

ruby
scaffold = client.scaffold(file: "path/to/spreadsheet.xlsx")

Managing templates

ruby
# Create
template = client.create_template(
  file: "path/to/template.xlsx", name: "Invoice", category: "finance", tags: "billing,monthly")

# List
templates = client.list_templates
templates.each { |t| puts "#{t['id']}: #{t['name']}" }

# Update metadata
client.update_template(id: 42, name: "Invoice v2", category: "accounting", tags: "billing,quarterly")

# Add a new version
client.create_template_version(id: 42, file: "path/to/template_v2.xlsx")

# Delete
client.delete_template(id: 42)

Rendering a stored template

ruby
html_bytes = client.render_template_version(
  id:        42,
  version:   2,
  format:    "html",
  data_json: '{"customer": "Jane"}',
  sheet:     "Page1",
  title:     "Invoice #1001"
)
File.binwrite("invoice.html", html_bytes)

Batch rendering

Render multiple records into a single ZIP archive:

ruby
records = [
  { name: "Alice", amount: 100 },
  { name: "Bob",   amount: 200 }
]

zip_bytes = client.batch_render(
  records_json:   records.to_json,
  template_id:    42,
  version:        1,
  format:         "pdf",
  title_template: "invoice_{{name}}",
  sheet:          "Sheet1"
)
File.binwrite("invoices.zip", zip_bytes)

By-hash workflow

Every stored version exposes a content hash (sha256 of the file). Address a version directly by hash:

ruby
meta = client.get_template_by_hash("3c9f...d1ab")
pdf  = client.render_by_hash(hash: "3c9f...d1ab", format: "pdf", data_json: { customer: "Jane" }.to_json)
xlsx = client.download_by_hash(hash: "3c9f...d1ab", format: "xlsx")

Error handling

All errors raise Calco::Error, which includes the HTTP status when available:

ruby
begin
  client.convert(file: "missing.xlsx", format: "pdf")
rescue Calco::Error => e
  puts "Status: #{e.status}"
  puts "Message: #{e.message}"
end

Rails integration

Initializer

ruby
# config/initializers/calco.rb
Rails.application.config.calco = Calco::Client.new(
  ENV.fetch("CALCO_URL"),
  api_key: ENV["CALCO_API_KEY"],
  timeout: 180
)

Controller

ruby
class ReportsController < ApplicationController
  def export
    client   = Rails.application.config.calco
    pdf_data = client.convert(
      file:      params[:file].tempfile.path,
      format:    "pdf",
      data_json: report_params.to_json,
      title:     "Report #{Date.today}"
    )

    send_data pdf_data,
              filename:    "report.pdf",
              type:        "application/pdf",
              disposition: "attachment"
  end

  private

  def report_params
    params.require(:report).permit(:company, :quarter)
  end
end

Background job

ruby
class BatchRenderJob < ApplicationJob
  queue_as :default

  def perform(template_id, records)
    client = Rails.application.config.calco
    zip    = client.batch_render(
      records_json: records.to_json,
      template_id:  template_id,
      version:      1,
      format:       "pdf"
    )
    ActiveStorage::Blob.create_and_upload!(
      io:           StringIO.new(zip),
      filename:     "batch_#{template_id}.zip",
      content_type: "application/zip"
    )
  end
end

Configuration options

OptionDefaultDescription
base_url—Root URL of the service (required)
api_keynilBearer token for authentication
timeout120HTTP open/read timeout in seconds