Skip to content
This repository was archived by the owner on Apr 1, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading