Skip to content

Commit e6b2870

Browse files
authored
always pass embedding service headers (#267)
* always pass embedding service headers * remove test
1 parent 5899b2f commit e6b2870

File tree

4 files changed

+33
-86
lines changed

4 files changed

+33
-86
lines changed

src/connection/grpc.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ export const grpcClient = (config: GrpcConnectionParams & { grpcMaxMessageLength
194194
Batcher.use(
195195
client,
196196
collection,
197-
new Metadata(bearerToken ? { ...config.headers, authorization: bearerToken } : config.headers),
197+
getMetadataWithEmbeddingServiceAuth(config, bearerToken),
198198
config.timeout?.insert || 90,
199199
consistencyLevel,
200200
tenant
@@ -223,7 +223,7 @@ export const grpcClient = (config: GrpcConnectionParams & { grpcMaxMessageLength
223223
Searcher.use(
224224
client,
225225
collection,
226-
new Metadata(bearerToken ? { ...config.headers, authorization: bearerToken } : config.headers),
226+
getMetadataWithEmbeddingServiceAuth(config, bearerToken),
227227
config.timeout?.query || 30,
228228
consistencyLevel,
229229
tenant
@@ -237,3 +237,16 @@ export const grpcClient = (config: GrpcConnectionParams & { grpcMaxMessageLength
237237
),
238238
};
239239
};
240+
241+
const getMetadataWithEmbeddingServiceAuth = (config: GrpcConnectionParams, bearerToken?: string) =>
242+
new Metadata(
243+
bearerToken
244+
? {
245+
...config.headers,
246+
authorization: bearerToken,
247+
'X-Weaviate-Cluster-Url': config.host,
248+
// keeping for backwards compatibility for older clusters for now. On newer clusters, Embedding Service reuses Authorization header.
249+
'X-Weaviate-Api-Key': bearerToken,
250+
}
251+
: config.headers
252+
);

src/connection/helpers.test.ts

Lines changed: 0 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import weaviate from '../index.js';
2-
import { connectToWeaviateCloud } from './helpers.js';
32

43
const WCD_URL = 'https://piblpmmdsiknacjnm1ltla.c1.europe-west3.gcp.weaviate.cloud';
54
const WCD_KEY = 'cy4ua772mBlMdfw3YnclqAWzFhQt0RLIN0sl';
@@ -30,57 +29,4 @@ describe('Testing of the connection helper methods', () => {
3029
throw new Error('it should not have errord: ' + e);
3130
});
3231
});
33-
34-
describe('adds Weaviate Embedding Service headers', () => {
35-
it('to empty headers', async () => {
36-
const clientMakerMock = jest.fn().mockResolvedValue(undefined);
37-
38-
await connectToWeaviateCloud(WCD_URL, clientMakerMock, {
39-
authCredentials: new weaviate.ApiKey(WCD_KEY),
40-
});
41-
42-
expect(clientMakerMock.mock.calls[0][0].headers).toEqual({
43-
'X-Weaviate-Api-Key': WCD_KEY,
44-
'X-Weaviate-Cluster-Url': WCD_URL,
45-
});
46-
});
47-
48-
it('to existing headers', async () => {
49-
const clientMakerMock = jest.fn().mockResolvedValue(undefined);
50-
51-
await connectToWeaviateCloud(WCD_URL, clientMakerMock, {
52-
authCredentials: new weaviate.ApiKey(WCD_KEY),
53-
headers: { existingHeader: 'existingValue' },
54-
});
55-
56-
expect(clientMakerMock.mock.calls[0][0].headers).toEqual({
57-
existingHeader: 'existingValue',
58-
'X-Weaviate-Api-Key': WCD_KEY,
59-
'X-Weaviate-Cluster-Url': WCD_URL,
60-
});
61-
});
62-
});
63-
64-
describe('does not add Weaviate Embedding Service headers when not using API key', () => {
65-
it('to empty headers', async () => {
66-
const clientMakerMock = jest.fn().mockResolvedValue(undefined);
67-
68-
await connectToWeaviateCloud(WCD_URL, clientMakerMock, {
69-
authCredentials: new weaviate.AuthUserPasswordCredentials({ username: 'test' }),
70-
});
71-
72-
expect(clientMakerMock.mock.calls[0][0].headers).toBe(undefined);
73-
});
74-
75-
it('to existing headers', async () => {
76-
const clientMakerMock = jest.fn().mockResolvedValue(undefined);
77-
78-
await connectToWeaviateCloud(WCD_URL, clientMakerMock, {
79-
authCredentials: new weaviate.AuthUserPasswordCredentials({ username: 'test' }),
80-
headers: { existingHeader: 'existingValue' },
81-
});
82-
83-
expect(clientMakerMock.mock.calls[0][0].headers).toEqual({ existingHeader: 'existingValue' });
84-
});
85-
});
8632
});

src/connection/helpers.ts

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { WeaviateStartUpError } from '../errors.js';
22
import { ClientParams, WeaviateClient } from '../index.js';
3-
import { AuthCredentials, isApiKey, mapApiKey } from './auth.js';
3+
import { AuthCredentials } from './auth.js';
44
import { ProxiesParams, TimeoutParams } from './http.js';
55

66
/** The options available to the `weaviate.connectToWeaviateCloud` method. */
@@ -102,7 +102,7 @@ export function connectToWeaviateCloud(
102102
},
103103
},
104104
auth,
105-
headers: addWeaviateEmbeddingServiceHeaders(clusterURL, auth, headers),
105+
headers: options?.headers,
106106
...rest,
107107
}).catch((e) => {
108108
throw new WeaviateStartUpError(`Weaviate failed to startup with message: ${e.message}`);
@@ -169,19 +169,3 @@ export function connectToCustom(
169169
throw new WeaviateStartUpError(`Weaviate failed to startup with message: ${e.message}`);
170170
});
171171
}
172-
173-
function addWeaviateEmbeddingServiceHeaders(
174-
clusterURL: string,
175-
creds?: AuthCredentials,
176-
headers?: Record<string, string>
177-
) {
178-
if (!isApiKey(creds)) {
179-
return headers;
180-
}
181-
182-
return {
183-
...headers,
184-
'X-Weaviate-Api-Key': mapApiKey(creds).apiKey,
185-
'X-Weaviate-Cluster-Url': clusterURL,
186-
};
187-
}

src/connection/http.ts

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -243,11 +243,11 @@ export const httpClient = (config: InternalConnectionParams): HttpClient => {
243243
headers: {
244244
...config.headers,
245245
'content-type': 'application/json',
246+
...getAuthHeaders(config, bearerToken),
246247
},
247248
body: JSON.stringify(payload),
248249
agent: config.agent,
249250
};
250-
addAuthHeaderIfNeeded(request, bearerToken);
251251
return fetchWithTimeout(url(path), config.timeout?.insert || 90, request).then(
252252
checkStatus<T>(expectReturnContent)
253253
);
@@ -263,11 +263,11 @@ export const httpClient = (config: InternalConnectionParams): HttpClient => {
263263
headers: {
264264
...config.headers,
265265
'content-type': 'application/json',
266+
...getAuthHeaders(config, bearerToken),
266267
},
267268
body: JSON.stringify(payload),
268269
agent: config.agent,
269270
};
270-
addAuthHeaderIfNeeded(request, bearerToken);
271271
return fetchWithTimeout(url(path), config.timeout?.insert || 90, request).then(
272272
checkStatus<T>(expectReturnContent)
273273
);
@@ -278,11 +278,11 @@ export const httpClient = (config: InternalConnectionParams): HttpClient => {
278278
headers: {
279279
...config.headers,
280280
'content-type': 'application/json',
281+
...getAuthHeaders(config, bearerToken),
281282
},
282283
body: JSON.stringify(payload),
283284
agent: config.agent,
284285
};
285-
addAuthHeaderIfNeeded(request, bearerToken);
286286
return fetchWithTimeout(url(path), config.timeout?.insert || 90, request).then(checkStatus<T>(false));
287287
},
288288
delete: <B>(path: string, payload: B | null = null, expectReturnContent = false, bearerToken = '') => {
@@ -291,11 +291,11 @@ export const httpClient = (config: InternalConnectionParams): HttpClient => {
291291
headers: {
292292
...config.headers,
293293
'content-type': 'application/json',
294+
...getAuthHeaders(config, bearerToken),
294295
},
295296
body: payload ? JSON.stringify(payload) : undefined,
296297
agent: config.agent,
297298
};
298-
addAuthHeaderIfNeeded(request, bearerToken);
299299
return fetchWithTimeout(url(path), config.timeout?.insert || 90, request).then(
300300
checkStatus<undefined>(expectReturnContent)
301301
);
@@ -306,11 +306,11 @@ export const httpClient = (config: InternalConnectionParams): HttpClient => {
306306
headers: {
307307
...config.headers,
308308
'content-type': 'application/json',
309+
...getAuthHeaders(config, bearerToken),
309310
},
310311
body: payload ? JSON.stringify(payload) : undefined,
311312
agent: config.agent,
312313
};
313-
addAuthHeaderIfNeeded(request, bearerToken);
314314
return fetchWithTimeout(url(path), config.timeout?.query || 30, request).then(
315315
handleHeadResponse<undefined>(false)
316316
);
@@ -320,10 +320,10 @@ export const httpClient = (config: InternalConnectionParams): HttpClient => {
320320
method: 'GET',
321321
headers: {
322322
...config.headers,
323+
...getAuthHeaders(config, bearerToken),
323324
},
324325
agent: config.agent,
325326
};
326-
addAuthHeaderIfNeeded(request, bearerToken);
327327
return fetchWithTimeout(url(path), config.timeout?.query || 30, request).then(
328328
checkStatus<any>(expectReturnContent)
329329
);
@@ -334,10 +334,10 @@ export const httpClient = (config: InternalConnectionParams): HttpClient => {
334334
method: 'GET',
335335
headers: {
336336
...config.headers,
337+
...getAuthHeaders(config, bearerToken),
337338
},
338339
agent: config.agent,
339340
};
340-
addAuthHeaderIfNeeded(request, bearerToken);
341341
return fetchWithTimeout(url(path), config.timeout?.query || 30, request);
342342
},
343343
externalGet: (externalUrl: string) => {
@@ -406,8 +406,12 @@ const handleHeadResponse =
406406
return checkStatus<T>(expectResponseBody)(res);
407407
};
408408

409-
function addAuthHeaderIfNeeded(request: any, bearerToken: string) {
410-
if (bearerToken !== '') {
411-
request.headers.Authorization = `Bearer ${bearerToken}`;
412-
}
413-
}
409+
const getAuthHeaders = (config: InternalConnectionParams, bearerToken: string) =>
410+
bearerToken
411+
? {
412+
Authorization: `Bearer ${bearerToken}`,
413+
'X-Weaviate-Cluster-Url': config.host,
414+
// keeping for backwards compatibility for older clusters for now. On newer clusters, Embedding Service reuses Authorization header.
415+
'X-Weaviate-Api-Key': bearerToken,
416+
}
417+
: undefined;

0 commit comments

Comments
 (0)