Golang SDK for Spice.ai
See Go Docs at pkg.go.dev/github.com/spiceai/gospice/v8.
For full documentation visit docs.spice.ai.
- Get the gospice package.
go get github.com/spiceai/gospice/v8@latest- Import the package.
import "github.com/spiceai/gospice/v8"- Create a SpiceClient passing in your API key. Get your free API key at spice.ai.
spice := NewSpiceClient()
defer spice.Close()- Initialize the SpiceClient with spice.ai cloud.
if err := spice.Init(
spice.WithApiKey(ApiKey),
spice.WithSpiceCloudAddress()
); err != nil {
panic(fmt.Errorf("error initializing SpiceClient: %w", err))
}- Execute a query and get back an Apache Arrow Reader.
reader, err := spice.Query(context.Background(), "SELECT 1")
if err != nil {
panic(fmt.Errorf("error querying: %w", err))
}
defer reader.Release()- Iterate through the reader to access the records.
for reader.Next() {
record := reader.RecordBatch()
defer record.Release()
fmt.Println(record)
}gospice v8 supports parameterized queries using ADBC (Arrow Database Connectivity), which is the recommended approach for queries with parameters to prevent SQL injection:
// Query with a single parameter
reader, err := spice.SqlWithParams(
context.Background(),
"SELECT * FROM tpch.customer WHERE c_custkey > $1 LIMIT 10",
100,
)
if err != nil {
panic(fmt.Errorf("error querying: %w", err))
}
defer reader.Release()
for reader.Next() {
record := reader.RecordBatch()
defer record.Release()
fmt.Println(record)
}Query with multiple parameters:
reader, err := spice.SqlWithParams(
context.Background(),
"SELECT * FROM taxi_trips WHERE trip_distance > $1 AND fare_amount > $2 LIMIT 100",
5.0,
20.0,
)
if err != nil {
panic(fmt.Errorf("error querying: %w", err))
}
defer reader.Release()Supported parameter types with automatic type inference:
- Integers:
int,int8,int16,int32,int64,uint,uint8,uint16,uint32,uint64 - Floating point:
float32,float64 - String:
string - Boolean:
bool - Binary:
[]byte - Null values:
nil
Typed Parameters for Advanced Use Cases:
For precise control over Arrow types, use typed parameter constructors:
import "github.com/spiceai/gospice/v8"
// Explicit type control for complex scenarios
reader, err := spice.SqlWithParams(
ctx,
"SELECT * FROM data WHERE id = $1 AND amount = $2 AND active = $3",
gospice.Int64Param(12345), // Explicitly int64
gospice.Decimal128Param(...), // Decimal with precision
gospice.BoolParam(true), // Explicitly boolean
)Available typed parameter constructors:
- Integers:
Int8Param,Int16Param,Int32Param,Int64Param,Uint8Param,Uint16Param,Uint32Param,Uint64Param - Floating point:
Float16Param,Float32Param,Float64Param - Strings:
StringParam,LargeStringParam - Binary:
BinaryParam,LargeBinaryParam,FixedSizeBinaryParam - Boolean:
BoolParam - Date/Time:
Date32Param,Date64Param,Time32Param,Time64Param,TimestampParam,DurationParam - Intervals:
MonthIntervalParam,DayTimeIntervalParam,MonthDayNanoIntervalParam - Decimals:
Decimal128Param,Decimal256Param - Null:
NullParam
Or use the generic constructors:
NewParam(value)- Creates a parameter with automatic type inferenceNewTypedParam(value, arrowType)- Creates a parameter with explicit Arrow type
Follow the quickstart guide to install and run spice locally
Initialize the SpiceClient to use local runtime connection:
if err := spice.Init(); err != nil {
panic(fmt.Errorf("error initializing SpiceClient: %w", err))
}Configure with a custom flight address:
if err := spice.Init(
spice.WithFlightAddress("grpc://localhost:50052")
); err != nil {
panic(fmt.Errorf("error initializing SpiceClient: %w", err))
}gospice v8 provides health check methods to verify Spice instance status before executing queries:
// Check if Spice instance is healthy (unauthenticated)
ctx := context.Background()
if !spice.IsSpiceHealthy(ctx) {
log.Println("Spice instance is not healthy")
return
}
// Check if Spice Cloud is ready (requires API key)
if !spice.IsSpiceReady(ctx) {
log.Println("Spice Cloud is not ready or API key is invalid")
return
}IsSpiceHealthy(ctx)- Calls/healthendpoint (unauthenticated)IsSpiceReady(ctx)- Calls/v1/readyendpoint (requires API key)
Run go run . to execute a sample query and print the results to the console.
See query_test.go for examples on querying TPC-H and taxi trips datasets.
The SpiceClient implements connection retry mechanism (3 attempts by default).
The number of attempts can be configured via SetMaxRetries:
spice := NewSpiceClient()
spice.SetMaxRetries(5) // Setting to 0 will disable retriesRetries are performed for connection and system internal errors. It is the SDK user's responsibility to properly handle other errors, for example RESOURCE_EXHAUSTED (HTTP 429).
gospice v8 is fully backward compatible with v7. To upgrade:
go get github.com/spiceai/gospice/v8@latest
go mod tidyUpdate your imports:
// Before
import "github.com/spiceai/gospice/v7"
// After
import "github.com/spiceai/gospice/v8"What's new in v8:
- New
Sql()andSqlWithParams()methods for cleaner API (.Query()methods still work for backward compatibility) IsSpiceHealthy()andIsSpiceReady()health check methods- Apache Arrow v18 and Go 1.24 support
See UPGRADE_V7_TO_V8.md for detailed migration guide.
Run all tests:
go test ./...Run tests with verbose output:
go test -v ./...Run specific test suites:
# Local runtime tests only
go test -v -run="TestLocal"
# Cloud tests only
go test -v -run="TestCloud"
# ADBC tests only
go test -v -run="TestADBC"Run all benchmarks:
go test -bench=. -benchmemRun specific benchmarks:
# Benchmark query performance
go test -bench=BenchmarkQuery -benchmem
# Benchmark parameterized queries
go test -bench=BenchmarkQueryWithParams -benchmem
# Benchmark health checks
go test -bench=BenchmarkHealthChecks -benchmem
# Benchmark client initialization
go test -bench=BenchmarkClientInitialization -benchmemRun benchmarks with custom settings:
# Run for 10 seconds each
go test -bench=. -benchtime=10s
# Run with CPU profiling
go test -bench=. -cpuprofile=cpu.prof
# Run with memory profiling
go test -bench=. -memprofile=mem.profAvailable benchmarks:
BenchmarkCloudQuery- Basic query performance against Spice CloudBenchmarkCloudQueryWithParams- Parameterized query performance (Cloud)BenchmarkLocalQuery- Query performance against local runtimeBenchmarkLocalQueryWithParams- Parameterized query performance (Local)BenchmarkParameterBinding- Parameter binding overhead with varying parameter countsBenchmarkClientInitialization- Client initialization overheadBenchmarkHealthChecks- Health check endpoint performanceBenchmarkRecordProcessing- Different record processing patterns