mirror of
https://github.com/router-for-me/CLIProxyAPI.git
synced 2026-02-02 20:40:52 +08:00
refactor(watcher): Move API key client creation to watcher package
This commit is contained in:
@@ -9,7 +9,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"net/http"
|
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@@ -26,7 +25,7 @@ import (
|
|||||||
"github.com/luispater/CLIProxyAPI/v5/internal/client"
|
"github.com/luispater/CLIProxyAPI/v5/internal/client"
|
||||||
"github.com/luispater/CLIProxyAPI/v5/internal/config"
|
"github.com/luispater/CLIProxyAPI/v5/internal/config"
|
||||||
"github.com/luispater/CLIProxyAPI/v5/internal/interfaces"
|
"github.com/luispater/CLIProxyAPI/v5/internal/interfaces"
|
||||||
"github.com/luispater/CLIProxyAPI/v5/internal/util"
|
"github.com/luispater/CLIProxyAPI/v5/internal/misc"
|
||||||
"github.com/luispater/CLIProxyAPI/v5/internal/watcher"
|
"github.com/luispater/CLIProxyAPI/v5/internal/watcher"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"github.com/tidwall/gjson"
|
"github.com/tidwall/gjson"
|
||||||
@@ -75,6 +74,7 @@ func StartService(cfg *config.Config, configPath string) {
|
|||||||
|
|
||||||
// Process only JSON files in the auth directory to load authentication tokens.
|
// Process only JSON files in the auth directory to load authentication tokens.
|
||||||
if !info.IsDir() && strings.HasSuffix(info.Name(), ".json") {
|
if !info.IsDir() && strings.HasSuffix(info.Name(), ".json") {
|
||||||
|
misc.LogCredentialSeparator()
|
||||||
log.Debugf("Loading token from: %s", path)
|
log.Debugf("Loading token from: %s", path)
|
||||||
data, errReadFile := os.ReadFile(path)
|
data, errReadFile := os.ReadFile(path)
|
||||||
if errReadFile != nil {
|
if errReadFile != nil {
|
||||||
@@ -170,7 +170,7 @@ func StartService(cfg *config.Config, configPath string) {
|
|||||||
log.Fatalf("Error walking auth directory: %v", err)
|
log.Fatalf("Error walking auth directory: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
apiKeyClients, glAPIKeyCount, claudeAPIKeyCount, codexAPIKeyCount, openAICompatCount := buildAPIKeyClients(cfg)
|
apiKeyClients, glAPIKeyCount, claudeAPIKeyCount, codexAPIKeyCount, openAICompatCount := watcher.BuildAPIKeyClients(cfg)
|
||||||
|
|
||||||
totalNewClients := len(cliClients) + len(apiKeyClients)
|
totalNewClients := len(cliClients) + len(apiKeyClients)
|
||||||
log.Infof("full client load complete - %d clients (%d auth files + %d GL API keys + %d Claude API keys + %d Codex keys + %d OpenAI-compat)",
|
log.Infof("full client load complete - %d clients (%d auth files + %d GL API keys + %d Claude API keys + %d Codex keys + %d OpenAI-compat)",
|
||||||
@@ -377,57 +377,3 @@ func clientsToSlice(clientMap map[string]interfaces.Client) []interfaces.Client
|
|||||||
}
|
}
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
// buildAPIKeyClients creates clients from API keys in the config
|
|
||||||
func buildAPIKeyClients(cfg *config.Config) (map[string]interfaces.Client, int, int, int, int) {
|
|
||||||
apiKeyClients := make(map[string]interfaces.Client)
|
|
||||||
glAPIKeyCount := 0
|
|
||||||
claudeAPIKeyCount := 0
|
|
||||||
codexAPIKeyCount := 0
|
|
||||||
openAICompatCount := 0
|
|
||||||
|
|
||||||
if len(cfg.GlAPIKey) > 0 {
|
|
||||||
for _, key := range cfg.GlAPIKey {
|
|
||||||
httpClient := util.SetProxy(cfg, &http.Client{})
|
|
||||||
log.Debug("Initializing with Generative Language API Key...")
|
|
||||||
cliClient := client.NewGeminiClient(httpClient, cfg, key)
|
|
||||||
apiKeyClients[cliClient.GetClientID()] = cliClient
|
|
||||||
glAPIKeyCount++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(cfg.ClaudeKey) > 0 {
|
|
||||||
for i := range cfg.ClaudeKey {
|
|
||||||
log.Debug("Initializing with Claude API Key...")
|
|
||||||
cliClient := client.NewClaudeClientWithKey(cfg, i)
|
|
||||||
apiKeyClients[cliClient.GetClientID()] = cliClient
|
|
||||||
claudeAPIKeyCount++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(cfg.CodexKey) > 0 {
|
|
||||||
for i := range cfg.CodexKey {
|
|
||||||
log.Debug("Initializing with Codex API Key...")
|
|
||||||
cliClient := client.NewCodexClientWithKey(cfg, i)
|
|
||||||
apiKeyClients[cliClient.GetClientID()] = cliClient
|
|
||||||
codexAPIKeyCount++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(cfg.OpenAICompatibility) > 0 {
|
|
||||||
for _, compatConfig := range cfg.OpenAICompatibility {
|
|
||||||
for i := 0; i < len(compatConfig.APIKeys); i++ {
|
|
||||||
log.Debugf("Initializing OpenAI compatibility client for provider: %s", compatConfig.Name)
|
|
||||||
compatClient, errClient := client.NewOpenAICompatibilityClient(cfg, &compatConfig, i)
|
|
||||||
if errClient != nil {
|
|
||||||
log.Errorf("failed to create OpenAI compatibility client for %s: %v", compatConfig.Name, errClient)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
apiKeyClients[compatClient.GetClientID()] = compatClient
|
|
||||||
openAICompatCount++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return apiKeyClients, glAPIKeyCount, claudeAPIKeyCount, codexAPIKeyCount, openAICompatCount
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -2,10 +2,13 @@ package misc
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var credentialSeparator = strings.Repeat("-", 70)
|
||||||
|
|
||||||
// LogSavingCredentials emits a consistent log message when persisting auth material.
|
// LogSavingCredentials emits a consistent log message when persisting auth material.
|
||||||
func LogSavingCredentials(path string) {
|
func LogSavingCredentials(path string) {
|
||||||
if path == "" {
|
if path == "" {
|
||||||
@@ -14,3 +17,8 @@ func LogSavingCredentials(path string) {
|
|||||||
// Use filepath.Clean so logs remain stable even if callers pass redundant separators.
|
// Use filepath.Clean so logs remain stable even if callers pass redundant separators.
|
||||||
log.Infof("Saving credentials to %s", filepath.Clean(path))
|
log.Infof("Saving credentials to %s", filepath.Clean(path))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LogCredentialSeparator adds a visual separator to group auth/key processing logs.
|
||||||
|
func LogCredentialSeparator() {
|
||||||
|
log.Info(credentialSeparator)
|
||||||
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import (
|
|||||||
"github.com/luispater/CLIProxyAPI/v5/internal/client"
|
"github.com/luispater/CLIProxyAPI/v5/internal/client"
|
||||||
"github.com/luispater/CLIProxyAPI/v5/internal/config"
|
"github.com/luispater/CLIProxyAPI/v5/internal/config"
|
||||||
"github.com/luispater/CLIProxyAPI/v5/internal/interfaces"
|
"github.com/luispater/CLIProxyAPI/v5/internal/interfaces"
|
||||||
|
"github.com/luispater/CLIProxyAPI/v5/internal/misc"
|
||||||
"github.com/luispater/CLIProxyAPI/v5/internal/util"
|
"github.com/luispater/CLIProxyAPI/v5/internal/util"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"github.com/tidwall/gjson"
|
"github.com/tidwall/gjson"
|
||||||
@@ -302,7 +303,7 @@ func (w *Watcher) reloadClients() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create new API key clients based on the new config
|
// Create new API key clients based on the new config
|
||||||
newAPIKeyClients, glAPIKeyCount, claudeAPIKeyCount, codexAPIKeyCount, openAICompatCount := buildAPIKeyClients(cfg)
|
newAPIKeyClients, glAPIKeyCount, claudeAPIKeyCount, codexAPIKeyCount, openAICompatCount := BuildAPIKeyClients(cfg)
|
||||||
log.Debugf("created %d new API key clients", len(newAPIKeyClients))
|
log.Debugf("created %d new API key clients", len(newAPIKeyClients))
|
||||||
|
|
||||||
// Load file-based clients
|
// Load file-based clients
|
||||||
@@ -604,6 +605,7 @@ func (w *Watcher) loadFileClients(cfg *config.Config) (map[string]interfaces.Cli
|
|||||||
}
|
}
|
||||||
if !info.IsDir() && strings.HasSuffix(info.Name(), ".json") {
|
if !info.IsDir() && strings.HasSuffix(info.Name(), ".json") {
|
||||||
authFileCount++
|
authFileCount++
|
||||||
|
misc.LogCredentialSeparator()
|
||||||
log.Debugf("processing auth file %d: %s", authFileCount, filepath.Base(path))
|
log.Debugf("processing auth file %d: %s", authFileCount, filepath.Base(path))
|
||||||
if cliClient, errCreate := w.createClientFromFile(path, cfg); errCreate == nil && cliClient != nil {
|
if cliClient, errCreate := w.createClientFromFile(path, cfg); errCreate == nil && cliClient != nil {
|
||||||
newClients[path] = cliClient
|
newClients[path] = cliClient
|
||||||
@@ -622,8 +624,7 @@ func (w *Watcher) loadFileClients(cfg *config.Config) (map[string]interfaces.Cli
|
|||||||
return newClients, successfulAuthCount
|
return newClients, successfulAuthCount
|
||||||
}
|
}
|
||||||
|
|
||||||
// buildAPIKeyClients creates clients from API keys in the config.
|
func BuildAPIKeyClients(cfg *config.Config) (map[string]interfaces.Client, int, int, int, int) {
|
||||||
func buildAPIKeyClients(cfg *config.Config) (map[string]interfaces.Client, int, int, int, int) {
|
|
||||||
apiKeyClients := make(map[string]interfaces.Client)
|
apiKeyClients := make(map[string]interfaces.Client)
|
||||||
glAPIKeyCount := 0
|
glAPIKeyCount := 0
|
||||||
claudeAPIKeyCount := 0
|
claudeAPIKeyCount := 0
|
||||||
@@ -633,6 +634,8 @@ func buildAPIKeyClients(cfg *config.Config) (map[string]interfaces.Client, int,
|
|||||||
if len(cfg.GlAPIKey) > 0 {
|
if len(cfg.GlAPIKey) > 0 {
|
||||||
for _, key := range cfg.GlAPIKey {
|
for _, key := range cfg.GlAPIKey {
|
||||||
httpClient := util.SetProxy(cfg, &http.Client{})
|
httpClient := util.SetProxy(cfg, &http.Client{})
|
||||||
|
misc.LogCredentialSeparator()
|
||||||
|
log.Debug("Initializing with Gemini API Key...")
|
||||||
cliClient := client.NewGeminiClient(httpClient, cfg, key)
|
cliClient := client.NewGeminiClient(httpClient, cfg, key)
|
||||||
apiKeyClients[cliClient.GetClientID()] = cliClient
|
apiKeyClients[cliClient.GetClientID()] = cliClient
|
||||||
glAPIKeyCount++
|
glAPIKeyCount++
|
||||||
@@ -640,6 +643,8 @@ func buildAPIKeyClients(cfg *config.Config) (map[string]interfaces.Client, int,
|
|||||||
}
|
}
|
||||||
if len(cfg.ClaudeKey) > 0 {
|
if len(cfg.ClaudeKey) > 0 {
|
||||||
for i := range cfg.ClaudeKey {
|
for i := range cfg.ClaudeKey {
|
||||||
|
misc.LogCredentialSeparator()
|
||||||
|
log.Debug("Initializing with Claude API Key...")
|
||||||
cliClient := client.NewClaudeClientWithKey(cfg, i)
|
cliClient := client.NewClaudeClientWithKey(cfg, i)
|
||||||
apiKeyClients[cliClient.GetClientID()] = cliClient
|
apiKeyClients[cliClient.GetClientID()] = cliClient
|
||||||
claudeAPIKeyCount++
|
claudeAPIKeyCount++
|
||||||
@@ -647,6 +652,8 @@ func buildAPIKeyClients(cfg *config.Config) (map[string]interfaces.Client, int,
|
|||||||
}
|
}
|
||||||
if len(cfg.CodexKey) > 0 {
|
if len(cfg.CodexKey) > 0 {
|
||||||
for i := range cfg.CodexKey {
|
for i := range cfg.CodexKey {
|
||||||
|
misc.LogCredentialSeparator()
|
||||||
|
log.Debug("Initializing with Codex API Key...")
|
||||||
cliClient := client.NewCodexClientWithKey(cfg, i)
|
cliClient := client.NewCodexClientWithKey(cfg, i)
|
||||||
apiKeyClients[cliClient.GetClientID()] = cliClient
|
apiKeyClients[cliClient.GetClientID()] = cliClient
|
||||||
codexAPIKeyCount++
|
codexAPIKeyCount++
|
||||||
@@ -655,9 +662,11 @@ func buildAPIKeyClients(cfg *config.Config) (map[string]interfaces.Client, int,
|
|||||||
if len(cfg.OpenAICompatibility) > 0 {
|
if len(cfg.OpenAICompatibility) > 0 {
|
||||||
for _, compatConfig := range cfg.OpenAICompatibility {
|
for _, compatConfig := range cfg.OpenAICompatibility {
|
||||||
for i := 0; i < len(compatConfig.APIKeys); i++ {
|
for i := 0; i < len(compatConfig.APIKeys); i++ {
|
||||||
|
misc.LogCredentialSeparator()
|
||||||
|
log.Debugf("Initializing OpenAI compatibility client for provider: %s", compatConfig.Name)
|
||||||
compatClient, errClient := client.NewOpenAICompatibilityClient(cfg, &compatConfig, i)
|
compatClient, errClient := client.NewOpenAICompatibilityClient(cfg, &compatConfig, i)
|
||||||
if errClient != nil {
|
if errClient != nil {
|
||||||
log.Errorf("failed to create OpenAI-compatibility client for %s: %v", compatConfig.Name, errClient)
|
log.Errorf("failed to create OpenAI compatibility client for %s: %v", compatConfig.Name, errClient)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
apiKeyClients[compatClient.GetClientID()] = compatClient
|
apiKeyClients[compatClient.GetClientID()] = compatClient
|
||||||
|
|||||||
Reference in New Issue
Block a user