Skip to content
Open
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: 2 additions & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
portincmd "github.com/Bandwidth/cli/cmd/portin"
quickstartcmd "github.com/Bandwidth/cli/cmd/quickstart"
recordingcmd "github.com/Bandwidth/cli/cmd/recording"
samplecmd "github.com/Bandwidth/cli/cmd/sample"
shortcodecmd "github.com/Bandwidth/cli/cmd/shortcode"
sipcmd "github.com/Bandwidth/cli/cmd/sip"
sitecmd "github.com/Bandwidth/cli/cmd/site"
Expand Down Expand Up @@ -115,6 +116,7 @@ func init() {
rootCmd.AddCommand(transcriptioncmd.Cmd)
rootCmd.AddCommand(bxmlcmd.Cmd)
rootCmd.AddCommand(quickstartcmd.Cmd)
rootCmd.AddCommand(samplecmd.Cmd)
rootCmd.AddCommand(vcpcmd.Cmd)
rootCmd.AddCommand(tendlccmd.Cmd)
rootCmd.AddCommand(shortcodecmd.Cmd)
Expand Down
82 changes: 82 additions & 0 deletions cmd/sample/catalog.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package sample

// envPrompt describes an environment variable that a sample app requires beyond
// the standard Bandwidth credentials (which are auto-populated from band auth).
type envPrompt struct {
Key string // env var name written to .env
Flag string // CLI flag name (without --)
Description string // shown in --help
}

// langSetup describes how to install dependencies and run the app for a given language.
type langSetup struct {
// ReqFile is the path (relative to clone root) of the dependency manifest.
ReqFile string
// AppDir is the working directory to cd into before running.
AppDir string
// InstallCmd is the command to install dependencies (run once after clone).
InstallCmd []string
// RunCmd is the command to start the app (run in the AppDir).
RunCmd []string
// HealthPath is the HTTP path polled to detect a ready server.
HealthPath string
}

// SampleEntry describes one sample app and its variants.
type SampleEntry struct {
Description string
// Repos maps language name → GitHub clone URL.
Repos map[string]string
// ExtraEnv lists environment variables required beyond BW_* credentials.
ExtraEnv []envPrompt
// Setup maps language name → build/run instructions.
Setup map[string]langSetup
// Port is the default local port the app listens on.
Port int
}

// catalog is the authoritative list of runnable Bandwidth sample apps.
var catalog = map[string]*SampleEntry{
"live-assistant": {
Description: "Real-time AI voice assistant powered by OpenAI Realtime API",
Repos: map[string]string{
"python": "https://github.com/Bandwidth-Samples/openai-live-websockets-python",
},
ExtraEnv: []envPrompt{
{Key: "OPENAI_API_KEY", Flag: "openai-key", Description: "OpenAI API key (must have Realtime API access)"},
{Key: "TRANSFER_TO", Flag: "transfer-to", Description: "Phone number to transfer calls to (E.164, e.g. +19195551234)"},
},
Setup: map[string]langSetup{
"python": {
AppDir: "app",
InstallCmd: []string{".venv/bin/pip", "install", "-q", "-r", "app/requirements.txt"},
RunCmd: []string{".venv/bin/python3", "main.py"},
HealthPath: "/health",
},
},
Port: 3000,
},
"voice-gather": {
Description: "In-call DTMF gather example",
Repos: map[string]string{
"java": "https://github.com/Bandwidth-Samples/in-call-gather-java",
"node": "https://github.com/Bandwidth-Samples/in-call-gather-nodejs",
"python": "https://github.com/Bandwidth-Samples/in-call-gather-python",
},
Setup: map[string]langSetup{
"python": {
AppDir: ".",
InstallCmd: []string{".venv/bin/pip", "install", "-q", "-r", "requirements.txt"},
RunCmd: []string{".venv/bin/python3", "app.py"},
HealthPath: "/",
},
"node": {
AppDir: ".",
InstallCmd: []string{"npm", "install", "--silent"},
RunCmd: []string{"node", "index.js"},
HealthPath: "/",
},
},
Port: 3000,
},
}
35 changes: 35 additions & 0 deletions cmd/sample/list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package sample

import (
"fmt"
"sort"

"github.com/spf13/cobra"
)

var listCmd = &cobra.Command{
Use: "list",
Short: "List available sample applications",
RunE: runList,
}

func runList(cmd *cobra.Command, args []string) error {
names := make([]string, 0, len(catalog))
for n := range catalog {
names = append(names, n)
}
sort.Strings(names)

for _, name := range names {
entry := catalog[name]
langs := make([]string, 0, len(entry.Repos))
for l := range entry.Repos {
langs = append(langs, l)
}
sort.Strings(langs)

fmt.Printf("%-20s %s\n", name, entry.Description)
fmt.Printf("%-20s languages: %v\n\n", "", langs)
}
return nil
}
Loading
Loading