Skip to content

Commit 9be46a8

Browse files
feat(client): add support for endpoint-specific base URLs
1 parent d5dff04 commit 9be46a8

File tree

5 files changed

+46
-8
lines changed

5 files changed

+46
-8
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
"publint": "^0.2.12",
4343
"ts-jest": "^29.1.0",
4444
"ts-node": "^10.5.0",
45-
"tsc-multi": "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.7/tsc-multi.tgz",
45+
"tsc-multi": "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.8/tsc-multi.tgz",
4646
"tsconfig-paths": "^4.0.0",
4747
"typescript": "5.8.3"
4848
},

src/client.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,13 @@ export class BaseAnthropic {
323323
});
324324
}
325325

326+
/**
327+
* Check whether the base URL is set to its default.
328+
*/
329+
#baseURLOverridden(): boolean {
330+
return this.baseURL !== 'https://api.anthropic.com';
331+
}
332+
326333
protected defaultQuery(): Record<string, string | undefined> | undefined {
327334
return this._options.defaultQuery;
328335
}
@@ -402,11 +409,16 @@ export class BaseAnthropic {
402409
return Errors.APIError.generate(status, error, message, headers);
403410
}
404411

405-
buildURL(path: string, query: Record<string, unknown> | null | undefined): string {
412+
buildURL(
413+
path: string,
414+
query: Record<string, unknown> | null | undefined,
415+
defaultBaseURL?: string | undefined,
416+
): string {
417+
const baseURL = (!this.#baseURLOverridden() && defaultBaseURL) || this.baseURL;
406418
const url =
407419
isAbsoluteURL(path) ?
408420
new URL(path)
409-
: new URL(this.baseURL + (this.baseURL.endsWith('/') && path.startsWith('/') ? path.slice(1) : path));
421+
: new URL(baseURL + (baseURL.endsWith('/') && path.startsWith('/') ? path.slice(1) : path));
410422

411423
const defaultQuery = this.defaultQuery();
412424
if (!isEmptyObj(defaultQuery)) {
@@ -796,9 +808,9 @@ export class BaseAnthropic {
796808
{ retryCount = 0 }: { retryCount?: number } = {},
797809
): { req: FinalizedRequestInit; url: string; timeout: number } {
798810
const options = { ...inputOptions };
799-
const { method, path, query } = options;
811+
const { method, path, query, defaultBaseURL } = options;
800812

801-
const url = this.buildURL(path!, query as Record<string, unknown>);
813+
const url = this.buildURL(path!, query as Record<string, unknown>, defaultBaseURL);
802814
if ('timeout' in options) validatePositiveInteger('timeout', options.timeout);
803815
options.timeout = options.timeout ?? this.timeout;
804816
const { bodyHeaders, body } = this.buildBody({ options });

src/internal/request-options.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export type RequestOptions = {
2121
fetchOptions?: MergedRequestInit;
2222
signal?: AbortSignal | undefined | null;
2323
idempotencyKey?: string;
24+
defaultBaseURL?: string | undefined;
2425

2526
__binaryResponse?: boolean | undefined;
2627
__streamClass?: typeof Stream;

tests/index.test.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,31 @@ describe('instantiate client', () => {
320320
const client = new Anthropic({ apiKey: 'my-anthropic-api-key' });
321321
expect(client.baseURL).toEqual('https://api.anthropic.com');
322322
});
323+
324+
test('in request options', () => {
325+
const client = new Anthropic({ apiKey: 'my-anthropic-api-key' });
326+
expect(client.buildURL('/foo', null, 'http://localhost:5000/option')).toEqual(
327+
'http://localhost:5000/option/foo',
328+
);
329+
});
330+
331+
test('in request options overridden by client options', () => {
332+
const client = new Anthropic({
333+
apiKey: 'my-anthropic-api-key',
334+
baseURL: 'http://localhost:5000/client',
335+
});
336+
expect(client.buildURL('/foo', null, 'http://localhost:5000/option')).toEqual(
337+
'http://localhost:5000/client/foo',
338+
);
339+
});
340+
341+
test('in request options overridden by env variable', () => {
342+
process.env['ANTHROPIC_BASE_URL'] = 'http://localhost:5000/env';
343+
const client = new Anthropic({ apiKey: 'my-anthropic-api-key' });
344+
expect(client.buildURL('/foo', null, 'http://localhost:5000/option')).toEqual(
345+
'http://localhost:5000/env/foo',
346+
);
347+
});
323348
});
324349

325350
test('maxRetries option is correctly set', () => {

yarn.lock

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3283,9 +3283,9 @@ ts-node@^10.5.0:
32833283
v8-compile-cache-lib "^3.0.0"
32843284
yn "3.1.1"
32853285

3286-
"tsc-multi@https://github.com/stainless-api/tsc-multi/releases/download/v1.1.7/tsc-multi.tgz":
3287-
version "1.1.7"
3288-
resolved "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.7/tsc-multi.tgz#52f40adf8b808bd0b633346d11cc4a8aeea465cd"
3286+
"tsc-multi@https://github.com/stainless-api/tsc-multi/releases/download/v1.1.8/tsc-multi.tgz":
3287+
version "1.1.8"
3288+
resolved "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.8/tsc-multi.tgz#f544b359b8f05e607771ffacc280e58201476b04"
32893289
dependencies:
32903290
debug "^4.3.7"
32913291
fast-glob "^3.3.2"

0 commit comments

Comments
 (0)