1// Package main is the main entry point for the HTTP server that serves
 2// inference providers.
 3package main
 4
 5import (
 6	"encoding/json"
 7	"log"
 8	"net/http"
 9	"time"
10
11	"github.com/charmbracelet/catwalk/internal/providers"
12	"github.com/prometheus/client_golang/prometheus"
13	"github.com/prometheus/client_golang/prometheus/promauto"
14	"github.com/prometheus/client_golang/prometheus/promhttp"
15)
16
17var counter = promauto.NewCounter(prometheus.CounterOpts{
18	Namespace: "catwalk",
19	Subsystem: "providers",
20	Name:      "requests_total",
21	Help:      "Total number of requests to the providers endpoint",
22})
23
24func providersHandler(w http.ResponseWriter, r *http.Request) {
25	w.Header().Set("Content-Type", "application/json")
26	if r.Method == http.MethodHead {
27		return
28	}
29
30	if r.Method != http.MethodGet {
31		http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
32		return
33	}
34
35	counter.Inc()
36	allProviders := providers.GetAll()
37	if err := json.NewEncoder(w).Encode(allProviders); err != nil {
38		http.Error(w, "Internal server error", http.StatusInternalServerError)
39		return
40	}
41}
42
43func main() {
44	mux := http.NewServeMux()
45	mux.HandleFunc("/providers", providersHandler)
46	mux.HandleFunc("/healthz", func(w http.ResponseWriter, _ *http.Request) {
47		w.WriteHeader(http.StatusOK)
48		_, _ = w.Write([]byte("OK"))
49	})
50	mux.Handle("/metrics", promhttp.Handler())
51
52	server := &http.Server{
53		Addr:         ":8080",
54		Handler:      mux,
55		ReadTimeout:  15 * time.Second,
56		WriteTimeout: 15 * time.Second,
57		IdleTimeout:  60 * time.Second,
58	}
59
60	log.Println("Server starting on :8080")
61	if err := server.ListenAndServe(); err != nil {
62		log.Fatal("Server failed to start:", err)
63	}
64}