Skip to content

Commit 272e313

Browse files
feat(cmd): add API validation tool for quick configuration testing
1 parent 2471af8 commit 272e313

File tree

1 file changed

+30
-6
lines changed

1 file changed

+30
-6
lines changed

cmd/validate-api/main.go

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,37 +15,44 @@ import (
1515
)
1616

1717
func main() {
18-
// Command line options
18+
// --- Command line flags ---
19+
// These allow the user to override the API key, set a custom timeout, and enable verbose output.
1920
var (
2021
apiKey = flag.String("api-key", "", "OpenAI API key (overrides OPENAI_API_KEY)")
2122
timeout = flag.Duration("timeout", 10*time.Second, "Request timeout")
2223
verbose = flag.Bool("verbose", false, "Show request details")
2324
)
2425
flag.Parse()
2526

26-
// Get API key
27+
// --- API Key Resolution ---
28+
// Priority: --api-key flag > OPENAI_API_KEY env var.
2729
key := *apiKey
2830
if key == "" {
2931
key = os.Getenv("OPENAI_API_KEY")
3032
}
3133
if key == "" {
34+
// Fail fast if no API key is provided.
3235
fmt.Fprintln(os.Stderr, "No API key provided")
3336
fmt.Fprintln(os.Stderr, " Use:")
3437
fmt.Fprintln(os.Stderr, " • --api-key 'sk-...'")
3538
fmt.Fprintln(os.Stderr, " • or export OPENAI_API_KEY='sk-...'")
3639
os.Exit(1)
3740
}
3841

39-
// Create client with timeout
42+
// --- Context with Timeout ---
43+
// Ensures the request does not hang indefinitely.
4044
ctx, cancel := context.WithTimeout(context.Background(), *timeout)
4145
defer cancel()
4246

47+
// --- Client Initialization ---
48+
// The client is configured with the resolved API key and timeout.
4349
client := openai.NewClient(
4450
option.WithAPIKey(key),
4551
option.WithRequestTimeout(*timeout),
4652
)
4753

48-
// Verbose mode
54+
// --- Verbose Logging ---
55+
// Show diagnostic info if requested.
4956
if *verbose {
5057
fmt.Printf("Testing OpenAI API connection...\n")
5158
fmt.Printf("Timeout: %v\n", *timeout)
@@ -57,7 +64,8 @@ func main() {
5764
fmt.Println()
5865
}
5966

60-
// Test connection
67+
// --- API Validation ---
68+
// The core check: attempt to list models. This is a lightweight endpoint and a good proxy for API health.
6169
if err := validateAPI(ctx, client); err != nil {
6270
handleError(err)
6371
os.Exit(1)
@@ -69,16 +77,21 @@ func main() {
6977
}
7078
}
7179

80+
// validateAPI attempts a simple API call to verify connectivity and authentication.
81+
// Returns an error if the call fails for any reason.
7282
func validateAPI(ctx context.Context, client openai.Client) error {
73-
// Simple test: list models
83+
// Simple test: list models (minimal permissions required, fast response)
7484
_, err := client.Models.List(ctx)
7585
return err
7686
}
7787

88+
// handleError provides structured, actionable error messages for common API issues.
89+
// This function distinguishes between API errors (with status codes) and generic/network errors.
7890
func handleError(err error) {
7991
fmt.Fprintf(os.Stderr, "API Error: %v\n\n", err)
8092

8193
if apiErr, ok := err.(*apierror.Error); ok {
94+
// Handle known API error codes with specific guidance.
8295
switch apiErr.StatusCode {
8396
case 401:
8497
fmt.Fprintln(os.Stderr, " Authentication issue:")
@@ -98,10 +111,12 @@ func handleError(err error) {
98111
fmt.Fprintln(os.Stderr, " • OpenAI service is temporarily unavailable")
99112
fmt.Fprintln(os.Stderr, " • Try again in a few minutes")
100113
default:
114+
// For unhandled status codes, print the code and message for debugging.
101115
fmt.Fprintf(os.Stderr, " Error code: %d\n", apiErr.StatusCode)
102116
fmt.Fprintf(os.Stderr, " Message: %s\n", apiErr.Message)
103117
}
104118
} else {
119+
// Handle network and unknown errors.
105120
errStr := err.Error()
106121
if strings.Contains(errStr, "Connection refused") {
107122
fmt.Fprintln(os.Stderr, " Connection issue:")
@@ -112,9 +127,18 @@ func handleError(err error) {
112127
fmt.Fprintln(os.Stderr, " • Check your internet connection")
113128
fmt.Fprintln(os.Stderr, " • Increase timeout with --timeout 30s")
114129
} else {
130+
// Catch-all for unexpected errors.
115131
fmt.Fprintf(os.Stderr, "Unknown error: %s\n", errStr)
116132
}
117133
}
118134

135+
// Always provide a pointer to the official error documentation for further troubleshooting.
119136
fmt.Fprintln(os.Stderr, "\n For more help: https://platform.openai.com/docs/guides/error-codes")
120137
}
138+
139+
// ---
140+
// TODO (future improvements):
141+
// - Add support for multiple API keys
142+
// - Add support for multiple models
143+
// - Add support for multiple endpoints
144+
// - Add support for multiple API versions

0 commit comments

Comments
 (0)