@@ -14,10 +14,12 @@ import { makeRequestOptionsFromResolvedModel } from "../lib/makeRequestOptions.j
14
14
import type { InferenceProviderOrPolicy , InferenceTask , RequestArgs } from "../types.js" ;
15
15
import { templates } from "./templates.exported.js" ;
16
16
17
- export type InferenceSnippetOptions = { streaming ?: boolean ; billTo ?: string ; accessToken ?: string } & Record <
18
- string ,
19
- unknown
20
- > ;
17
+ export type InferenceSnippetOptions = {
18
+ streaming ?: boolean ;
19
+ billTo ?: string ;
20
+ accessToken ?: string ;
21
+ directRequest ?: boolean ;
22
+ } & Record < string , unknown > ;
21
23
22
24
const PYTHON_CLIENTS = [ "huggingface_hub" , "fal_client" , "requests" , "openai" ] as const ;
23
25
const JS_CLIENTS = [ "fetch" , "huggingface.js" , "openai" ] as const ;
@@ -124,7 +126,10 @@ const HF_JS_METHODS: Partial<Record<WidgetType, string>> = {
124
126
translation : "translation" ,
125
127
} ;
126
128
127
- const ACCESS_TOKEN_PLACEHOLDER = "<ACCESS_TOKEN>" ; // Placeholder to replace with env variable in snippets
129
+ // Placeholders to replace with env variable in snippets
130
+ // little hack to support both direct requests and routing => routed requests should start with "hf_"
131
+ const ACCESS_TOKEN_ROUTING_PLACEHOLDER = "hf_token_placeholder" ;
132
+ const ACCESS_TOKEN_DIRECT_REQUEST_PLACEHOLDER = "not_hf_token_placeholder" ;
128
133
129
134
// Snippet generators
130
135
const snippetGenerator = ( templateName : string , inputPreparationFn ?: InputPreparationFn ) => {
@@ -153,7 +158,11 @@ const snippetGenerator = (templateName: string, inputPreparationFn?: InputPrepar
153
158
console . error ( `Failed to get provider helper for ${ provider } (${ task } )` , e ) ;
154
159
return [ ] ;
155
160
}
156
- const accessTokenOrPlaceholder = opts ?. accessToken ?? ACCESS_TOKEN_PLACEHOLDER ;
161
+
162
+ const placeholder = opts ?. directRequest
163
+ ? ACCESS_TOKEN_DIRECT_REQUEST_PLACEHOLDER
164
+ : ACCESS_TOKEN_ROUTING_PLACEHOLDER ;
165
+ const accessTokenOrPlaceholder = opts ?. accessToken ?? placeholder ;
157
166
158
167
/// Prepare inputs + make request
159
168
const inputs = inputPreparationFn ? inputPreparationFn ( model , opts ) : { inputs : getModelInputSnippet ( model ) } ;
@@ -255,8 +264,8 @@ const snippetGenerator = (templateName: string, inputPreparationFn?: InputPrepar
255
264
}
256
265
257
266
/// Replace access token placeholder
258
- if ( snippet . includes ( ACCESS_TOKEN_PLACEHOLDER ) ) {
259
- snippet = replaceAccessTokenPlaceholder ( snippet , language , provider ) ;
267
+ if ( snippet . includes ( placeholder ) ) {
268
+ snippet = replaceAccessTokenPlaceholder ( opts ?. directRequest , placeholder , snippet , language , provider ) ;
260
269
}
261
270
262
271
/// Snippet is ready!
@@ -431,6 +440,8 @@ function removeSuffix(str: string, suffix: string) {
431
440
}
432
441
433
442
function replaceAccessTokenPlaceholder (
443
+ directRequest : boolean | undefined ,
444
+ placeholder : string ,
434
445
snippet : string ,
435
446
language : InferenceSnippetLanguage ,
436
447
provider : InferenceProviderOrPolicy
@@ -439,46 +450,57 @@ function replaceAccessTokenPlaceholder(
439
450
// Once snippets are rendered, we replace the placeholder with code to fetch the access token from an environment variable.
440
451
441
452
// Determine if HF_TOKEN or specific provider token should be used
442
- const accessTokenEnvVar =
443
- ! snippet . includes ( "https://" ) || // no URL provided => using a client => use $HF_TOKEN
444
- snippet . includes ( "https://router.huggingface.co" ) || // explicit routed request => use $HF_TOKEN
445
- provider == "hf-inference" // hf-inference provider => use $HF_TOKEN
446
- ? "HF_TOKEN"
447
- : provider . toUpperCase ( ) . replace ( "-" , "_" ) + "_API_KEY" ; // e.g. "REPLICATE_API_KEY"
453
+ const useHfToken =
454
+ provider == "hf-inference" || // hf-inference provider => use $HF_TOKEN
455
+ ( ! directRequest && // if explicit directRequest => use provider-specific token
456
+ ( ! snippet . includes ( "https://" ) || // no URL provided => using a client => use $HF_TOKEN
457
+ snippet . includes ( "https://router.huggingface.co" ) ) ) ; // explicit routed request => use $HF_TOKEN
458
+
459
+ const accessTokenEnvVar = useHfToken
460
+ ? "HF_TOKEN" // e.g. routed request or hf-inference
461
+ : provider . toUpperCase ( ) . replace ( "-" , "_" ) + "_API_KEY" ; // e.g. "REPLICATE_API_KEY"
448
462
449
463
// Replace the placeholder with the env variable
450
464
if ( language === "sh" ) {
451
465
snippet = snippet . replace (
452
- `'Authorization: Bearer ${ ACCESS_TOKEN_PLACEHOLDER } '` ,
466
+ `'Authorization: Bearer ${ placeholder } '` ,
453
467
`"Authorization: Bearer $${ accessTokenEnvVar } "` // e.g. "Authorization: Bearer $HF_TOKEN"
454
468
) ;
455
469
} else if ( language === "python" ) {
456
470
snippet = "import os\n" + snippet ;
457
471
snippet = snippet . replace (
458
- `"${ ACCESS_TOKEN_PLACEHOLDER } "` ,
472
+ `"${ placeholder } "` ,
459
473
`os.environ["${ accessTokenEnvVar } "]` // e.g. os.environ["HF_TOKEN")
460
474
) ;
461
475
snippet = snippet . replace (
462
- `"Bearer ${ ACCESS_TOKEN_PLACEHOLDER } "` ,
476
+ `"Bearer ${ placeholder } "` ,
463
477
`f"Bearer {os.environ['${ accessTokenEnvVar } ']}"` // e.g. f"Bearer {os.environ['HF_TOKEN']}"
464
478
) ;
465
479
snippet = snippet . replace (
466
- `"Key ${ ACCESS_TOKEN_PLACEHOLDER } "` ,
480
+ `"Key ${ placeholder } "` ,
467
481
`f"Key {os.environ['${ accessTokenEnvVar } ']}"` // e.g. f"Key {os.environ['FAL_AI_API_KEY']}"
468
482
) ;
483
+ snippet = snippet . replace (
484
+ `"X-Key ${ placeholder } "` ,
485
+ `f"X-Key {os.environ['${ accessTokenEnvVar } ']}"` // e.g. f"X-Key {os.environ['BLACK_FOREST_LABS_API_KEY']}"
486
+ ) ;
469
487
} else if ( language === "js" ) {
470
488
snippet = snippet . replace (
471
- `"${ ACCESS_TOKEN_PLACEHOLDER } "` ,
489
+ `"${ placeholder } "` ,
472
490
`process.env.${ accessTokenEnvVar } ` // e.g. process.env.HF_TOKEN
473
491
) ;
474
492
snippet = snippet . replace (
475
- `Authorization: "Bearer ${ ACCESS_TOKEN_PLACEHOLDER } ",` ,
493
+ `Authorization: "Bearer ${ placeholder } ",` ,
476
494
`Authorization: \`Bearer $\{process.env.${ accessTokenEnvVar } }\`,` // e.g. Authorization: `Bearer ${process.env.HF_TOKEN}`,
477
495
) ;
478
496
snippet = snippet . replace (
479
- `Authorization: "Key ${ ACCESS_TOKEN_PLACEHOLDER } ",` ,
497
+ `Authorization: "Key ${ placeholder } ",` ,
480
498
`Authorization: \`Key $\{process.env.${ accessTokenEnvVar } }\`,` // e.g. Authorization: `Key ${process.env.FAL_AI_API_KEY}`,
481
499
) ;
500
+ snippet = snippet . replace (
501
+ `Authorization: "X-Key ${ placeholder } ",` ,
502
+ `Authorization: \`X-Key $\{process.env.${ accessTokenEnvVar } }\`,` // e.g. Authorization: `X-Key ${process.env.BLACK_FOREST_LABS_AI_API_KEY}`,
503
+ ) ;
482
504
}
483
505
return snippet ;
484
506
}
0 commit comments