Installation & configuration
This is the canonical home for install + Shipeasy.configure. Snippets elsewhere assume configure already ran at boot; this page is where it lives.
Generated from the SDK's own /docs/ — also served raw at
https://shipeasy-ai.github.io/sdk-ruby/pages/installation.md.
This is the canonical home for install + Shipeasy.configure. Snippets
elsewhere assume configure already ran at boot; this page is where it lives.
This is a server SDK: it authenticates with your server key and must never be embedded in a browser.
Add the gem
# Gemfile
gem "shipeasy-sdk"bundle installOr without Bundler:
gem install shipeasy-sdkThe gem is pure Ruby (no native extensions) and runs on Ruby 3.0+. Rails is optional — when Rails is loaded the gem auto-mounts a Railtie that registers the i18n view helpers and the anon-id Rack middleware. Outside Rails (Sinatra / Hanami / scripts) it pulls in no web framework.
Optional: OpenFeature
The OpenFeature provider needs the openfeature-sdk gem (Ruby ≥ 3.4). Add it
only if you use Shipeasy::OpenFeature::Provider — see openfeature.
Keys
- Server key (
SHIPEASY_SERVER_KEY) — authenticates flag / experiment / config evaluation and metric ingestion. Set it asc.api_key. - Client (public) key (
SHIPEASY_CLIENT_KEY) — only needed for the i18n view helpers and the SSR i18n loader tag. Set it asc.public_key.
The SDK reads no env vars itself — you wire them through configure.
Shipeasy.configure — once per process
Call Shipeasy.configure once at startup, then construct a cheap,
user-bound Shipeasy::Client.new(user) per request — every read takes no user
argument because the user is bound at construction.
Shipeasy.configure do |c|
c.api_key = ENV.fetch("SHIPEASY_SERVER_KEY") # required — server key, never a browser
# Optional: map YOUR user object → the Shipeasy attribute hash. Runs once,
# in the Shipeasy::Client constructor. Omit it and the object you pass to
# Shipeasy::Client.new IS the attribute hash (identity default).
c.attributes = ->(u) { { "user_id" => u.id, "plan" => u.plan } }
# i18n view helpers only (see the i18n page):
c.public_key = ENV.fetch("SHIPEASY_CLIENT_KEY") # public client key
c.profile = "default" # i18n locale profile
end-
c.api_key(required) — your Shipeasy server key. Authenticates flags, configs, kill switches and experiments. Read it from the environment; never hard-code it. -
c.attributes(optional) — a transform from YOUR user object to the Shipeasy attribute hash that targeting evaluates against. The default is identity, so if your user object is already that hash you can omit it:Shipeasy::Client.new({ "user_id" => "u_1", "plan" => "pro" }).get_flag("new_checkout")
One-shot vs background poll
configure is first-config-wins: the first call wires everything up; later calls
are a no-op.
-
default (
c.init = true) — fire a one-shot fetch fire-and-forget so the firstShipeasy::Client.new(user).get_flag(...)resolves against real rules. Ideal for serverless / short-lived processes — no poll thread is spawned. -
c.poll = true— for a long-running server, start the background poll (initial fetch + periodic refresh, 30 s default /X-Poll-Intervalheader) so flags stay fresh without a redeploy. Configuration owns the lifecycle:Shipeasy.configure { |c| c.api_key = ENV.fetch("SHIPEASY_SERVER_KEY"); c.poll = true }
configure options
| option | default | what it does |
|---|---|---|
api_key | (required) | Server SDK key. Authenticates evaluation + ingestion. |
attributes | identity | Callable mapping your user object → the Shipeasy attribute hash. |
init | true | Fire the one-shot fetch fire-and-forget. |
poll | false | Start the background poll (refreshes the blob over time). |
base_url | https://edge.shipeasy.dev | API base URL for the blobs. Override for local dev / staging. |
env | "prod" | Deployment environment tag, attached to see() events + usage telemetry. |
disable_telemetry | false | Opt out of per-evaluation usage telemetry. Evaluation itself is unaffected. |
telemetry_url | built-in | Override the telemetry endpoint (rarely needed). |
private_attributes | nil | Attribute keys stripped from every outbound event before it leaves the process. They still drive targeting locally. See advanced. |
sticky_store | nil | Pin a user's experiment group across re-buckets. See advanced. |
public_key | (none) | Public client key — for the i18n view helpers / loader tag only. |
profile | "default" | i18n locale profile read by the view helpers. |
# example: staging env, telemetry off, redact `email`, background poll
Shipeasy.configure do |c|
c.api_key = ENV.fetch("SHIPEASY_SERVER_KEY")
c.env = "staging"
c.disable_telemetry = true
c.private_attributes = ["email", "ip"]
c.poll = true
endIdentity default. The attribute hash you produce is the unit of identity —
supply user_id for logged-in users, or let the anon-id middleware (below)
inject anonymous_id for logged-out traffic. An explicit user_id /
anonymous_id always wins. Constructing Shipeasy::Client.new(user) before
configure raises Shipeasy::Error.
Rails
Generator (recommended)
The gem ships a Rails generator that scaffolds the install for you:
bin/rails generate shipeasy:installIt creates config/initializers/shipeasy.rb (server key from the environment,
background poll on), then prints the keys / Rails-credentials next steps. Add
--i18n to also set the public client key and inject <%= i18n_head_tags %>
into your application layout's <head>; add --no-poll for a serverless
one-shot fetch:
bin/rails generate shipeasy:install --i18n # also wires the i18n view helpers
bin/rails generate shipeasy:install --no-poll # serverless one-shot fetchYou never wire middleware by hand — the gem's Railties already mount the anon-id Rack middleware and the i18n view helpers. The generator only creates what your app owns: the initializer, the (optional) layout tag, and a reminder to set your keys.
Manual
Or write the initializer yourself — Bundler requires the gem automatically, so
all you need is an initializer that calls Shipeasy.configure:
# config/initializers/shipeasy.rb
Shipeasy.configure do |c|
c.api_key = ENV.fetch("SHIPEASY_SERVER_KEY")
c.attributes = ->(u) { { "user_id" => u.id, "plan" => u.plan } }
c.poll = true # background poll for a persistent server
c.public_key = ENV.fetch("SHIPEASY_CLIENT_KEY") # for i18n view helpers
c.profile = "default"
endThen in a controller / anywhere per request:
flags = Shipeasy::Client.new(current_user) # runs the attributes transform once
flags.get_flag("new_checkout") # NO user arg — bound at constructionThe Railtie mounts the i18n view helpers and Shipeasy::SDK::RackMiddleware
(which mints the shared __se_anon_id cookie for anonymous bucketing) with no
extra wiring. In a Rails view:
<%= i18n_head_tags %>
<h1><%= i18n_t("hero.title", name: current_user.name) %></h1>Sinatra / Hanami / bare Rack
No Railtie here, so configure in your app file and mount the anon-id middleware yourself for zero-config anonymous bucketing.
require "shipeasy-sdk"
Shipeasy.configure { |c| c.api_key = ENV.fetch("SHIPEASY_SERVER_KEY"); c.poll = true }
class App < Sinatra::Base
use Shipeasy::SDK::RackMiddleware # mints __se_anon_id for logged-out traffic
get "/" do
flags = Shipeasy::Client.new(current_user || {})
flags.get_flag("new_checkout") ? "new" : "old"
end
endThe i18n view helpers (i18n_*) are not loaded outside Rails, so the gem does
not pull Rails into a Sinatra/Hanami app.
Plain Ruby / scripts
Same pattern, just without config/initializers:
require "shipeasy-sdk"
Shipeasy.configure { |c| c.api_key = ENV.fetch("SHIPEASY_SERVER_KEY") }
# With no `attributes` transform, the hash you pass IS the attribute map.
Shipeasy::Client.new({ "user_id" => "u_1" }).get_flag("new_checkout")Serverless / Lambda / Cloud Run
The default configure (one-shot fetch, no poll thread) is already
serverless-friendly: the fetch is fire-and-forget and no background thread is
spawned. Just leave c.poll off (its default).
Shipeasy.configure { |c| c.api_key = ENV.fetch("SHIPEASY_SERVER_KEY") } # c.poll defaults to false
Shipeasy::Client.new(user).get_flag("new_checkout")Tests and offline
For unit tests and offline evaluation, swap configure for one of its drop-in
siblings — no api key, no network — then read through the same
Shipeasy::Client.new(user):
# unit tests: seed values, zero network
Shipeasy.configure_for_testing(flags: { "new_checkout" => true })
# offline: evaluate the real rules from a snapshot / file
Shipeasy.configure_for_offline(path: "shipeasy-snapshot.json")See testing for the full override args.
Next: configuration deep-dive · flags · experiments · i18n.
Shipeasy Ruby SDK — Overview
shipeasy-sdk is the server-side Ruby gem for the Shipeasy hosted service: feature gates (flags), dynamic configs, kill switches, A/B experiments, metric…
Configuration
```ruby config/initializers/shipeasy.rb Shipeasy.configure do |c| c.apikey = ENV.fetch("SHIPEASYSERVERKEY") c.attributes = -(u) { { "userid" = u.id, "plan"…