diff --git a/client.go b/client.go index 997e355e..f496f966 100644 --- a/client.go +++ b/client.go @@ -261,7 +261,18 @@ func NewClient(ctx context.Context, cc *ClientConfig) (*Client, error) { } cc.HTTPClient = client } else { - cc.HTTPClient = &http.Client{} + // If credentials are provided for Gemini API, create an authenticated HTTP client + if cc.Credentials != nil { + client, err := httptransport.NewClient(&httptransport.Options{ + Credentials: cc.Credentials, + }) + if err != nil { + return nil, fmt.Errorf("failed to create HTTP client: %w", err) + } + cc.HTTPClient = client + } else { + cc.HTTPClient = &http.Client{} + } } } diff --git a/client_test.go b/client_test.go index 1ca432e2..14be46bf 100644 --- a/client_test.go +++ b/client_test.go @@ -433,6 +433,82 @@ func TestNewClient(t *testing.T) { } +func TestCustomCredentialsWithGeminiAPI(t *testing.T) { + // This test verifies that custom credentials are properly used when creating a client + // with the Gemini API backend. + ctx := context.Background() + + // Create mock credentials + mockCreds := &auth.Credentials{} + + // Test case: Gemini API with custom credentials + t.Run("GeminiAPI with custom credentials", func(t *testing.T) { + client, err := NewClient(ctx, &ClientConfig{ + Backend: BackendGeminiAPI, + APIKey: "test-api-key", + Credentials: mockCreds, + }) + if err != nil { + t.Fatalf("Expected no error, got %v", err) + } + + // Verify the credentials were correctly passed to the client config + if client.clientConfig.Credentials != mockCreds { + t.Errorf("Credentials were not properly set in client config") + } + + // Verify that HTTPClient is not nil (it should have been created) + if client.clientConfig.HTTPClient == nil { + t.Errorf("Expected HTTPClient to be created, got nil") + } + }) + + // Test case: Custom HTTP options with Gemini API + t.Run("GeminiAPI with custom HTTP options", func(t *testing.T) { + customOptions := HTTPOptions{ + APIVersion: "custom-version", + BaseURL: "https://custom-url.example.com/", + } + + client, err := NewClient(ctx, &ClientConfig{ + Backend: BackendGeminiAPI, + APIKey: "test-api-key", + HTTPOptions: customOptions, + }) + if err != nil { + t.Fatalf("Expected no error, got %v", err) + } + + // Verify HTTP options were correctly passed to the client config + if client.clientConfig.HTTPOptions.APIVersion != customOptions.APIVersion { + t.Errorf("Expected APIVersion %q, got %q", customOptions.APIVersion, client.clientConfig.HTTPOptions.APIVersion) + } + if client.clientConfig.HTTPOptions.BaseURL != customOptions.BaseURL { + t.Errorf("Expected BaseURL %q, got %q", customOptions.BaseURL, client.clientConfig.HTTPOptions.BaseURL) + } + }) + + // Test case: Gemini API with custom credentials and HTTP client + t.Run("GeminiAPI with custom credentials and HTTP client", func(t *testing.T) { + customHTTPClient := &http.Client{Timeout: 10 * time.Second} + + client, err := NewClient(ctx, &ClientConfig{ + Backend: BackendGeminiAPI, + APIKey: "test-api-key", + Credentials: mockCreds, + HTTPClient: customHTTPClient, + }) + if err != nil { + t.Fatalf("Expected no error, got %v", err) + } + + // Verify custom HTTP client was used + if client.clientConfig.HTTPClient != customHTTPClient { + t.Errorf("Expected custom HTTP client to be used") + } + }) +} + func TestClientConfigHTTPOptions(t *testing.T) { tests := []struct { name string diff --git a/example_test.go b/example_test.go index 36ef64b8..12f3a0f4 100644 --- a/example_test.go +++ b/example_test.go @@ -21,7 +21,9 @@ import ( "io" "log" "net/http" + "time" + "cloud.google.com/go/auth" "google.golang.org/genai" ) @@ -61,6 +63,47 @@ func ExampleNewClient_geminiapi() { fmt.Println(client.ClientConfig().APIKey) } +// This example shows how to create a new client for Gemini API with custom credentials and HTTP configuration. +func ExampleNewClient_geminiapi_withCustomCredentials() { + ctx := context.Background() + + // In a real application, you would create credentials from a service account + // For example, using auth.DetectDefault() or other credential methods + // Here we just demonstrate with a mock credentials object + creds := &auth.Credentials{} + + // Create a custom HTTP client with specific timeouts + customHTTPClient := &http.Client{ + Timeout: 30 * time.Second, + } + + // Create client with custom credentials and HTTP configuration + client, err := genai.NewClient(ctx, &genai.ClientConfig{ + APIKey: apiKey, + Backend: genai.BackendGeminiAPI, + Credentials: creds, + HTTPClient: customHTTPClient, + HTTPOptions: genai.HTTPOptions{ + APIVersion: "v1beta", // Specify API version if needed + }, + }) + if err != nil { + log.Fatalf("failed to create client: %v", err) + } + + // The client now uses the custom credentials and HTTP configuration + // for all API calls + result, err := client.Models.GenerateContent(ctx, + "gemini-2.0-flash", + genai.Text("Tell me about cloud credentials?"), + nil, + ) + if err != nil { + log.Fatal(err) + } + debugPrint(result) +} + // This example shows how to call the GenerateContent method with a simple text to Vertex AI. func ExampleModels_GenerateContent_text_vertexai() { ctx := context.Background()