From 1aeea858abcca8a1d2e9b70ff37071468bb5c98f Mon Sep 17 00:00:00 2001 From: karamouche Date: Mon, 6 Jul 2026 14:56:26 -0400 Subject: [PATCH] feat: add CLI versioning header and update client initialization --- cmd/transcribe.go | 2 +- cmd/transcribe_test.go | 45 ++++++++++++++++++++++++++++++++--- pkg/client/client.go | 12 +++++++++- pkg/client/client_test.go | 4 ++-- pkg/client/transcribe.go | 4 ++-- pkg/client/transcribe_test.go | 18 +++++++++----- pkg/client/transcription.go | 2 +- 7 files changed, 71 insertions(+), 16 deletions(-) diff --git a/cmd/transcribe.go b/cmd/transcribe.go index bd459d3..2751d29 100644 --- a/cmd/transcribe.go +++ b/cmd/transcribe.go @@ -68,7 +68,7 @@ Examples: return err } - client := gladia.NewGladiaClient(key, verbose) + client := gladia.NewGladiaClient(key, verbose, version) audioURL, err := resolveAudioSource(client, args[0]) if err != nil { diff --git a/cmd/transcribe_test.go b/cmd/transcribe_test.go index e36fbde..103f6f9 100644 --- a/cmd/transcribe_test.go +++ b/cmd/transcribe_test.go @@ -134,7 +134,7 @@ func TestBuildLanguageConfig(t *testing.T) { } func TestResolveAudioSource_URL(t *testing.T) { - client := gladia.NewGladiaClient("key", false) + client := gladia.NewGladiaClient("key", false, "dev") url := "https://cdn.example.com/audio.wav" got, err := resolveAudioSource(client, url) if err != nil { @@ -146,7 +146,7 @@ func TestResolveAudioSource_URL(t *testing.T) { } func TestResolveAudioSource_missingFile(t *testing.T) { - client := gladia.NewGladiaClient("key", false) + client := gladia.NewGladiaClient("key", false, "dev") _, err := resolveAudioSource(client, filepath.Join(t.TempDir(), "nope.wav")) if err == nil { t.Fatal("expected error for missing file") @@ -163,7 +163,7 @@ func TestResolveAudioSource_upload(t *testing.T) { })) defer server.Close() - client := gladia.NewGladiaClient("test-key", false) + client := gladia.NewGladiaClient("test-key", false, "dev") client.GladiaEndpoint = server.URL dir := t.TempDir() @@ -329,6 +329,45 @@ func TestTranscribeCommand_invalidLanguage(t *testing.T) { } } +func TestTranscribeCommand_sendsVersionHeader(t *testing.T) { + withTempHome(t) + t.Setenv(envGladiaAPIKey, "test-key") + + var versionHeader string + donePayload := sampleTranscriptionResult() + donePayload.Status = "done" + doneBody, _ := json.Marshal(donePayload) + + server := httptest.NewServer(nil) + base := server.URL + server.Config.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch { + case r.Method == http.MethodPost && r.URL.Path == "/v2/pre-recorded": + versionHeader = r.Header.Get("x-gladia-version") + w.WriteHeader(http.StatusCreated) + _ = json.NewEncoder(w).Encode(map[string]string{"result_url": base + "/result/1"}) + case r.Method == http.MethodGet: + _, _ = w.Write(doneBody) + } + }) + defer server.Close() + + oldEndpoint := gladia.GladiaApiEndpoint + gladia.GladiaApiEndpoint = server.URL + t.Cleanup(func() { gladia.GladiaApiEndpoint = oldEndpoint }) + + cmd := newRootCmd() + cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) + cmd.SetArgs([]string{"transcribe", "https://example.com/audio.wav"}) + if err := cmd.Execute(); err != nil { + t.Fatalf("execute: %v", err) + } + if versionHeader != "cli/dev" { + t.Fatalf("x-gladia-version = %q, want cli/dev", versionHeader) + } +} + func TestTranscribeCommand_URLTextOutput(t *testing.T) { withTempHome(t) t.Setenv(envGladiaAPIKey, "test-key") diff --git a/pkg/client/client.go b/pkg/client/client.go index 8da1187..ef54ef6 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -11,14 +11,19 @@ var GladiaApiEndpoint = "https://api.gladia.io" type GladiaClient struct { ApiKey string GladiaEndpoint string + CLIVersion string httpClient *http.Client Verbose bool } -func NewGladiaClient(apiKey string, verbose bool) *GladiaClient { +func NewGladiaClient(apiKey string, verbose bool, cliVersion string) *GladiaClient { + if cliVersion == "" { + cliVersion = "dev" + } return &GladiaClient{ ApiKey: apiKey, GladiaEndpoint: GladiaApiEndpoint, + CLIVersion: cliVersion, httpClient: &http.Client{}, Verbose: verbose, } @@ -27,3 +32,8 @@ func NewGladiaClient(apiKey string, verbose bool) *GladiaClient { func (c *GladiaClient) apiURL(path string) string { return strings.TrimSuffix(c.GladiaEndpoint, "/") + path } + +func (c *GladiaClient) setRequestHeaders(req *http.Request) { + req.Header.Set("x-gladia-key", c.ApiKey) + req.Header.Set("x-gladia-version", "cli/"+c.CLIVersion) +} diff --git a/pkg/client/client_test.go b/pkg/client/client_test.go index 52ce7a3..5332a56 100644 --- a/pkg/client/client_test.go +++ b/pkg/client/client_test.go @@ -15,8 +15,8 @@ func TestGladiaClient_apiURL(t *testing.T) { } func TestNewGladiaClient_defaults(t *testing.T) { - c := NewGladiaClient("key", true) - if c.ApiKey != "key" || !c.Verbose || c.GladiaEndpoint != GladiaApiEndpoint { + c := NewGladiaClient("key", true, "dev") + if c.ApiKey != "key" || !c.Verbose || c.GladiaEndpoint != GladiaApiEndpoint || c.CLIVersion != "dev" { t.Fatalf("unexpected client: %+v", c) } } diff --git a/pkg/client/transcribe.go b/pkg/client/transcribe.go index ae6c2cc..89bc656 100644 --- a/pkg/client/transcribe.go +++ b/pkg/client/transcribe.go @@ -209,7 +209,7 @@ func (c *GladiaClient) UploadFile(filePath string) (string, error) { } req.Header.Set("Content-Type", writer.FormDataContentType()) - req.Header.Set("x-gladia-key", c.ApiKey) + c.setRequestHeaders(req) resp, err := c.httpClient.Do(req) if err != nil { @@ -272,7 +272,7 @@ func (c *GladiaClient) createAndExecuteRequest(method, url string, body io.Reade } req.Header.Set("Content-Type", "application/json") - req.Header.Set("x-gladia-key", c.ApiKey) + c.setRequestHeaders(req) resp, err := c.httpClient.Do(req) if err != nil { diff --git a/pkg/client/transcribe_test.go b/pkg/client/transcribe_test.go index 0413328..ee90514 100644 --- a/pkg/client/transcribe_test.go +++ b/pkg/client/transcribe_test.go @@ -18,6 +18,9 @@ func TestUploadFile_success(t *testing.T) { if r.Header.Get("x-gladia-key") != "secret" { t.Fatalf("api key header = %q", r.Header.Get("x-gladia-key")) } + if r.Header.Get("x-gladia-version") != "cli/dev" { + t.Fatalf("version header = %q", r.Header.Get("x-gladia-version")) + } _ = json.NewEncoder(w).Encode(map[string]string{"audio_url": "https://cdn/audio.wav"}) })) defer server.Close() @@ -28,7 +31,7 @@ func TestUploadFile_success(t *testing.T) { t.Fatal(err) } - c := NewGladiaClient("secret", false) + c := NewGladiaClient("secret", false, "dev") c.GladiaEndpoint = server.URL url, err := c.UploadFile(path) @@ -52,7 +55,7 @@ func TestUploadFile_apiError(t *testing.T) { t.Fatal(err) } - c := NewGladiaClient("k", false) + c := NewGladiaClient("k", false, "dev") c.GladiaEndpoint = server.URL if _, err := c.UploadFile(path); err == nil { t.Fatal("expected error") @@ -70,6 +73,9 @@ func TestTranscribeAudioURL_success(t *testing.T) { server.Config.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { switch { case r.Method == http.MethodPost && r.URL.Path == "/v2/pre-recorded": + if r.Header.Get("x-gladia-version") != "cli/dev" { + t.Fatalf("version header = %q", r.Header.Get("x-gladia-version")) + } _ = json.NewDecoder(r.Body).Decode(&posted) w.WriteHeader(http.StatusCreated) _ = json.NewEncoder(w).Encode(TranscriptionResponse{ResultURL: base + "/poll"}) @@ -81,7 +87,7 @@ func TestTranscribeAudioURL_success(t *testing.T) { }) defer server.Close() - c := NewGladiaClient("k", false) + c := NewGladiaClient("k", false, "dev") c.GladiaEndpoint = server.URL req := TranscriptionRequest{ @@ -115,7 +121,7 @@ func TestTranscribeAudioURL_apiValidationError(t *testing.T) { })) defer server.Close() - c := NewGladiaClient("k", false) + c := NewGladiaClient("k", false, "dev") c.GladiaEndpoint = server.URL _, err := c.TranscribeAudioURL("https://a", TranscriptionRequest{}) if err == nil { @@ -132,7 +138,7 @@ func TestPollForTranscriptionResult_errorStatus(t *testing.T) { })) defer server.Close() - c := NewGladiaClient("k", false) + c := NewGladiaClient("k", false, "dev") c.GladiaEndpoint = server.URL _, err := c.pollForTranscriptionResult(server.URL + "/status") if err == nil || !strings.Contains(err.Error(), "boom") { @@ -141,7 +147,7 @@ func TestPollForTranscriptionResult_errorStatus(t *testing.T) { } func TestDecodeAPIError(t *testing.T) { - c := NewGladiaClient("k", false) + c := NewGladiaClient("k", false, "dev") rec := httptest.NewRecorder() rec.WriteHeader(http.StatusBadRequest) _ = json.NewEncoder(rec).Encode(map[string]interface{}{ diff --git a/pkg/client/transcription.go b/pkg/client/transcription.go index af4bead..e3b70fe 100644 --- a/pkg/client/transcription.go +++ b/pkg/client/transcription.go @@ -81,7 +81,7 @@ func (c *GladiaClient) ListTranscriptions(offset, limit int, status, kind, date, q.Add("after_date", afterDate) req.URL.RawQuery = q.Encode() - req.Header.Add("x-gladia-key", c.ApiKey) + c.setRequestHeaders(req) resp, err := c.httpClient.Do(req) if err != nil {