Skip to content

Commit

Permalink
Sync from internal repo (2024-10-21) (#31)
Browse files Browse the repository at this point in the history
* fix(sdk/go): migrate from nhooyr.io/websocket to coder/websocket (#6735)

GitOrigin-RevId: a2afc9dd6887e79cfacc4e443dccf58245f6f648

* feat(sdk/go): add support for multichannel (#6815)

GitOrigin-RevId: a0cbddc3866fd5a1d8525907fe2d280cf9e940b5
  • Loading branch information
marcusolsson authored Oct 21, 2024
1 parent 878ef53 commit 52add84
Show file tree
Hide file tree
Showing 20 changed files with 460 additions and 185 deletions.
2 changes: 1 addition & 1 deletion .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ linters-settings:
main:
allow:
- $gostd
- nhooyr.io/websocket
- github.com/coder/websocket
- github.com/google
- github.com/stretchr/testify
- github.com/cenkalti/backoff
Expand Down
139 changes: 80 additions & 59 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,17 @@ A Go client library for accessing [AssemblyAI](https://assemblyai.com).
## Overview

- [AssemblyAI Go SDK](#assemblyai-go-sdk)
- [Overview](#overview)
- [Documentation](#documentation)
- [Quickstart](#quickstart)
- [Installation](#installation)
- [Examples](#examples)
- [Core Transcription](#core-transcription)
- [Audio Intelligence](#audio-intelligence)
- [Real-Time Transcription](#real-time-transcription)
- [Playgrounds](#playgrounds)
- [Overview](#overview)
- [Documentation](#documentation)
- [Quickstart](#quickstart)
- [Installation](#installation)
- [Examples](#examples)
- [Core Transcription](#core-transcription)
- [Audio Intelligence](#audio-intelligence)
- [Real-Time Transcription](#real-time-transcription)
- [Playgrounds](#playgrounds)
- [Tips and tricks](#tips-and-tricks)
- [Inspect API errors](#inspect-api-errors)

## Documentation

Expand Down Expand Up @@ -54,28 +56,28 @@ Before you begin, you need to have your API key. If you don't have one yet, [**s
package main

import (
"context"
"log"
"os"
"context"
"log"
"os"

"github.com/AssemblyAI/assemblyai-go-sdk"
"github.com/AssemblyAI/assemblyai-go-sdk"
)

func main() {
apiKey := os.Getenv("ASSEMBLYAI_API_KEY")
apiKey := os.Getenv("ASSEMBLYAI_API_KEY")

ctx := context.Background()
ctx := context.Background()

audioURL := "https://example.org/audio.mp3"
audioURL := "https://example.org/audio.mp3"

client := assemblyai.NewClient(apiKey)
client := assemblyai.NewClient(apiKey)

transcript, err := client.Transcripts.TranscribeFromURL(ctx, audioURL, nil)
if err != nil {
log.Fatal("Something bad happened:", err)
}
transcript, err := client.Transcripts.TranscribeFromURL(ctx, audioURL, nil)
if err != nil {
log.Fatal("Something bad happened:", err)
}

log.Println(*transcript.Text)
log.Println(*transcript.Text)
}
```

Expand All @@ -87,32 +89,32 @@ func main() {
package main

import (
"context"
"log"
"os"
"context"
"log"
"os"

"github.com/AssemblyAI/assemblyai-go-sdk"
"github.com/AssemblyAI/assemblyai-go-sdk"
)

func main() {
apiKey := os.Getenv("ASSEMBLYAI_API_KEY")
apiKey := os.Getenv("ASSEMBLYAI_API_KEY")

ctx := context.Background()
ctx := context.Background()

client := assemblyai.NewClient(apiKey)
client := assemblyai.NewClient(apiKey)

f, err := os.Open("./my-local-audio-file.wav")
if err != nil {
log.Fatal("Couldn't open audio file:", err)
}
defer f.Close()
f, err := os.Open("./my-local-audio-file.wav")
if err != nil {
log.Fatal("Couldn't open audio file:", err)
}
defer f.Close()

transcript, err := client.Transcripts.TranscribeFromReader(ctx, f, nil)
if err != nil {
log.Fatal("Something bad happened:", err)
}
transcript, err := client.Transcripts.TranscribeFromReader(ctx, f, nil)
if err != nil {
log.Fatal("Something bad happened:", err)
}

log.Println(*transcript.Text)
log.Println(*transcript.Text)
}
```

Expand All @@ -127,36 +129,36 @@ func main() {
package main

import (
"context"
"log"
"os"
"context"
"log"
"os"

"github.com/AssemblyAI/assemblyai-go-sdk"
"github.com/AssemblyAI/assemblyai-go-sdk"
)

func main() {
apiKey := os.Getenv("ASSEMBLYAI_API_KEY")
apiKey := os.Getenv("ASSEMBLYAI_API_KEY")

ctx := context.Background()
ctx := context.Background()

audioURL := "https://example.org/audio.mp3"
audioURL := "https://example.org/audio.mp3"

client := assemblyai.NewClient(apiKey)
client := assemblyai.NewClient(apiKey)

opts := &assemblyai.TranscriptParams{
EntityDetection: assemblyai.Bool(true),
}
opts := &assemblyai.TranscriptParams{
EntityDetection: assemblyai.Bool(true),
}

transcript, err := client.Transcripts.TranscribeFromURL(ctx, audioURL, opts)
if err != nil {
log.Fatal("Something bad happened:", err)
}
transcript, err := client.Transcripts.TranscribeFromURL(ctx, audioURL, opts)
if err != nil {
log.Fatal("Something bad happened:", err)
}

for _, entity := range transcript.Entities {
log.Println(*entity.Text)
log.Println(entity.EntityType)
log.Printf("Timestamp: %v - %v", *entity.Start, *entity.End)
}
for _, entity := range transcript.Entities {
log.Println(*entity.Text)
log.Println(entity.EntityType)
log.Printf("Timestamp: %v - %v", *entity.Start, *entity.End)
}
}
```

Expand All @@ -172,3 +174,22 @@ Visit one of our Playgrounds:

- [LeMUR Playground](https://www.assemblyai.com/playground/v2/source)
- [Transcription Playground](https://www.assemblyai.com/playground)

## Tips and tricks

### Inspect API errors

If you receive an API error, you can inspect the HTTP response returned by the API for more details:

```go
transcript, err := client.Transcripts.TranscribeFromURL(ctx, audioURL, nil)
if err != nil {
var apierr aai.APIError
if errors.As(err, &apierr) {
// apierr.Response is the *http.Response from the API call.
fmt.Println(apierr.Response.StatusCode)
} else {
// err is not an API error.
}
}
```
44 changes: 35 additions & 9 deletions assemblyai.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ import (
"encoding/json"
"fmt"
"io"
"mime"
"net/http"
"net/url"
"os"
)

const (
version = "1.8.1"
version = "1.9.0"
defaultBaseURLScheme = "https"
defaultBaseURLHost = "api.assemblyai.com"
)
Expand Down Expand Up @@ -137,33 +138,58 @@ func (c *Client) newRequest(ctx context.Context, method, path string, body io.Re
return req, err
}

func (c *Client) do(req *http.Request, v interface{}) (*http.Response, error) {
func (c *Client) do(req *http.Request, v interface{}) error {
resp, err := c.httpClient.Do(req)
if err != nil {
return nil, err
return err
}
defer resp.Body.Close()

if resp.StatusCode != http.StatusOK {
contentType := resp.Header.Get("Content-Type")

mimeType, _, err := mime.ParseMediaType(contentType)
if err != nil {
return err
}

isJSONResponse := mimeType == "application/json"
isAPIError := resp.StatusCode < 200 || resp.StatusCode >= 400

if isAPIError {
var buf bytes.Buffer

_, err := io.Copy(&buf, resp.Body)
if err != nil {
return err
}

var apierr APIError

if err := json.NewDecoder(resp.Body).Decode(&apierr); err != nil {
return nil, err
if isJSONResponse {
if err := json.Unmarshal(buf.Bytes(), &apierr); err != nil {
return err
}
}

// Reset response body so that clients can read it again.
resp.Body = io.NopCloser(bytes.NewBuffer(buf.Bytes()))

apierr.Status = resp.StatusCode
apierr.Response = resp

return nil, apierr
return apierr
}

if v != nil {
switch val := v.(type) {
case *[]byte:
*val, err = io.ReadAll(resp.Body)
default:
err = json.NewDecoder(resp.Body).Decode(v)
if isJSONResponse {
err = json.NewDecoder(resp.Body).Decode(v)
}
}
}

return resp, err
return err
}
5 changes: 5 additions & 0 deletions assemblyai_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"testing"

"github.com/stretchr/testify/require"
Expand All @@ -22,6 +23,10 @@ func setup() (*Client, *http.ServeMux, func()) {
func writeFileResponse(t *testing.T, w http.ResponseWriter, filename string) {
t.Helper()

if filepath.Ext(filename) == ".json" {
w.Header().Set("Content-Type", "application/json")
}

b, err := os.ReadFile(filename)
require.NoError(t, err)

Expand Down
4 changes: 4 additions & 0 deletions errors.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package assemblyai

import "net/http"

// APIError represents an error returned by the AssemblyAI API.
type APIError struct {
Status int `json:"-"`
Message string `json:"error"`

Response *http.Response `json:"-"`
}

// Error returns the API error message.
Expand Down
2 changes: 1 addition & 1 deletion examples/realtime/go.mod
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module github.com/AssemblyAI/DeepLearning/assemblyai/developer_tools/go/examples/realtime
module github.com/AssemblyAI/assemblyai-go-sdk/examples/realtime

go 1.21

Expand Down
19 changes: 19 additions & 0 deletions examples/upload-with-progress/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module github.com/AssemblyAI/assemblyai-go-sdk/examples/upload-with-progress

go 1.21

require (
github.com/AssemblyAI/assemblyai-go-sdk v1.5.1
github.com/schollz/progressbar/v3 v3.14.6
)

require (
github.com/cenkalti/backoff v2.2.1+incompatible // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/klauspost/compress v1.10.3 // indirect
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect
github.com/rivo/uniseg v0.4.7 // indirect
golang.org/x/sys v0.22.0 // indirect
golang.org/x/term v0.22.0 // indirect
nhooyr.io/websocket v1.8.7 // indirect
)
Loading

0 comments on commit 52add84

Please sign in to comment.