Sume video jobs in Go: net/http, a struct, and a poll loop

A Go program that submits a Sume video job with net/http, decodes the job into a struct, polls to completed, and prints the URL and cost in 30 lines.

5 min readSume
All posts

Go's standard library is enough for Sume's asynchronous video API. The program below posts a sume/auto job, decodes the job body into a small struct, polls every 20 seconds, and prints the first download URL plus usage.cost once the job is completed.

The code

Set SUME_API_KEY. The program submits one job, polls polling_url every 20 seconds until completed, and prints the first download URL.

package main
import ("encoding/json"; "fmt"; "net/http"; "os"; "strings"; "time")
type Job struct {
	Status       string
	PollingURL   string   `json:"polling_url"`
	UnsignedURLs []string `json:"unsigned_urls"`
	Usage        struct{ Cost float64 }
}
func call(method, url, body string) Job {
	req, _ := http.NewRequest(method, url, strings.NewReader(body))
	req.Header.Set("Authorization", "Bearer "+os.Getenv("SUME_API_KEY"))
	req.Header.Set("Content-Type", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil { panic(err) }
	defer res.Body.Close()
	var j Job
	json.NewDecoder(res.Body).Decode(&j)
	return j
}
func main() {
	job := call("POST", "https://api.sume.com/v1/videos",
		`{"model":"sume/auto","prompt":"A tram crossing a bridge at dawn","aspect_ratio":"16:9"}`)
	for {
		time.Sleep(20 * time.Second)
		s := call("GET", job.PollingURL, "")
		fmt.Println(s.Status)
		if s.Status == "completed" { fmt.Println(s.UnsignedURLs[0], s.Usage.Cost); return }
		if s.Status == "failed" || s.Status == "cancelled" { os.Exit(1) }
	}
}

What to know

sume/auto currently resolves to Gemini Omni Flash 1.1 and takes 3 to 10 seconds in 16:9 or 9:16. The defaults are 720p and 8 seconds, so this call bills $1.00 (list $0.10 per second x 1.25 x 8 s). A failed or cancelled job ends the loop with a non-success status; check error in the poll body.

usage.cost is a JSON number in the documented response, so float64 decodes it. The program was vetted with go vet but not run against the live API. For a service, wrap the loop in a context with a deadline and switch the sleep to time.Ticker; a clip on a slower model can take several minutes.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume