File tree Expand file tree Collapse file tree
Connectors.Google.UnitTests/Core Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -422,6 +422,38 @@ public async Task ItCreatesPostRequestWithSemanticKernelVersionHeaderAsync()
422422 Assert . Equal ( expectedVersion , header ) ;
423423 }
424424
425+ [ Fact ]
426+ public async Task ItCreatesPostRequestWithApiKeyInHeaderAsync ( )
427+ {
428+ // Arrange
429+ var client = this . CreateChatCompletionClient ( ) ;
430+ var chatHistory = CreateSampleChatHistory ( ) ;
431+
432+ // Act
433+ await client . GenerateChatMessageAsync ( chatHistory ) ;
434+
435+ // Assert
436+ Assert . NotNull ( this . _messageHandlerStub . RequestHeaders ) ;
437+ var apiKeyHeader = this . _messageHandlerStub . RequestHeaders . GetValues ( "x-goog-api-key" ) . SingleOrDefault ( ) ;
438+ Assert . NotNull ( apiKeyHeader ) ;
439+ Assert . Equal ( "fake-key" , apiKeyHeader ) ;
440+ }
441+
442+ [ Fact ]
443+ public async Task ItCreatesPostRequestWithoutApiKeyInUrlAsync ( )
444+ {
445+ // Arrange
446+ var client = this . CreateChatCompletionClient ( ) ;
447+ var chatHistory = CreateSampleChatHistory ( ) ;
448+
449+ // Act
450+ await client . GenerateChatMessageAsync ( chatHistory ) ;
451+
452+ // Assert
453+ Assert . NotNull ( this . _messageHandlerStub . RequestUri ) ;
454+ Assert . DoesNotContain ( "key=" , this . _messageHandlerStub . RequestUri . ToString ( ) ) ;
455+ }
456+
425457 [ Fact ]
426458 public async Task ItCreatesPostRequestWithResponseSchemaPropertyAsync ( )
427459 {
Original file line number Diff line number Diff line change @@ -392,6 +392,38 @@ public async Task ItCreatesPostRequestWithSemanticKernelVersionHeaderAsync()
392392 Assert . Equal ( expectedVersion , header ) ;
393393 }
394394
395+ [ Fact ]
396+ public async Task ItCreatesPostRequestWithApiKeyInHeaderAsync ( )
397+ {
398+ // Arrange
399+ var client = this . CreateChatCompletionClient ( ) ;
400+ var chatHistory = CreateSampleChatHistory ( ) ;
401+
402+ // Act
403+ await client . StreamGenerateChatMessageAsync ( chatHistory ) . ToListAsync ( ) ;
404+
405+ // Assert
406+ Assert . NotNull ( this . _messageHandlerStub . RequestHeaders ) ;
407+ var apiKeyHeader = this . _messageHandlerStub . RequestHeaders . GetValues ( "x-goog-api-key" ) . SingleOrDefault ( ) ;
408+ Assert . NotNull ( apiKeyHeader ) ;
409+ Assert . Equal ( "fake-key" , apiKeyHeader ) ;
410+ }
411+
412+ [ Fact ]
413+ public async Task ItCreatesPostRequestWithoutApiKeyInUrlAsync ( )
414+ {
415+ // Arrange
416+ var client = this . CreateChatCompletionClient ( ) ;
417+ var chatHistory = CreateSampleChatHistory ( ) ;
418+
419+ // Act
420+ await client . StreamGenerateChatMessageAsync ( chatHistory ) . ToListAsync ( ) ;
421+
422+ // Assert
423+ Assert . NotNull ( this . _messageHandlerStub . RequestUri ) ;
424+ Assert . DoesNotContain ( "key=" , this . _messageHandlerStub . RequestUri . ToString ( ) ) ;
425+ }
426+
395427 private static ChatHistory CreateSampleChatHistory ( )
396428 {
397429 var chatHistory = new ChatHistory ( ) ;
Original file line number Diff line number Diff line change @@ -116,6 +116,36 @@ public async Task ItCreatesPostRequestWithSemanticKernelVersionHeaderAsync()
116116 Assert . Equal ( expectedVersion , header ) ;
117117 }
118118
119+ [ Fact ]
120+ public async Task ItCreatesPostRequestWithApiKeyInHeaderAsync ( )
121+ {
122+ // Arrange
123+ var client = this . CreateTokenCounterClient ( ) ;
124+
125+ // Act
126+ await client . CountTokensAsync ( "fake-text" ) ;
127+
128+ // Assert
129+ Assert . NotNull ( this . _messageHandlerStub . RequestHeaders ) ;
130+ var apiKeyHeader = this . _messageHandlerStub . RequestHeaders . GetValues ( "x-goog-api-key" ) . SingleOrDefault ( ) ;
131+ Assert . NotNull ( apiKeyHeader ) ;
132+ Assert . Equal ( "fake-key" , apiKeyHeader ) ;
133+ }
134+
135+ [ Fact ]
136+ public async Task ItCreatesPostRequestWithoutApiKeyInUrlAsync ( )
137+ {
138+ // Arrange
139+ var client = this . CreateTokenCounterClient ( ) ;
140+
141+ // Act
142+ await client . CountTokensAsync ( "fake-text" ) ;
143+
144+ // Assert
145+ Assert . NotNull ( this . _messageHandlerStub . RequestUri ) ;
146+ Assert . DoesNotContain ( "key=" , this . _messageHandlerStub . RequestUri . ToString ( ) ) ;
147+ }
148+
119149 [ Theory ]
120150 [ InlineData ( "https://malicious-site.com" ) ]
121151 [ InlineData ( "http://internal-network.local" ) ]
Original file line number Diff line number Diff line change @@ -142,6 +142,38 @@ public async Task ItCreatesPostRequestWithSemanticKernelVersionHeaderAsync()
142142 Assert . Equal ( expectedVersion , header ) ;
143143 }
144144
145+ [ Fact ]
146+ public async Task ItCreatesPostRequestWithApiKeyInHeaderAsync ( )
147+ {
148+ // Arrange
149+ var client = this . CreateEmbeddingsClient ( ) ;
150+ IList < string > data = [ "sample data" ] ;
151+
152+ // Act
153+ await client . GenerateEmbeddingsAsync ( data ) ;
154+
155+ // Assert
156+ Assert . NotNull ( this . _messageHandlerStub . RequestHeaders ) ;
157+ var apiKeyHeader = this . _messageHandlerStub . RequestHeaders . GetValues ( "x-goog-api-key" ) . SingleOrDefault ( ) ;
158+ Assert . NotNull ( apiKeyHeader ) ;
159+ Assert . Equal ( "fake-key" , apiKeyHeader ) ;
160+ }
161+
162+ [ Fact ]
163+ public async Task ItCreatesPostRequestWithoutApiKeyInUrlAsync ( )
164+ {
165+ // Arrange
166+ var client = this . CreateEmbeddingsClient ( ) ;
167+ IList < string > data = [ "sample data" ] ;
168+
169+ // Act
170+ await client . GenerateEmbeddingsAsync ( data ) ;
171+
172+ // Assert
173+ Assert . NotNull ( this . _messageHandlerStub . RequestUri ) ;
174+ Assert . DoesNotContain ( "key=" , this . _messageHandlerStub . RequestUri . ToString ( ) ) ;
175+ }
176+
145177 [ Fact ]
146178 public async Task ShouldIncludeDimensionsInAllRequestsAsync ( )
147179 {
Original file line number Diff line number Diff line change @@ -15,6 +15,7 @@ namespace Microsoft.SemanticKernel.Connectors.Google.Core;
1515internal abstract class ClientBase
1616{
1717 private readonly Func < ValueTask < string > > ? _bearerTokenProvider ;
18+ private readonly string ? _apiKey ;
1819
1920 protected ILogger Logger { get ; }
2021
@@ -32,12 +33,14 @@ protected ClientBase(
3233
3334 protected ClientBase (
3435 HttpClient httpClient ,
35- ILogger ? logger )
36+ ILogger ? logger ,
37+ string ? apiKey = null )
3638 {
3739 Verify . NotNull ( httpClient ) ;
3840
3941 this . HttpClient = httpClient ;
4042 this . Logger = logger ?? NullLogger . Instance ;
43+ this . _apiKey = apiKey ;
4144 }
4245
4346 protected static void ValidateMaxTokens ( int ? maxTokens )
@@ -96,6 +99,10 @@ protected async Task<HttpRequestMessage> CreateHttpRequestAsync(object requestDa
9699 httpRequestMessage . Headers . Authorization =
97100 new AuthenticationHeaderValue ( "Bearer" , bearerKey ) ;
98101 }
102+ else if ( ! string . IsNullOrWhiteSpace ( this . _apiKey ) )
103+ {
104+ httpRequestMessage . Headers . Add ( "x-goog-api-key" , this . _apiKey ) ;
105+ }
99106
100107 return httpRequestMessage ;
101108 }
Original file line number Diff line number Diff line change @@ -100,16 +100,17 @@ public GeminiChatCompletionClient(
100100 ILogger ? logger = null )
101101 : base (
102102 httpClient : httpClient ,
103- logger : logger )
103+ logger : logger ,
104+ apiKey : apiKey )
104105 {
105106 Verify . NotNullOrWhiteSpace ( modelId ) ;
106107 Verify . NotNullOrWhiteSpace ( apiKey ) ;
107108
108109 string versionSubLink = GetApiVersionSubLink ( apiVersion ) ;
109110
110111 this . _modelId = modelId ;
111- this . _chatGenerationEndpoint = new Uri ( $ "https://generativelanguage.googleapis.com/{ versionSubLink } /models/{ this . _modelId } :generateContent?key= { apiKey } ") ;
112- this . _chatStreamingEndpoint = new Uri ( $ "https://generativelanguage.googleapis.com/{ versionSubLink } /models/{ this . _modelId } :streamGenerateContent?key= { apiKey } & alt=sse") ;
112+ this . _chatGenerationEndpoint = new Uri ( $ "https://generativelanguage.googleapis.com/{ versionSubLink } /models/{ this . _modelId } :generateContent") ;
113+ this . _chatStreamingEndpoint = new Uri ( $ "https://generativelanguage.googleapis.com/{ versionSubLink } /models/{ this . _modelId } :streamGenerateContent?alt=sse") ;
113114 }
114115
115116 /// <summary>
Original file line number Diff line number Diff line change @@ -33,15 +33,16 @@ public GeminiTokenCounterClient(
3333 ILogger ? logger = null )
3434 : base (
3535 httpClient : httpClient ,
36- logger : logger )
36+ logger : logger ,
37+ apiKey : apiKey )
3738 {
3839 Verify . NotNullOrWhiteSpace ( modelId ) ;
3940 Verify . NotNullOrWhiteSpace ( apiKey ) ;
4041
4142 string versionSubLink = GetApiVersionSubLink ( apiVersion ) ;
4243
4344 this . _modelId = modelId ;
44- this . _tokenCountingEndpoint = new Uri ( $ "https://generativelanguage.googleapis.com/{ versionSubLink } /models/{ this . _modelId } :countTokens?key= { apiKey } ") ;
45+ this . _tokenCountingEndpoint = new Uri ( $ "https://generativelanguage.googleapis.com/{ versionSubLink } /models/{ this . _modelId } :countTokens") ;
4546 }
4647
4748 /// <summary>
Original file line number Diff line number Diff line change @@ -37,15 +37,16 @@ public GoogleAIEmbeddingClient(
3737 int ? dimensions = null )
3838 : base (
3939 httpClient : httpClient ,
40- logger : logger )
40+ logger : logger ,
41+ apiKey : apiKey )
4142 {
4243 Verify . NotNullOrWhiteSpace ( modelId ) ;
4344 Verify . NotNullOrWhiteSpace ( apiKey ) ;
4445
4546 string versionSubLink = GetApiVersionSubLink ( apiVersion ) ;
4647
4748 this . _embeddingModelId = modelId ;
48- this . _embeddingEndpoint = new Uri ( $ "https://generativelanguage.googleapis.com/{ versionSubLink } /models/{ this . _embeddingModelId } :batchEmbedContents?key= { apiKey } ") ;
49+ this . _embeddingEndpoint = new Uri ( $ "https://generativelanguage.googleapis.com/{ versionSubLink } /models/{ this . _embeddingModelId } :batchEmbedContents") ;
4950 this . _dimensions = dimensions ;
5051 }
5152
You can’t perform that action at this time.
0 commit comments