Integration Examples

View as Markdown

Overview

This page provides complete, production-ready examples for integrating Smallest Self-Host into your applications.

Python Examples

Basic Transcription

1import requests
2import os
3
4LICENSE_KEY = os.getenv("LICENSE_KEY")
5API_URL = "http://localhost:7100"
6
7def transcribe_audio(audio_url):
8 response = requests.post(
9 f"{API_URL}/v1/listen",
10 headers={
11 "Authorization": f"Token {LICENSE_KEY}",
12 "Content-Type": "application/json"
13 },
14 json={"url": audio_url}
15 )
16
17 if response.status_code == 200:
18 return response.json()
19 else:
20 raise Exception(f"Transcription failed: {response.text}")
21
22result = transcribe_audio("https://example.com/audio.wav")
23print(f"Transcription: {result['text']}")
24print(f"Confidence: {result['confidence']}")

With Retry Logic

1import requests
2from requests.adapters import HTTPAdapter
3from urllib3.util.retry import Retry
4import time
5
6class SmallestClient:
7 def __init__(self, api_url, license_key):
8 self.api_url = api_url
9 self.license_key = license_key
10
11 self.session = requests.Session()
12 retry = Retry(
13 total=3,
14 backoff_factor=1,
15 status_forcelist=[429, 500, 502, 503, 504]
16 )
17 adapter = HTTPAdapter(max_retries=retry)
18 self.session.mount('http://', adapter)
19 self.session.mount('https://', adapter)
20
21 def transcribe(self, audio_url, **kwargs):
22 headers = {
23 "Authorization": f"Token {self.license_key}",
24 "Content-Type": "application/json"
25 }
26
27 payload = {"url": audio_url, **kwargs}
28
29 response = self.session.post(
30 f"{self.api_url}/v1/listen",
31 headers=headers,
32 json=payload,
33 timeout=300
34 )
35
36 response.raise_for_status()
37 return response.json()
38
39client = SmallestClient(
40 api_url="http://localhost:7100",
41 license_key=os.getenv("LICENSE_KEY")
42)
43
44result = client.transcribe(
45 "https://example.com/audio.wav",
46 punctuate=True,
47 timestamps=True
48)
49print(result['text'])

Async Processing with Webhook

1from flask import Flask, request, jsonify
2import requests
3import os
4
5app = Flask(__name__)
6
7LICENSE_KEY = os.getenv("LICENSE_KEY")
8API_URL = "http://localhost:7100"
9
10@app.route('/webhook/transcription', methods=['POST'])
11def transcription_webhook():
12 data = request.json
13 job_id = data['job_id']
14 status = data['status']
15
16 if status == 'completed':
17 result = data['result']
18 print(f"Job {job_id} completed: {result['text']}")
19 elif status == 'failed':
20 print(f"Job {job_id} failed: {data['error']}")
21
22 return jsonify({"received": True})
23
24def submit_async_transcription(audio_url):
25 response = requests.post(
26 f"{API_URL}/v1/listen",
27 headers={
28 "Authorization": f"Token {LICENSE_KEY}",
29 "Content-Type": "application/json"
30 },
31 json={
32 "url": audio_url,
33 "callback_url": "https://myapp.com/webhook/transcription"
34 }
35 )
36
37 return response.json()
38
39if __name__ == '__main__':
40 job = submit_async_transcription("https://example.com/long-audio.mp3")
41 print(f"Job submitted: {job['job_id']}")
42
43 app.run(port=5000)

Batch Processing

1import concurrent.futures
2import requests
3import os
4
5LICENSE_KEY = os.getenv("LICENSE_KEY")
6API_URL = "http://localhost:7100"
7
8def transcribe_single(audio_url):
9 try:
10 response = requests.post(
11 f"{API_URL}/v1/listen",
12 headers={
13 "Authorization": f"Token {LICENSE_KEY}",
14 "Content-Type": "application/json"
15 },
16 json={"url": audio_url},
17 timeout=300
18 )
19 response.raise_for_status()
20 return {
21 "url": audio_url,
22 "success": True,
23 "result": response.json()
24 }
25 except Exception as e:
26 return {
27 "url": audio_url,
28 "success": False,
29 "error": str(e)
30 }
31
32audio_urls = [
33 "https://example.com/audio1.wav",
34 "https://example.com/audio2.wav",
35 "https://example.com/audio3.wav",
36]
37
38with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
39 results = list(executor.map(transcribe_single, audio_urls))
40
41for result in results:
42 if result['success']:
43 print(f"{result['url']}: {result['result']['text']}")
44 else:
45 print(f"{result['url']}: ERROR - {result['error']}")

JavaScript/Node.js Examples

Basic Transcription

1const axios = require('axios');
2
3const LICENSE_KEY = process.env.LICENSE_KEY;
4const API_URL = 'http://localhost:7100';
5
6async function transcribeAudio(audioUrl) {
7 try {
8 const response = await axios.post(
9 `${API_URL}/v1/listen`,
10 { url: audioUrl },
11 {
12 headers: {
13 'Authorization': `Token ${LICENSE_KEY}`,
14 'Content-Type': 'application/json'
15 }
16 }
17 );
18
19 return response.data;
20 } catch (error) {
21 console.error('Transcription failed:', error.response?.data || error.message);
22 throw error;
23 }
24}
25
26transcribeAudio('https://example.com/audio.wav')
27 .then(result => {
28 console.log('Transcription:', result.text);
29 console.log('Confidence:', result.confidence);
30 });

TypeScript Client Class

1import axios, { AxiosInstance } from 'axios';
2
3interface TranscriptionOptions {
4 url?: string;
5 file?: File;
6 language?: string;
7 punctuate?: boolean;
8 diarize?: boolean;
9 timestamps?: boolean;
10 callback_url?: string;
11}
12
13interface TranscriptionResult {
14 request_id: string;
15 text: string;
16 confidence: number;
17 duration: number;
18 language: string;
19 words?: Array<{
20 word: string;
21 start: number;
22 end: number;
23 confidence: number;
24 }>;
25}
26
27class SmallestClient {
28 private client: AxiosInstance;
29
30 constructor(apiUrl: string, licenseKey: string) {
31 this.client = axios.create({
32 baseURL: apiUrl,
33 headers: {
34 'Authorization': `Token ${licenseKey}`,
35 'Content-Type': 'application/json'
36 },
37 timeout: 300000
38 });
39 }
40
41 async transcribe(options: TranscriptionOptions): Promise<TranscriptionResult> {
42 const response = await this.client.post('/v1/listen', options);
43 return response.data;
44 }
45
46 async health(): Promise<{ status: string }> {
47 const response = await this.client.get('/health');
48 return response.data;
49 }
50}
51
52const client = new SmallestClient(
53 process.env.API_URL || 'http://localhost:7100',
54 process.env.LICENSE_KEY!
55);
56
57async function main() {
58 const result = await client.transcribe({
59 url: 'https://example.com/audio.wav',
60 punctuate: true,
61 timestamps: true
62 });
63
64 console.log(result.text);
65}
66
67main();

Express.js API Integration

1const express = require('express');
2const axios = require('axios');
3const multer = require('multer');
4const FormData = require('form-data');
5
6const app = express();
7const upload = multer({ storage: multer.memoryStorage() });
8
9const LICENSE_KEY = process.env.LICENSE_KEY;
10const API_URL = 'http://localhost:7100';
11
12app.post('/transcribe', upload.single('audio'), async (req, res) => {
13 try {
14 let result;
15
16 if (req.file) {
17 const formData = new FormData();
18 formData.append('audio', req.file.buffer, req.file.originalname);
19
20 const response = await axios.post(
21 `${API_URL}/v1/listen`,
22 formData,
23 {
24 headers: {
25 'Authorization': `Token ${LICENSE_KEY}`,
26 ...formData.getHeaders()
27 }
28 }
29 );
30 result = response.data;
31 } else if (req.body.url) {
32 const response = await axios.post(
33 `${API_URL}/v1/listen`,
34 { url: req.body.url },
35 {
36 headers: {
37 'Authorization': `Token ${LICENSE_KEY}`,
38 'Content-Type': 'application/json'
39 }
40 }
41 );
42 result = response.data;
43 } else {
44 return res.status(400).json({ error: 'No audio file or URL provided' });
45 }
46
47 res.json(result);
48 } catch (error) {
49 console.error('Transcription error:', error.response?.data || error.message);
50 res.status(500).json({ error: 'Transcription failed' });
51 }
52});
53
54app.listen(3000, () => {
55 console.log('Server running on port 3000');
56});

Go Examples

Basic Client

1package main
2
3import (
4 "bytes"
5 "encoding/json"
6 "fmt"
7 "io/ioutil"
8 "net/http"
9 "os"
10 "time"
11)
12
13type TranscriptionRequest struct {
14 URL string `json:"url"`
15 Punctuate bool `json:"punctuate,omitempty"`
16 Language string `json:"language,omitempty"`
17}
18
19type TranscriptionResult struct {
20 RequestID string `json:"request_id"`
21 Text string `json:"text"`
22 Confidence float64 `json:"confidence"`
23 Duration float64 `json:"duration"`
24}
25
26type SmallestClient struct {
27 APIUrl string
28 LicenseKey string
29 HTTPClient *http.Client
30}
31
32func NewClient(apiURL, licenseKey string) *SmallestClient {
33 return &SmallestClient{
34 APIUrl: apiURL,
35 LicenseKey: licenseKey,
36 HTTPClient: &http.Client{Timeout: 5 * time.Minute},
37 }
38}
39
40func (c *SmallestClient) Transcribe(req TranscriptionRequest) (*TranscriptionResult, error) {
41 jsonData, err := json.Marshal(req)
42 if err != nil {
43 return nil, err
44 }
45
46 httpReq, err := http.NewRequest("POST", c.APIUrl+"/v1/listen", bytes.NewBuffer(jsonData))
47 if err != nil {
48 return nil, err
49 }
50
51 httpReq.Header.Set("Authorization", "Token "+c.LicenseKey)
52 httpReq.Header.Set("Content-Type", "application/json")
53
54 resp, err := c.HTTPClient.Do(httpReq)
55 if err != nil {
56 return nil, err
57 }
58 defer resp.Body.Close()
59
60 if resp.StatusCode != http.StatusOK {
61 body, _ := ioutil.ReadAll(resp.Body)
62 return nil, fmt.Errorf("API error: %s", string(body))
63 }
64
65 var result TranscriptionResult
66 if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
67 return nil, err
68 }
69
70 return &result, nil
71}
72
73func main() {
74 client := NewClient(
75 "http://localhost:7100",
76 os.Getenv("LICENSE_KEY"),
77 )
78
79 result, err := client.Transcribe(TranscriptionRequest{
80 URL: "https://example.com/audio.wav",
81 Punctuate: true,
82 Language: "en",
83 })
84
85 if err != nil {
86 fmt.Printf("Error: %v\n", err)
87 return
88 }
89
90 fmt.Printf("Transcription: %s\n", result.Text)
91 fmt.Printf("Confidence: %.2f\n", result.Confidence)
92}

Best Practices

Never hardcode credentials:

$export LICENSE_KEY="your-license-key"
$export API_URL="https://api.example.com"

Always handle errors gracefully:

1try:
2 result = client.transcribe(audio_url)
3except requests.exceptions.Timeout:
4 print("Request timed out")
5except requests.exceptions.HTTPError as e:
6 print(f"HTTP error: {e.response.status_code}")
7except Exception as e:
8 print(f"Unexpected error: {e}")

Implement exponential backoff:

1from tenacity import retry, stop_after_attempt, wait_exponential
2
3@retry(
4 stop=stop_after_attempt(3),
5 wait=wait_exponential(multiplier=1, min=4, max=10)
6)
7def transcribe_with_retry(audio_url):
8 return client.transcribe(audio_url)

Reuse connections for better performance:

1session = requests.Session()
2session.mount('http://', HTTPAdapter(pool_connections=10, pool_maxsize=10))

Track API usage and errors:

1import logging
2
3logging.basicConfig(level=logging.INFO)
4logger = logging.getLogger(__name__)
5
6logger.info(f"Transcribing: {audio_url}")
7result = client.transcribe(audio_url)
8logger.info(f"Success: {result['request_id']}")

What’s Next?