Go SDK
The InstaVM Go SDK provides a robust, type-safe interface for interacting with the InstaVM API. It features automatic session management, comprehensive error handling, and context support for cancellation and timeouts.
Installation
go get github.com/instavm/instavm-go
Quick Start
package main
import (
"context"
"fmt"
"log"
"github.com/instavm/instavm-go"
)
func main() {
// Initialize with your API key
client := instavm.New("your_api_key_here")
defer client.Close()
// Execute code
ctx := context.Background()
result, err := client.Execute(ctx, "fmt.Println(\"Hello from InstaVM!\")")
if err != nil {
log.Fatal(err)
}
fmt.Println(result.Output)
}
Client Configuration
Basic Configuration
package main
import (
"time"
"github.com/instavm/instavm-go"
)
func main() {
// Default configuration
client := instavm.New("your_api_key")
// Custom configuration
client := instavm.NewWithOptions("your_api_key", instavm.Options{
BaseURL: "https://api.instavm.io", // Custom API endpoint
Timeout: 30 * time.Second, // Request timeout
})
defer client.Close()
}
Using Environment Variables
package main
import (
"os"
"github.com/instavm/instavm-go"
)
func main() {
// Set API key via environment variable
os.Setenv("INSTAVM_API_KEY", "your_api_key")
client := instavm.New(os.Getenv("INSTAVM_API_KEY"))
defer client.Close()
}
Core Methods
Execute(ctx, command)
Execute code synchronously on a virtual machine.
package main
import (
"context"
"fmt"
"log"
"github.com/instavm/instavm-go"
)
func main() {
client := instavm.New("your_api_key")
defer client.Close()
ctx := context.Background()
result, err := client.Execute(ctx, `
import "math"
result := math.Sqrt(16)
fmt.Printf("Square root of 16 is %.1f\n", result)
`)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Output: %s\n", result.Output) // Square root of 16 is 4.0
fmt.Printf("Execution time: %.3fs\n", result.ExecutionTime) // 0.123
}
UploadFile(ctx, filePath)
Upload a file to the virtual machine.
package main
import (
"context"
"fmt"
"log"
"github.com/instavm/instavm-go"
)
func main() {
client := instavm.New("your_api_key")
defer client.Close()
ctx := context.Background()
// Upload a file
result, err := client.UploadFile(ctx, "/path/to/local/file.txt")
if err != nil {
log.Fatal(err)
}
fmt.Printf("Uploaded %s, size: %d bytes\n", result.Filename, result.Size)
// Now execute code that uses the file
execResult, err := client.Execute(ctx, `
package main
import (
"fmt"
"io/ioutil"
)
func main() {
content, err := ioutil.ReadFile("file.txt")
if err != nil {
panic(err)
}
fmt.Println(string(content))
}
`)
if err != nil {
log.Fatal(err)
}
fmt.Println(execResult.Output)
}
GetUsage(ctx)
Get usage metrics for the current session.
package main
import (
"context"
"fmt"
"log"
"github.com/instavm/instavm-go"
)
func main() {
client := instavm.New("your_api_key")
defer client.Close()
ctx := context.Background()
// Execute some code first
_, err := client.Execute(ctx, "fmt.Println(\"Hello World\")")
if err != nil {
log.Fatal(err)
}
// Get usage metrics
usage, err := client.GetUsage(ctx)
if err != nil {
log.Fatal(err)
}
fmt.Printf("CPU Time: %.3fs\n", usage.CPUTime)
fmt.Printf("Memory Used: %d bytes\n", usage.MemoryUsed)
fmt.Printf("Network I/O: %d bytes\n", usage.NetworkIO)
}
Session Management
Automatic Session Management (Recommended)
package main
import (
"context"
"fmt"
"log"
"github.com/instavm/instavm-go"
)
func main() {
client := instavm.New("your_api_key")
// Session started automatically
defer client.Close() // Always close session
ctx := context.Background()
result, err := client.Execute(ctx, "fmt.Println(\"Session managed automatically\")")
if err != nil {
log.Fatal(err)
}
fmt.Println(result.Output)
}
Manual Session Management
package main
import (
"context"
"fmt"
"log"
"github.com/instavm/instavm-go"
)
func main() {
client := instavm.New("your_api_key")
defer client.Close()
ctx := context.Background()
// Start session explicitly (optional, as it starts automatically)
err := client.StartSession(ctx)
if err != nil {
log.Fatal(err)
}
result, err := client.Execute(ctx, "fmt.Println(\"Manual session management\")")
if err != nil {
log.Fatal(err)
}
// Check session status
isActive := client.IsSessionActive(ctx)
fmt.Printf("Session is active: %t\n", isActive)
// Get session info
info, err := client.GetSessionInfo(ctx)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Session ID: %s\n", info.SessionID)
}
Error Handling
The SDK provides specific error types for different scenarios:
package main
import (
"context"
"fmt"
"github.com/instavm/instavm-go"
)
func main() {
client := instavm.New("invalid_api_key")
defer client.Close()
ctx := context.Background()
_, err := client.Execute(ctx, "fmt.Println(\"This will fail\")")
if err != nil {
switch e := err.(type) {
case *instavm.Error:
switch e.Type {
case "AUTHENTICATION":
fmt.Println("Invalid API key provided")
case "SESSION":
fmt.Printf("Session error: %s\n", e.Message)
case "EXECUTION":
fmt.Printf("Code execution failed: %s\n", e.Message)
case "NETWORK":
fmt.Printf("Network issue: %s\n", e.Message)
case "RATE_LIMIT":
fmt.Printf("Rate limit exceeded: %s\n", e.Message)
default:
fmt.Printf("InstaVM error: %s\n", e.Message)
}
default:
fmt.Printf("Unexpected error: %v\n", err)
}
}
}
Advanced Examples
Data Processing with Goroutines
package main
import (
"context"
"fmt"
"log"
"sync"
"github.com/instavm/instavm-go"
)
func processData(client *instavm.Client, data string, wg *sync.WaitGroup) {
defer wg.Done()
ctx := context.Background()
code := fmt.Sprintf(`
package main
import (
"fmt"
"strings"
)
func main() {
data := "%s"
words := strings.Fields(data)
fmt.Printf("Data: %%s, Word count: %%d\n", data, len(words))
}
`, data)
result, err := client.Execute(ctx, code)
if err != nil {
log.Printf("Error processing data '%s': %v", data, err)
return
}
fmt.Printf("Result: %s", result.Output)
}
func main() {
client := instavm.New("your_api_key")
defer client.Close()
datasets := []string{
"Hello world from InstaVM",
"Go is a powerful programming language",
"Concurrent processing with goroutines",
}
var wg sync.WaitGroup
for _, data := range datasets {
wg.Add(1)
go processData(client, data, &wg)
}
wg.Wait()
fmt.Println("All data processed!")
}
Web Server with Gin Framework
package main
import (
"context"
"fmt"
"log"
"github.com/instavm/instavm-go"
)
func main() {
client := instavm.New("your_api_key")
defer client.Close()
ctx := context.Background()
result, err := client.Execute(ctx, `
package main
import (
"log"
"net/http"
"strconv"
"time"
"github.com/gin-gonic/gin"
)
type CalculationRequest struct {
A float64 ` + "`" + `json:"a"` + "`" + `
B float64 ` + "`" + `json:"b"` + "`" + `
Operation string ` + "`" + `json:"operation"` + "`" + `
}
type CalculationResponse struct {
Result float64 ` + "`" + `json:"result"` + "`" + `
Error string ` + "`" + `json:"error,omitempty"` + "`" + `
}
func main() {
gin.SetMode(gin.ReleaseMode)
r := gin.New()
r.POST("/calculate", func(c *gin.Context) {
var req CalculationRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, CalculationResponse{
Error: "Invalid request format",
})
return
}
var result float64
var errMsg string
switch req.Operation {
case "add":
result = req.A + req.B
case "subtract":
result = req.A - req.B
case "multiply":
result = req.A * req.B
case "divide":
if req.B != 0 {
result = req.A / req.B
} else {
errMsg = "Division by zero"
}
default:
errMsg = "Invalid operation"
}
if errMsg != "" {
c.JSON(http.StatusBadRequest, CalculationResponse{Error: errMsg})
} else {
c.JSON(http.StatusOK, CalculationResponse{Result: result})
}
})
// Start server in a goroutine
go func() {
if err := r.Run(":8080"); err != nil {
log.Printf("Server failed to start: %v", err)
}
}()
// Simulate some requests
time.Sleep(100 * time.Millisecond)
// Make test request
// Note: In a real scenario, you'd make HTTP requests from outside
fmt.Println("Web server started on :8080")
fmt.Println("Example endpoints:")
fmt.Println("POST /calculate")
fmt.Println(` + "`" + `{"a": 10, "b": 5, "operation": "add"}` + "`" + `)
time.Sleep(1 * time.Second)
}
`)
if err != nil {
log.Fatal(err)
}
fmt.Println(result.Output)
}
File Processing and Analysis
package main
import (
"context"
"fmt"
"log"
"github.com/instavm/instavm-go"
)
func main() {
client := instavm.New("your_api_key")
defer client.Close()
ctx := context.Background()
// Upload a data file
uploadResult, err := client.UploadFile(ctx, "/path/to/data.csv")
if err != nil {
log.Fatal(err)
}
fmt.Printf("Uploaded %s\n", uploadResult.Filename)
// Process the CSV file
result, err := client.Execute(ctx, `
package main
import (
"encoding/csv"
"fmt"
"io"
"os"
"strconv"
)
func main() {
file, err := os.Open("data.csv")
if err != nil {
panic(err)
}
defer file.Close()
reader := csv.NewReader(file)
var sum float64
var count int
// Skip header if present
if _, err := reader.Read(); err != nil && err != io.EOF {
panic(err)
}
for {
record, err := reader.Read()
if err == io.EOF {
break
}
if err != nil {
panic(err)
}
// Assume numeric data in first column
if len(record) > 0 {
if value, err := strconv.ParseFloat(record[0], 64); err == nil {
sum += value
count++
}
}
}
if count > 0 {
average := sum / float64(count)
fmt.Printf("Processed %d records\n", count)
fmt.Printf("Sum: %.2f\n", sum)
fmt.Printf("Average: %.2f\n", average)
} else {
fmt.Println("No valid numeric data found")
}
}
`)
if err != nil {
log.Fatal(err)
}
fmt.Println(result.Output)
}
Context and Timeout Management
package main
import (
"context"
"fmt"
"log"
"time"
"github.com/instavm/instavm-go"
)
func main() {
client := instavm.New("your_api_key")
defer client.Close()
// Create context with timeout
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
// Execute long-running code with timeout
result, err := client.Execute(ctx, `
package main
import (
"fmt"
"time"
)
func main() {
fmt.Println("Starting long operation...")
for i := 0; i < 5; i++ {
time.Sleep(1 * time.Second)
fmt.Printf("Step %d/5 completed\n", i+1)
}
fmt.Println("Operation completed!")
}
`)
if err != nil {
log.Fatal(err)
}
fmt.Println(result.Output)
}
// Example with cancellation
func cancellationExample() {
client := instavm.New("your_api_key")
defer client.Close()
ctx, cancel := context.WithCancel(context.Background())
// Cancel after 3 seconds
go func() {
time.Sleep(3 * time.Second)
fmt.Println("Cancelling operation...")
cancel()
}()
_, err := client.Execute(ctx, `
package main
import (
"fmt"
"time"
)
func main() {
for i := 0; i < 10; i++ {
time.Sleep(1 * time.Second)
fmt.Printf("Working... %d\n", i)
}
}
`)
if err != nil {
fmt.Printf("Operation was cancelled: %v\n", err)
}
}
Types and Structures
ExecutionResult
type ExecutionResult struct {
Output string `json:"output"`
ExecutionTime float64 `json:"execution_time"`
Error string `json:"error,omitempty"`
SessionID string `json:"session_id,omitempty"`
}
SessionInfo
type SessionInfo struct {
SessionID string `json:"session_id"`
CreatedAt time.Time `json:"created_at"`
Status string `json:"status"`
}
UsageInfo
type UsageInfo struct {
CPUTime float64 `json:"cpu_time"`
MemoryUsed int64 `json:"memory_used"`
NetworkIO int64 `json:"network_io"`
ExecutionTime float64 `json:"execution_time"`
}
Error
type Error struct {
Type string `json:"type"`
Message string `json:"message"`
Code int `json:"code,omitempty"`
}
Performance Tips
- Use defer for cleanup: Always defer
client.Close()
to ensure sessions are closed - Context management: Use contexts for timeout and cancellation control
- Reuse clients: Create one client instance for multiple operations
- Handle errors appropriately: Check error types for specific handling
- Use goroutines: Leverage Go's concurrency for parallel processing
Configuration Options
Parameter | Default | Description |
---|---|---|
apiKey | Required | Your InstaVM API key |
BaseURL | https://api.instavm.io | API endpoint URL |
Timeout | 30s | Request timeout duration |