SDKs
Official TypeScript, Python and Go clients for the Sawvant API.
Overview
There are official SDKs for TypeScript, Python and Go. They are open source, generated from the OpenAPI spec, and wrap the REST API. From any other language you call the REST API directly; the API reference has request samples for each endpoint.
| Language | Package | Install |
|---|---|---|
| TypeScript | @sawvant/sdk | npm install @sawvant/sdk |
| Python | sawvant | pip install sawvant |
| Go | sawvant-go | go get github.com/sawvant/sawvant-go |
The TypeScript SDK needs Node.js 18 or later, the Python SDK Python 3.8 or later and the Go SDK Go 1.22 or later. The source of each SDK is on GitHub: sawvant-typescript, sawvant-python and sawvant-go.
Quick Start
Submit a job, then poll until it is done. Sizes are in mm.
TypeScript
import { Configuration, JobsApi, OptimizationApi } from '@sawvant/sdk';
const config = new Configuration({
apiKey: 'sk_your_api_key',
basePath: 'https://api.sawvant.com',
});
const optimization = new OptimizationApi(config);
const jobs = new JobsApi(config);
const job = await optimization.createOptimization({
sheets: [
{ id: 'S1', length: 2440, width: 1220, quantity: 5, grain: 'none' },
],
parts: [
{ id: 'P1', length: 600, width: 400, quantity: 10, grain: 'none' },
],
machine: { bladeThickness: 4, maxLevels: 3, cutDirection: 'default' },
});
let result = await jobs.getJob(job.jobId);
while (result.status === 'pending' || result.status === 'running') {
await new Promise(resolve => setTimeout(resolve, 500));
result = await jobs.getJob(job.jobId);
}
if (result.status === 'completed') {
console.log(result.result?.summary);
} else {
console.error('Job failed:', result.error);
}Python
import time
import sawvant
from sawvant import (
CutDirection,
GrainDirection,
JobsApi,
Machine,
OptimizationApi,
OptimizeRequest,
Part,
Sheet,
)
configuration = sawvant.Configuration(
host='https://api.sawvant.com',
api_key={'apiKey': 'sk_your_api_key'},
)
with sawvant.ApiClient(configuration) as client:
optimization = OptimizationApi(client)
jobs = JobsApi(client)
request = OptimizeRequest(
sheets=[Sheet(id='S1', length=2440, width=1220, quantity=5, grain=GrainDirection.NONE)],
parts=[Part(id='P1', length=600, width=400, quantity=10, grain=GrainDirection.NONE)],
machine=Machine(blade_thickness=4, max_levels=3, cut_direction=CutDirection.DEFAULT),
)
job = optimization.create_optimization(request)
result = jobs.get_job(job.job_id)
while result.status in ('pending', 'running'):
time.sleep(0.5)
result = jobs.get_job(job.job_id)
if result.status == 'completed':
print(result.result.summary)
else:
print('Job failed:', result.error)Go
package main
import (
"context"
"fmt"
"log"
"time"
sawvant "github.com/sawvant/sawvant-go"
)
func main() {
cfg := sawvant.NewConfiguration()
cfg.Host = "api.sawvant.com"
client := sawvant.NewAPIClient(cfg)
ctx := context.WithValue(context.Background(), sawvant.ContextAPIKeys, map[string]sawvant.APIKey{
"apiKey": {Key: "sk_your_api_key"},
})
req := sawvant.OptimizeRequest{
Sheets: []sawvant.Sheet{
{Id: "S1", Length: 2440, Width: 1220, Quantity: 5, Grain: sawvant.NONE},
},
Parts: []sawvant.Part{
{Id: "P1", Length: 600, Width: 400, Quantity: 10, Grain: sawvant.NONE},
},
Machine: sawvant.Machine{BladeThickness: 4, MaxLevels: 3, CutDirection: sawvant.DEFAULT},
}
job, _, err := client.OptimizationAPI.CreateOptimization(ctx).OptimizeRequest(req).Execute()
if err != nil {
log.Fatalf("create optimization: %v", err)
}
for {
res, _, err := client.JobsAPI.GetJob(ctx, job.GetJobId()).Execute()
if err != nil {
log.Fatalf("get job: %v", err)
}
switch res.GetStatus() {
case "completed":
fmt.Printf("%+v\n", res.GetResult().Summary)
return
case "failed":
log.Fatalf("job failed: %s", res.GetError())
}
time.Sleep(500 * time.Millisecond)
}
}SSE Streaming
On the Pro plan you can follow a job through Server-Sent Events instead of polling. The server leaves the result out of stream events to keep them small. When a completed event arrives, each SDK fetches the job with GET /v1/jobs/{id} and puts the full result in the event.
TypeScript
import { streamJob } from '@sawvant/sdk/dist/streaming.js';
for await (const event of streamJob(job.jobId, { apiKey: 'sk_your_api_key' })) {
if (event.type === 'progress') {
console.log('Progress:', event.data.progress);
} else if (event.type === 'completed') {
console.log('Done:', event.data.result);
break;
} else if (event.type === 'failed') {
console.error('Failed:', event.data.error);
break;
}
}streamJob also takes baseUrl and an AbortSignal as signal.
Python
The Python helper uses httpx. Install the SDK with the streaming extra:
pip install "sawvant[streaming]"from sawvant.streaming import stream_job
for event in stream_job(job.job_id, 'sk_your_api_key'):
if event.type == 'progress':
print('Progress:', event.data['progress'])
elif event.type == 'completed':
print('Done:', event.data['result'])
break
elif event.type == 'failed':
print('Failed:', event.data.get('error'))
breakstream_job also takes base_url and timeout in seconds. event.data is a plain dict with the job fields.
Go
StreamJob sends only the headers set on the configuration, so pass the key with AddDefaultHeader.
cfg := sawvant.NewConfiguration()
cfg.Host = "api.sawvant.com"
cfg.AddDefaultHeader("X-API-Key", "sk_your_api_key")
client := sawvant.NewAPIClient(cfg)
events, errs := client.StreamJob(ctx, jobID)
for {
select {
case event, ok := <-events:
if !ok {
return
}
switch event.Type {
case "progress":
fmt.Printf("Progress: %d%%\n", event.Data.GetProgress())
case "completed":
fmt.Printf("Done: %+v\n", event.Data.GetResult().Summary)
return
case "failed":
log.Fatalf("Failed: %s", event.Data.GetError())
}
case err := <-errs:
if err != nil {
log.Fatal(err)
}
}
}API Methods
| Endpoint | TypeScript | Python | Go |
|---|---|---|---|
POST /v1/optimize | OptimizationApi.createOptimization | OptimizationApi.create_optimization | OptimizationAPI.CreateOptimization |
GET /v1/jobs/{id} | JobsApi.getJob | JobsApi.get_job | JobsAPI.GetJob |
GET /v1/jobs/{id}/stream | streamJob | stream_job | StreamJob |
GET /health | SystemApi.getHealth | SystemApi.get_health | SystemAPI.GetHealth |