Howto

How to Run the Sandbox

Run a local DynamoDB environment with LocalStack for Sluice development and testing.

The Sluice sandbox runs a DynamoDB-compatible environment locally using LocalStack in Docker. It seeds vendor buckets so you can develop and test without AWS credentials.

Prerequisites

  • Docker (Docker Desktop or colima)
  • Docker Compose (included with Docker Desktop)
  • awslocal CLI (installed via pip install awscli-local or available in the LocalStack container)
  • Task runner (task --list to verify)

Commands

CommandWhat it does
task sandbox:startStart LocalStack, create the DynamoDB table, seed vendor buckets
task sandbox:stopStop LocalStack and remove volumes
task sandbox:resetStop, remove, restart, and reseed -- clean slate

Starting the sandbox

task sandbox:start

This runs docker compose up for LocalStack and then executes sandbox/init.sh, which creates the DynamoDB table and seeds it with vendor buckets.

Stopping the sandbox

task sandbox:stop

Stops LocalStack and removes volumes. All data is lost.

Resetting to a clean state

task sandbox:reset

Equivalent to stop + start. Use this after editing sandbox/init.sh (e.g., adding a new vendor bucket).

Seeded buckets

The sandbox comes with three pre-configured vendor buckets:

DimensionCapacityRefill rateCost per callLimit type
openai#rpm5008.333/s1requests
openai#tpm200,0003,333.33/s100tokens
elevenlabs#concurrent501concurrent

These mirror the Terraform-managed buckets in .infra/vendors.tf.

Connecting from each SDK

Set these environment variables to point the SDK at LocalStack instead of AWS:

export SLUICE_TABLE_NAME=ontopix-vendor-buckets-sandbox
export SLUICE_ENDPOINT_URL=http://localhost:4566
export SLUICE_AWS_REGION=eu-central-1

Python

from sluice import SluiceConfig, slot

# Option 1: environment variables (set the exports above)
async with slot("openai#rpm", timeout=10) as s:
    print(f"Slot acquired: {s.lease_id}")

# Option 2: explicit config
config = SluiceConfig(
    table_name="ontopix-vendor-buckets-sandbox",
    endpoint_url="http://localhost:4566",
    region="eu-central-1",
)
async with slot("openai#rpm", timeout=10, config=config) as s:
    print(f"Slot acquired: {s.lease_id}")

TypeScript

import { slot } from "@ontopix/sluice";

// Environment variables are read automatically
const result = await slot("openai#rpm", { timeout: 10 });

Go

import "github.com/ontopix/sluice/go"

// Environment variables are read automatically
err := sluice.WithSlot(ctx, "openai#rpm", 10*time.Second, func(ctx context.Context) error {
    fmt.Println("Slot acquired")
    return nil
})

Adding custom test buckets

You can add temporary buckets directly via awslocal without modifying sandbox/init.sh:

awslocal dynamodb put-item \
  --table-name "ontopix-vendor-buckets-sandbox" \
  --item '{
    "vendor_dimension": {"S": "test-vendor#rpm"},
    "capacity": {"N": "10"},
    "refill_rate": {"N": "0.167"},
    "tokens": {"N": "10"},
    "last_refill_at": {"N": "0"},
    "cost_per_call": {"N": "1"},
    "limit_type": {"S": "requests"},
    "version": {"N": "0"}
  }' \
  --region "eu-central-1"

These buckets survive until task sandbox:stop or task sandbox:reset.

To make a custom bucket permanent, add it to both sandbox/init.sh and .infra/vendors.tf (see How to Add a Vendor).

Inspecting table contents

awslocal dynamodb scan \
  --table-name "ontopix-vendor-buckets-sandbox" \
  --region "eu-central-1"

Running tests against the sandbox

Integration and contract tests expect the sandbox to be running:

task sandbox:start
task py:test:integration
task py:test:contract
task ts:test:contract
task go:test:contract

Or run all tests across all SDKs:

task test:all