@gradio/client 0.17.0 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -0
- package/README.md +10 -6
- package/dist/client.d.ts +18 -7
- package/dist/client.d.ts.map +1 -1
- package/dist/constants.d.ts +8 -2
- package/dist/constants.d.ts.map +1 -1
- package/dist/helpers/api_info.d.ts +22 -0
- package/dist/helpers/api_info.d.ts.map +1 -1
- package/dist/helpers/data.d.ts +2 -2
- package/dist/helpers/data.d.ts.map +1 -1
- package/dist/helpers/init_helpers.d.ts.map +1 -1
- package/dist/helpers/spaces.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +275 -183
- package/dist/test/handlers.d.ts +3 -0
- package/dist/test/handlers.d.ts.map +1 -0
- package/dist/test/mock_eventsource.d.ts +2 -0
- package/dist/test/mock_eventsource.d.ts.map +1 -0
- package/dist/test/server.d.ts +2 -0
- package/dist/test/server.d.ts.map +1 -0
- package/dist/test/test_data.d.ts +76 -0
- package/dist/test/test_data.d.ts.map +1 -0
- package/dist/types.d.ts +23 -7
- package/dist/types.d.ts.map +1 -1
- package/dist/upload.d.ts +2 -2
- package/dist/upload.d.ts.map +1 -1
- package/dist/utils/duplicate.d.ts.map +1 -1
- package/dist/utils/predict.d.ts +1 -1
- package/dist/utils/predict.d.ts.map +1 -1
- package/dist/utils/stream.d.ts +2 -2
- package/dist/utils/stream.d.ts.map +1 -1
- package/dist/utils/submit.d.ts +1 -1
- package/dist/utils/submit.d.ts.map +1 -1
- package/dist/utils/upload_files.d.ts.map +1 -1
- package/dist/utils/view_api.d.ts.map +1 -1
- package/package.json +8 -2
- package/src/client.ts +53 -28
- package/src/constants.ts +9 -2
- package/src/helpers/api_info.ts +75 -4
- package/src/helpers/data.ts +46 -28
- package/src/helpers/init_helpers.ts +7 -11
- package/src/helpers/spaces.ts +8 -3
- package/src/index.ts +1 -1
- package/src/test/api_info.test.ts +567 -0
- package/src/test/data.test.ts +281 -0
- package/src/test/handlers.ts +438 -0
- package/src/test/init.test.ts +139 -0
- package/src/test/init_helpers.test.ts +94 -0
- package/src/test/mock_eventsource.ts +13 -0
- package/src/test/post_data.test.ts +45 -0
- package/src/test/server.ts +6 -0
- package/src/test/spaces.test.ts +145 -0
- package/src/test/stream.test.ts +79 -0
- package/src/test/test_data.ts +557 -0
- package/src/test/upload_files.test.ts +42 -0
- package/src/test/view_api.test.ts +53 -0
- package/src/types.ts +36 -17
- package/src/upload.ts +4 -8
- package/src/utils/duplicate.ts +20 -3
- package/src/utils/handle_blob.ts +1 -1
- package/src/utils/post_data.ts +1 -1
- package/src/utils/predict.ts +2 -2
- package/src/utils/stream.ts +30 -21
- package/src/utils/submit.ts +42 -19
- package/src/utils/upload_files.ts +11 -6
- package/src/utils/view_api.ts +4 -7
- package/vite.config.js +7 -0
- package/src/utils/client.node-test.ts +0 -173
package/dist/index.js
CHANGED
@@ -5,16 +5,23 @@ var __publicField = (obj, key, value) => {
|
|
5
5
|
return value;
|
6
6
|
};
|
7
7
|
var fn = new Intl.Collator(0, { numeric: 1 }).compare;
|
8
|
-
function semiver
|
8
|
+
function semiver(a, b, bool) {
|
9
9
|
a = a.split(".");
|
10
10
|
b = b.split(".");
|
11
11
|
return fn(a[0], b[0]) || fn(a[1], b[1]) || (b[2] = b.slice(2).join("."), bool = /[.-]/.test(a[2] = a.slice(2).join(".")), bool == /[.-]/.test(b[2]) ? fn(a[2], b[2]) : bool ? -1 : 1);
|
12
12
|
}
|
13
|
+
const UPLOAD_URL = "upload";
|
13
14
|
const CONFIG_URL = "config";
|
14
15
|
const API_INFO_URL = "info";
|
16
|
+
const RUNTIME_URL = "runtime";
|
17
|
+
const SLEEPTIME_URL = "sleeptime";
|
15
18
|
const SPACE_FETCHER_URL = "https://gradio-space-api-fetcher-v2.hf.space/api";
|
16
|
-
const QUEUE_FULL_MSG = "This application is
|
17
|
-
const BROKEN_CONNECTION_MSG = "Connection errored out.";
|
19
|
+
const QUEUE_FULL_MSG = "This application is currently busy. Please try again. ";
|
20
|
+
const BROKEN_CONNECTION_MSG = "Connection errored out. ";
|
21
|
+
const CONFIG_ERROR_MSG = "Could not resolve app config. ";
|
22
|
+
const SPACE_STATUS_ERROR_MSG = "Could not get space status. ";
|
23
|
+
const API_INFO_ERROR_MSG = "Could not get API info. ";
|
24
|
+
const SPACE_METADATA_ERROR_MSG = "Space metadata could not be loaded. ";
|
18
25
|
function resolve_root(base_url, root_path, prioritize_base) {
|
19
26
|
if (root_path.startsWith("http://") || root_path.startsWith("https://")) {
|
20
27
|
return prioritize_base ? base_url : root_path;
|
@@ -31,7 +38,6 @@ async function get_jwt(space, token) {
|
|
31
38
|
const jwt = (await r.json()).token;
|
32
39
|
return jwt || false;
|
33
40
|
} catch (e) {
|
34
|
-
console.error(e);
|
35
41
|
return false;
|
36
42
|
}
|
37
43
|
}
|
@@ -53,21 +59,18 @@ async function resolve_config(endpoint) {
|
|
53
59
|
config.root = config_root;
|
54
60
|
return { ...config, path };
|
55
61
|
} else if (endpoint) {
|
56
|
-
const response = await this.
|
57
|
-
|
58
|
-
|
59
|
-
headers
|
60
|
-
}
|
61
|
-
);
|
62
|
+
const response = await this.fetch(`${endpoint}/${CONFIG_URL}`, {
|
63
|
+
headers
|
64
|
+
});
|
62
65
|
if ((response == null ? void 0 : response.status) === 200) {
|
63
66
|
let config = await response.json();
|
64
67
|
config.path = config.path ?? "";
|
65
68
|
config.root = endpoint;
|
66
69
|
return config;
|
67
70
|
}
|
68
|
-
throw new Error(
|
71
|
+
throw new Error(CONFIG_ERROR_MSG);
|
69
72
|
}
|
70
|
-
throw new Error(
|
73
|
+
throw new Error(CONFIG_ERROR_MSG);
|
71
74
|
}
|
72
75
|
function determine_protocol(endpoint) {
|
73
76
|
if (endpoint.startsWith("http")) {
|
@@ -112,15 +115,15 @@ async function process_endpoint(app_reference, hf_token) {
|
|
112
115
|
`https://huggingface.co/api/spaces/${_app_reference}/host`,
|
113
116
|
{ headers }
|
114
117
|
);
|
115
|
-
if (res.status !== 200)
|
116
|
-
throw new Error("Space metadata could not be loaded.");
|
117
118
|
const _host = (await res.json()).host;
|
118
119
|
return {
|
119
120
|
space_id: app_reference,
|
120
121
|
...determine_protocol(_host)
|
121
122
|
};
|
122
123
|
} catch (e) {
|
123
|
-
throw new Error(
|
124
|
+
throw new Error(
|
125
|
+
"Space metadata could not be loaded. " + e.message
|
126
|
+
);
|
124
127
|
}
|
125
128
|
}
|
126
129
|
if (RE_SPACE_DOMAIN.test(_app_reference)) {
|
@@ -314,6 +317,45 @@ function handle_message(data, last_status) {
|
|
314
317
|
}
|
315
318
|
return { type: "none", status: { stage: "error", queue } };
|
316
319
|
}
|
320
|
+
const map_data_to_params = (data, api_info) => {
|
321
|
+
const parameters = Object.values(api_info.named_endpoints).flatMap(
|
322
|
+
(values) => values.parameters
|
323
|
+
);
|
324
|
+
if (Array.isArray(data)) {
|
325
|
+
if (data.length > parameters.length) {
|
326
|
+
console.warn("Too many arguments provided for the endpoint.");
|
327
|
+
}
|
328
|
+
return data;
|
329
|
+
}
|
330
|
+
const resolved_data = [];
|
331
|
+
const provided_keys = Object.keys(data);
|
332
|
+
parameters.forEach((param, index) => {
|
333
|
+
if (data.hasOwnProperty(param.parameter_name)) {
|
334
|
+
resolved_data[index] = data[param.parameter_name];
|
335
|
+
} else if (param.parameter_has_default) {
|
336
|
+
resolved_data[index] = param.parameter_default;
|
337
|
+
} else {
|
338
|
+
throw new Error(
|
339
|
+
`No value provided for required parameter: ${param.parameter_name}`
|
340
|
+
);
|
341
|
+
}
|
342
|
+
});
|
343
|
+
provided_keys.forEach((key) => {
|
344
|
+
if (!parameters.some((param) => param.parameter_name === key)) {
|
345
|
+
throw new Error(
|
346
|
+
`Parameter \`${key}\` is not a valid keyword argument. Please refer to the API for usage.`
|
347
|
+
);
|
348
|
+
}
|
349
|
+
});
|
350
|
+
resolved_data.forEach((value, idx) => {
|
351
|
+
if (value === void 0 && !parameters[idx].parameter_has_default) {
|
352
|
+
throw new Error(
|
353
|
+
`No value provided for required parameter: ${parameters[idx].parameter_name}`
|
354
|
+
);
|
355
|
+
}
|
356
|
+
});
|
357
|
+
return resolved_data;
|
358
|
+
};
|
317
359
|
async function view_api() {
|
318
360
|
if (this.api_info)
|
319
361
|
return this.api_info;
|
@@ -328,8 +370,8 @@ async function view_api() {
|
|
328
370
|
}
|
329
371
|
try {
|
330
372
|
let response;
|
331
|
-
if (semiver
|
332
|
-
response = await this.
|
373
|
+
if (semiver((config == null ? void 0 : config.version) || "2.0.0", "3.30") < 0) {
|
374
|
+
response = await this.fetch(SPACE_FETCHER_URL, {
|
333
375
|
method: "POST",
|
334
376
|
body: JSON.stringify({
|
335
377
|
serialize: false,
|
@@ -338,12 +380,9 @@ async function view_api() {
|
|
338
380
|
headers
|
339
381
|
});
|
340
382
|
} else {
|
341
|
-
response = await this.
|
342
|
-
|
343
|
-
|
344
|
-
headers
|
345
|
-
}
|
346
|
-
);
|
383
|
+
response = await this.fetch(`${config == null ? void 0 : config.root}/${API_INFO_URL}`, {
|
384
|
+
headers
|
385
|
+
});
|
347
386
|
}
|
348
387
|
if (!response.ok) {
|
349
388
|
throw new Error(BROKEN_CONNECTION_MSG);
|
@@ -361,12 +400,14 @@ async function view_api() {
|
|
361
400
|
}
|
362
401
|
}
|
363
402
|
async function upload_files(root_url, files, upload_id) {
|
403
|
+
var _a;
|
364
404
|
const headers = {};
|
365
|
-
if (this.options.hf_token) {
|
405
|
+
if ((_a = this == null ? void 0 : this.options) == null ? void 0 : _a.hf_token) {
|
366
406
|
headers.Authorization = `Bearer ${this.options.hf_token}`;
|
367
407
|
}
|
368
408
|
const chunkSize = 1e3;
|
369
409
|
const uploadResponses = [];
|
410
|
+
let response;
|
370
411
|
for (let i = 0; i < files.length; i += chunkSize) {
|
371
412
|
const chunk = files.slice(i, i + chunkSize);
|
372
413
|
const formData = new FormData();
|
@@ -374,17 +415,18 @@ async function upload_files(root_url, files, upload_id) {
|
|
374
415
|
formData.append("files", file);
|
375
416
|
});
|
376
417
|
try {
|
377
|
-
const upload_url = upload_id ? `${root_url}/upload?upload_id=${upload_id}` : `${root_url}
|
378
|
-
|
418
|
+
const upload_url = upload_id ? `${root_url}/upload?upload_id=${upload_id}` : `${root_url}/${UPLOAD_URL}`;
|
419
|
+
response = await this.fetch(upload_url, {
|
379
420
|
method: "POST",
|
380
421
|
body: formData,
|
381
422
|
headers
|
382
423
|
});
|
383
424
|
} catch (e) {
|
384
|
-
|
425
|
+
throw new Error(BROKEN_CONNECTION_MSG + e.message);
|
385
426
|
}
|
386
427
|
if (!response.ok) {
|
387
|
-
|
428
|
+
const error_text = await response.text();
|
429
|
+
return { error: `HTTP ${response.status}: ${error_text}` };
|
388
430
|
}
|
389
431
|
const output = await response.json();
|
390
432
|
if (output) {
|
@@ -393,87 +435,7 @@ async function upload_files(root_url, files, upload_id) {
|
|
393
435
|
}
|
394
436
|
return { files: uploadResponses };
|
395
437
|
}
|
396
|
-
function
|
397
|
-
while (stack.length > 1) {
|
398
|
-
const key2 = stack.shift();
|
399
|
-
if (typeof key2 === "string" || typeof key2 === "number") {
|
400
|
-
object = object[key2];
|
401
|
-
} else {
|
402
|
-
throw new Error("Invalid key type");
|
403
|
-
}
|
404
|
-
}
|
405
|
-
const key = stack.shift();
|
406
|
-
if (typeof key === "string" || typeof key === "number") {
|
407
|
-
object[key] = newValue;
|
408
|
-
} else {
|
409
|
-
throw new Error("Invalid key type");
|
410
|
-
}
|
411
|
-
}
|
412
|
-
async function walk_and_store_blobs(param, type = void 0, path = [], root = false, endpoint_info = void 0) {
|
413
|
-
if (Array.isArray(param)) {
|
414
|
-
let blob_refs = [];
|
415
|
-
await Promise.all(
|
416
|
-
param.map(async (item) => {
|
417
|
-
var _a;
|
418
|
-
let new_path = path.slice();
|
419
|
-
new_path.push(item);
|
420
|
-
const array_refs = await walk_and_store_blobs(
|
421
|
-
param[item],
|
422
|
-
root ? ((_a = endpoint_info == null ? void 0 : endpoint_info.parameters[item]) == null ? void 0 : _a.component) || void 0 : type,
|
423
|
-
new_path,
|
424
|
-
false,
|
425
|
-
endpoint_info
|
426
|
-
);
|
427
|
-
blob_refs = blob_refs.concat(array_refs);
|
428
|
-
})
|
429
|
-
);
|
430
|
-
return blob_refs;
|
431
|
-
} else if (globalThis.Buffer && param instanceof globalThis.Buffer) {
|
432
|
-
const is_image = type === "Image";
|
433
|
-
return [
|
434
|
-
{
|
435
|
-
path,
|
436
|
-
blob: is_image ? false : new NodeBlob([param]),
|
437
|
-
type
|
438
|
-
}
|
439
|
-
];
|
440
|
-
} else if (typeof param === "object") {
|
441
|
-
let blob_refs = [];
|
442
|
-
for (let key in param) {
|
443
|
-
if (param.hasOwnProperty(key)) {
|
444
|
-
let new_path = path.slice();
|
445
|
-
new_path.push(key);
|
446
|
-
blob_refs = blob_refs.concat(
|
447
|
-
await walk_and_store_blobs(
|
448
|
-
// @ts-ignore
|
449
|
-
param[key],
|
450
|
-
void 0,
|
451
|
-
new_path,
|
452
|
-
false,
|
453
|
-
endpoint_info
|
454
|
-
)
|
455
|
-
);
|
456
|
-
}
|
457
|
-
}
|
458
|
-
return blob_refs;
|
459
|
-
}
|
460
|
-
return [];
|
461
|
-
}
|
462
|
-
function skip_queue(id, config) {
|
463
|
-
var _a, _b, _c, _d;
|
464
|
-
return !(((_b = (_a = config == null ? void 0 : config.dependencies) == null ? void 0 : _a[id]) == null ? void 0 : _b.queue) === null ? config.enable_queue : (_d = (_c = config == null ? void 0 : config.dependencies) == null ? void 0 : _c[id]) == null ? void 0 : _d.queue) || false;
|
465
|
-
}
|
466
|
-
function post_message(message, origin) {
|
467
|
-
return new Promise((res, _rej) => {
|
468
|
-
const channel = new MessageChannel();
|
469
|
-
channel.port1.onmessage = ({ data }) => {
|
470
|
-
channel.port1.close();
|
471
|
-
res(data);
|
472
|
-
};
|
473
|
-
window.parent.postMessage(message, origin, [channel.port2]);
|
474
|
-
});
|
475
|
-
}
|
476
|
-
async function upload(file_data, root_url, upload_id, max_file_size, upload_fn = upload_files) {
|
438
|
+
async function upload(file_data, root_url, upload_id, max_file_size) {
|
477
439
|
let files = (Array.isArray(file_data) ? file_data : [file_data]).map(
|
478
440
|
(file_data2) => file_data2.blob
|
479
441
|
);
|
@@ -486,7 +448,7 @@ async function upload(file_data, root_url, upload_id, max_file_size, upload_fn =
|
|
486
448
|
);
|
487
449
|
}
|
488
450
|
return await Promise.all(
|
489
|
-
await
|
451
|
+
await this.upload_files(root_url, files, upload_id).then(
|
490
452
|
async (response) => {
|
491
453
|
if (response.error) {
|
492
454
|
throw new Error(response.error);
|
@@ -549,6 +511,95 @@ class FileData {
|
|
549
511
|
this.alt_text = alt_text;
|
550
512
|
}
|
551
513
|
}
|
514
|
+
function update_object(object, newValue, stack) {
|
515
|
+
while (stack.length > 1) {
|
516
|
+
const key2 = stack.shift();
|
517
|
+
if (typeof key2 === "string" || typeof key2 === "number") {
|
518
|
+
object = object[key2];
|
519
|
+
} else {
|
520
|
+
throw new Error("Invalid key type");
|
521
|
+
}
|
522
|
+
}
|
523
|
+
const key = stack.shift();
|
524
|
+
if (typeof key === "string" || typeof key === "number") {
|
525
|
+
object[key] = newValue;
|
526
|
+
} else {
|
527
|
+
throw new Error("Invalid key type");
|
528
|
+
}
|
529
|
+
}
|
530
|
+
async function walk_and_store_blobs(data, type = void 0, path = [], root = false, endpoint_info = void 0) {
|
531
|
+
if (Array.isArray(data)) {
|
532
|
+
let blob_refs = [];
|
533
|
+
await Promise.all(
|
534
|
+
data.map(async (item) => {
|
535
|
+
var _a;
|
536
|
+
let new_path = path.slice();
|
537
|
+
new_path.push(item);
|
538
|
+
const array_refs = await walk_and_store_blobs(
|
539
|
+
data[item],
|
540
|
+
root ? ((_a = endpoint_info == null ? void 0 : endpoint_info.parameters[item]) == null ? void 0 : _a.component) || void 0 : type,
|
541
|
+
new_path,
|
542
|
+
false,
|
543
|
+
endpoint_info
|
544
|
+
);
|
545
|
+
blob_refs = blob_refs.concat(array_refs);
|
546
|
+
})
|
547
|
+
);
|
548
|
+
return blob_refs;
|
549
|
+
} else if (globalThis.Buffer && data instanceof globalThis.Buffer || data instanceof Blob) {
|
550
|
+
const is_image = type === "Image";
|
551
|
+
return [
|
552
|
+
{
|
553
|
+
path,
|
554
|
+
blob: is_image ? false : new NodeBlob([data]),
|
555
|
+
type
|
556
|
+
}
|
557
|
+
];
|
558
|
+
} else if (typeof data === "object" && data !== null) {
|
559
|
+
let blob_refs = [];
|
560
|
+
for (const key of Object.keys(data)) {
|
561
|
+
const new_path = [...path, key];
|
562
|
+
const value = data[key];
|
563
|
+
blob_refs = blob_refs.concat(
|
564
|
+
await walk_and_store_blobs(
|
565
|
+
value,
|
566
|
+
void 0,
|
567
|
+
new_path,
|
568
|
+
false,
|
569
|
+
endpoint_info
|
570
|
+
)
|
571
|
+
);
|
572
|
+
}
|
573
|
+
if (!blob_refs.length && !(data instanceof Blob || data instanceof ArrayBuffer || data instanceof Uint8Array)) {
|
574
|
+
return [
|
575
|
+
{
|
576
|
+
path,
|
577
|
+
blob: new NodeBlob([JSON.stringify(data)]),
|
578
|
+
type: typeof data
|
579
|
+
}
|
580
|
+
];
|
581
|
+
}
|
582
|
+
return blob_refs;
|
583
|
+
}
|
584
|
+
return [];
|
585
|
+
}
|
586
|
+
function skip_queue(id, config) {
|
587
|
+
var _a, _b;
|
588
|
+
if (((_b = (_a = config == null ? void 0 : config.dependencies) == null ? void 0 : _a[id]) == null ? void 0 : _b.queue) !== null) {
|
589
|
+
return !config.dependencies[id].queue;
|
590
|
+
}
|
591
|
+
return !config.enable_queue;
|
592
|
+
}
|
593
|
+
function post_message(message, origin) {
|
594
|
+
return new Promise((res, _rej) => {
|
595
|
+
const channel = new MessageChannel();
|
596
|
+
channel.port1.onmessage = ({ data }) => {
|
597
|
+
channel.port1.close();
|
598
|
+
res(data);
|
599
|
+
};
|
600
|
+
window.parent.postMessage(message, origin, [channel.port2]);
|
601
|
+
});
|
602
|
+
}
|
552
603
|
async function handle_blob(endpoint, data, api_info) {
|
553
604
|
const self = this;
|
554
605
|
const blobRefs = await walk_and_store_blobs(
|
@@ -568,7 +619,7 @@ async function handle_blob(endpoint, data, api_info) {
|
|
568
619
|
path,
|
569
620
|
file_url,
|
570
621
|
type,
|
571
|
-
name: blob == null ? void 0 : blob.name
|
622
|
+
name: blob instanceof File ? blob == null ? void 0 : blob.name : void 0
|
572
623
|
};
|
573
624
|
})
|
574
625
|
);
|
@@ -588,7 +639,7 @@ async function post_data(url, body, additional_headers) {
|
|
588
639
|
headers.Authorization = `Bearer ${this.options.hf_token}`;
|
589
640
|
}
|
590
641
|
try {
|
591
|
-
var response = await this.
|
642
|
+
var response = await this.fetch(url, {
|
592
643
|
method: "POST",
|
593
644
|
body: JSON.stringify(body),
|
594
645
|
headers: { ...headers, ...additional_headers }
|
@@ -626,7 +677,7 @@ async function predict(endpoint, data) {
|
|
626
677
|
);
|
627
678
|
}
|
628
679
|
return new Promise(async (resolve, reject) => {
|
629
|
-
const app = this.submit(endpoint, data
|
680
|
+
const app = this.submit(endpoint, data);
|
630
681
|
let result;
|
631
682
|
app.on("data", (d) => {
|
632
683
|
if (status_complete) {
|
@@ -663,7 +714,7 @@ async function check_space_status(id, type, status_callback) {
|
|
663
714
|
status_callback({
|
664
715
|
status: "error",
|
665
716
|
load_status: "error",
|
666
|
-
message:
|
717
|
+
message: SPACE_STATUS_ERROR_MSG,
|
667
718
|
detail: "NOT_FOUND"
|
668
719
|
});
|
669
720
|
return;
|
@@ -751,7 +802,7 @@ async function get_space_hardware(space_id, hf_token) {
|
|
751
802
|
}
|
752
803
|
try {
|
753
804
|
const res = await fetch(
|
754
|
-
`https://huggingface.co/api/spaces/${space_id}
|
805
|
+
`https://huggingface.co/api/spaces/${space_id}/${RUNTIME_URL}`,
|
755
806
|
{ headers }
|
756
807
|
);
|
757
808
|
if (res.status !== 200)
|
@@ -772,7 +823,7 @@ async function set_space_timeout(space_id, timeout, hf_token) {
|
|
772
823
|
};
|
773
824
|
try {
|
774
825
|
const res = await fetch(
|
775
|
-
`https://huggingface.co/api/spaces/${space_id}
|
826
|
+
`https://huggingface.co/api/spaces/${space_id}/${SLEEPTIME_URL}`,
|
776
827
|
{
|
777
828
|
method: "POST",
|
778
829
|
headers: { "Content-Type": "application/json", ...headers },
|
@@ -827,8 +878,12 @@ async function duplicate(app_reference, options) {
|
|
827
878
|
body.private = true;
|
828
879
|
}
|
829
880
|
let original_hardware;
|
830
|
-
|
831
|
-
|
881
|
+
try {
|
882
|
+
if (!hardware) {
|
883
|
+
original_hardware = await get_space_hardware(app_reference, hf_token);
|
884
|
+
}
|
885
|
+
} catch (e) {
|
886
|
+
throw Error(SPACE_METADATA_ERROR_MSG + e.message);
|
832
887
|
}
|
833
888
|
const requested_hardware = hardware || original_hardware || "cpu-basic";
|
834
889
|
body.hardware = requested_hardware;
|
@@ -854,58 +909,73 @@ async function duplicate(app_reference, options) {
|
|
854
909
|
}
|
855
910
|
const duplicated_space = await response.json();
|
856
911
|
await set_space_timeout(`${user}/${space_name}`, timeout || 300, hf_token);
|
857
|
-
return await Client.connect(
|
912
|
+
return await Client.connect(
|
913
|
+
get_space_reference(duplicated_space.url),
|
914
|
+
options
|
915
|
+
);
|
858
916
|
} catch (e) {
|
859
917
|
throw new Error(e);
|
860
918
|
}
|
861
919
|
}
|
862
|
-
function
|
920
|
+
function get_space_reference(url) {
|
921
|
+
const regex = /https:\/\/huggingface.co\/spaces\/([^/]+\/[^/]+)/;
|
922
|
+
const match = url.match(regex);
|
923
|
+
if (match) {
|
924
|
+
return match[1];
|
925
|
+
}
|
926
|
+
}
|
927
|
+
async function open_stream() {
|
863
928
|
let {
|
864
929
|
event_callbacks,
|
865
930
|
unclosed_events,
|
866
931
|
pending_stream_messages,
|
867
932
|
stream_status,
|
868
|
-
config
|
933
|
+
config,
|
934
|
+
jwt
|
869
935
|
} = this;
|
870
936
|
if (!config) {
|
871
937
|
throw new Error("Could not resolve app config");
|
872
938
|
}
|
873
939
|
stream_status.open = true;
|
874
|
-
let
|
940
|
+
let stream = null;
|
875
941
|
let params = new URLSearchParams({
|
876
942
|
session_hash: this.session_hash
|
877
943
|
}).toString();
|
878
944
|
let url = new URL(`${config.root}/queue/data?${params}`);
|
879
|
-
|
880
|
-
|
881
|
-
|
945
|
+
if (jwt) {
|
946
|
+
url.searchParams.set("__sign", jwt);
|
947
|
+
}
|
948
|
+
stream = await this.stream(url);
|
949
|
+
if (!stream) {
|
950
|
+
console.warn("Cannot connect to SSE endpoint: " + url.toString());
|
951
|
+
return;
|
882
952
|
}
|
883
|
-
|
953
|
+
stream.onmessage = async function(event) {
|
884
954
|
let _data = JSON.parse(event.data);
|
885
955
|
if (_data.msg === "close_stream") {
|
886
|
-
close_stream(stream_status,
|
956
|
+
close_stream(stream_status, stream);
|
887
957
|
return;
|
888
958
|
}
|
889
959
|
const event_id = _data.event_id;
|
890
960
|
if (!event_id) {
|
891
961
|
await Promise.all(
|
892
962
|
Object.keys(event_callbacks).map(
|
893
|
-
(event_id2) => (
|
894
|
-
// @ts-ignore
|
895
|
-
event_callbacks[event_id2](_data)
|
896
|
-
)
|
897
|
-
// todo: check event_callbacks
|
963
|
+
(event_id2) => event_callbacks[event_id2](_data)
|
898
964
|
)
|
899
965
|
);
|
900
966
|
} else if (event_callbacks[event_id] && config) {
|
901
967
|
if (_data.msg === "process_completed" && ["sse", "sse_v1", "sse_v2", "sse_v2.1"].includes(config.protocol)) {
|
902
968
|
unclosed_events.delete(event_id);
|
903
969
|
if (unclosed_events.size === 0) {
|
904
|
-
close_stream(stream_status,
|
970
|
+
close_stream(stream_status, stream);
|
905
971
|
}
|
906
972
|
}
|
907
973
|
let fn2 = event_callbacks[event_id];
|
908
|
-
|
974
|
+
if (typeof window !== "undefined") {
|
975
|
+
window.setTimeout(fn2, 0, _data);
|
976
|
+
} else {
|
977
|
+
setImmediate(fn2, _data);
|
978
|
+
}
|
909
979
|
} else {
|
910
980
|
if (!pending_stream_messages[event_id]) {
|
911
981
|
pending_stream_messages[event_id] = [];
|
@@ -913,25 +983,22 @@ function open_stream() {
|
|
913
983
|
pending_stream_messages[event_id].push(_data);
|
914
984
|
}
|
915
985
|
};
|
916
|
-
|
986
|
+
stream.onerror = async function() {
|
917
987
|
await Promise.all(
|
918
988
|
Object.keys(event_callbacks).map(
|
919
|
-
(event_id) => (
|
920
|
-
|
921
|
-
|
922
|
-
|
923
|
-
message: BROKEN_CONNECTION_MSG
|
924
|
-
})
|
925
|
-
)
|
989
|
+
(event_id) => event_callbacks[event_id]({
|
990
|
+
msg: "unexpected_error",
|
991
|
+
message: BROKEN_CONNECTION_MSG
|
992
|
+
})
|
926
993
|
)
|
927
994
|
);
|
928
|
-
close_stream(stream_status,
|
995
|
+
close_stream(stream_status, stream);
|
929
996
|
};
|
930
997
|
}
|
931
|
-
function close_stream(stream_status,
|
932
|
-
if (stream_status &&
|
998
|
+
function close_stream(stream_status, stream) {
|
999
|
+
if (stream_status && stream) {
|
933
1000
|
stream_status.open = false;
|
934
|
-
|
1001
|
+
stream == null ? void 0 : stream.close();
|
935
1002
|
}
|
936
1003
|
}
|
937
1004
|
function apply_diff_stream(pending_diff_streams, event_id, data) {
|
@@ -1023,7 +1090,7 @@ function submit(endpoint, data, event_data, trigger_id) {
|
|
1023
1090
|
};
|
1024
1091
|
const { hf_token } = this.options;
|
1025
1092
|
const {
|
1026
|
-
|
1093
|
+
fetch: fetch2,
|
1027
1094
|
app_reference,
|
1028
1095
|
config,
|
1029
1096
|
session_hash,
|
@@ -1046,8 +1113,9 @@ function submit(endpoint, data, event_data, trigger_id) {
|
|
1046
1113
|
api_map,
|
1047
1114
|
config
|
1048
1115
|
);
|
1116
|
+
let resolved_data = map_data_to_params(data, api_info);
|
1049
1117
|
let websocket;
|
1050
|
-
let
|
1118
|
+
let stream;
|
1051
1119
|
let protocol = config.protocol ?? "ws";
|
1052
1120
|
const _endpoint = typeof endpoint === "number" ? "/predict" : endpoint;
|
1053
1121
|
let payload;
|
@@ -1080,14 +1148,14 @@ function submit(endpoint, data, event_data, trigger_id) {
|
|
1080
1148
|
}
|
1081
1149
|
cancel_request = { fn_index, session_hash };
|
1082
1150
|
} else {
|
1083
|
-
|
1151
|
+
stream == null ? void 0 : stream.close();
|
1084
1152
|
cancel_request = { event_id };
|
1085
1153
|
}
|
1086
1154
|
try {
|
1087
1155
|
if (!config) {
|
1088
1156
|
throw new Error("Could not resolve app config");
|
1089
1157
|
}
|
1090
|
-
await
|
1158
|
+
await fetch2(`${config.root}/reset`, {
|
1091
1159
|
headers: { "Content-Type": "application/json" },
|
1092
1160
|
method: "POST",
|
1093
1161
|
body: JSON.stringify(cancel_request)
|
@@ -1098,8 +1166,9 @@ function submit(endpoint, data, event_data, trigger_id) {
|
|
1098
1166
|
);
|
1099
1167
|
}
|
1100
1168
|
}
|
1101
|
-
this.handle_blob(
|
1169
|
+
this.handle_blob(config.root, resolved_data, endpoint_info).then(
|
1102
1170
|
async (_payload) => {
|
1171
|
+
var _a;
|
1103
1172
|
payload = {
|
1104
1173
|
data: _payload || [],
|
1105
1174
|
event_data,
|
@@ -1291,13 +1360,16 @@ function submit(endpoint, data, event_data, trigger_id) {
|
|
1291
1360
|
let url = new URL(
|
1292
1361
|
`${config.root}/queue/join?${url_params ? url_params + "&" : ""}${params}`
|
1293
1362
|
);
|
1294
|
-
|
1295
|
-
|
1296
|
-
|
1297
|
-
|
1363
|
+
if (this.jwt) {
|
1364
|
+
url.searchParams.set("__sign", this.jwt);
|
1365
|
+
}
|
1366
|
+
stream = await this.stream(url);
|
1367
|
+
if (!stream) {
|
1368
|
+
return Promise.reject(
|
1369
|
+
new Error("Cannot connect to SSE endpoint: " + url.toString())
|
1298
1370
|
);
|
1299
1371
|
}
|
1300
|
-
|
1372
|
+
stream.onmessage = async function(event) {
|
1301
1373
|
const _data = JSON.parse(event.data);
|
1302
1374
|
const { type, status, data: data2 } = handle_message(
|
1303
1375
|
_data,
|
@@ -1312,7 +1384,7 @@ function submit(endpoint, data, event_data, trigger_id) {
|
|
1312
1384
|
...status
|
1313
1385
|
});
|
1314
1386
|
if (status.stage === "error") {
|
1315
|
-
|
1387
|
+
stream == null ? void 0 : stream.close();
|
1316
1388
|
}
|
1317
1389
|
} else if (type === "data") {
|
1318
1390
|
event_id = _data.event_id;
|
@@ -1331,7 +1403,7 @@ function submit(endpoint, data, event_data, trigger_id) {
|
|
1331
1403
|
fn_index,
|
1332
1404
|
time: /* @__PURE__ */ new Date()
|
1333
1405
|
});
|
1334
|
-
|
1406
|
+
stream == null ? void 0 : stream.close();
|
1335
1407
|
}
|
1336
1408
|
} else if (type === "complete") {
|
1337
1409
|
complete = status;
|
@@ -1374,7 +1446,7 @@ function submit(endpoint, data, event_data, trigger_id) {
|
|
1374
1446
|
endpoint: _endpoint,
|
1375
1447
|
fn_index
|
1376
1448
|
});
|
1377
|
-
|
1449
|
+
stream == null ? void 0 : stream.close();
|
1378
1450
|
}
|
1379
1451
|
}
|
1380
1452
|
};
|
@@ -1387,7 +1459,10 @@ function submit(endpoint, data, event_data, trigger_id) {
|
|
1387
1459
|
fn_index,
|
1388
1460
|
time: /* @__PURE__ */ new Date()
|
1389
1461
|
});
|
1390
|
-
let hostname =
|
1462
|
+
let hostname = "";
|
1463
|
+
if (typeof window !== "undefined") {
|
1464
|
+
hostname = (_a = window == null ? void 0 : window.location) == null ? void 0 : _a.hostname;
|
1465
|
+
}
|
1391
1466
|
let hfhubdev = "dev.spaces.huggingface.tech";
|
1392
1467
|
const origin = hostname.includes(".dev.") ? `https://moon-${hostname.split(".")[1]}.${hfhubdev}` : `https://huggingface.co`;
|
1393
1468
|
const zerogpu_auth_promise = dependency.zerogpu && window.parent != window && config.space_id ? post_message("zerogpu-headers", origin) : Promise.resolve(null);
|
@@ -1401,7 +1476,7 @@ function submit(endpoint, data, event_data, trigger_id) {
|
|
1401
1476
|
headers
|
1402
1477
|
);
|
1403
1478
|
});
|
1404
|
-
post_data_promise.then(([response, status]) => {
|
1479
|
+
post_data_promise.then(async ([response, status]) => {
|
1405
1480
|
if (status === 503) {
|
1406
1481
|
fire_event({
|
1407
1482
|
type: "status",
|
@@ -1485,6 +1560,14 @@ function submit(endpoint, data, event_data, trigger_id) {
|
|
1485
1560
|
endpoint: _endpoint,
|
1486
1561
|
fn_index
|
1487
1562
|
});
|
1563
|
+
if (data2.render_config) {
|
1564
|
+
fire_event({
|
1565
|
+
type: "render",
|
1566
|
+
data: data2.render_config,
|
1567
|
+
endpoint: _endpoint,
|
1568
|
+
fn_index
|
1569
|
+
});
|
1570
|
+
}
|
1488
1571
|
if (complete) {
|
1489
1572
|
fire_event({
|
1490
1573
|
type: "status",
|
@@ -1517,7 +1600,7 @@ function submit(endpoint, data, event_data, trigger_id) {
|
|
1517
1600
|
time: /* @__PURE__ */ new Date()
|
1518
1601
|
});
|
1519
1602
|
if (["sse_v2", "sse_v2.1"].includes(protocol)) {
|
1520
|
-
close_stream(stream_status,
|
1603
|
+
close_stream(stream_status, stream);
|
1521
1604
|
stream_status.open = false;
|
1522
1605
|
}
|
1523
1606
|
}
|
@@ -1531,7 +1614,7 @@ function submit(endpoint, data, event_data, trigger_id) {
|
|
1531
1614
|
event_callbacks[event_id] = callback;
|
1532
1615
|
unclosed_events.add(event_id);
|
1533
1616
|
if (!stream_status.open) {
|
1534
|
-
this.open_stream();
|
1617
|
+
await this.open_stream();
|
1535
1618
|
}
|
1536
1619
|
}
|
1537
1620
|
});
|
@@ -1589,6 +1672,7 @@ class Client {
|
|
1589
1672
|
__publicField(this, "heartbeat_event", null);
|
1590
1673
|
__publicField(this, "view_api");
|
1591
1674
|
__publicField(this, "upload_files");
|
1675
|
+
__publicField(this, "upload");
|
1592
1676
|
__publicField(this, "handle_blob");
|
1593
1677
|
__publicField(this, "post_data");
|
1594
1678
|
__publicField(this, "submit");
|
@@ -1605,15 +1689,23 @@ class Client {
|
|
1605
1689
|
this.predict = predict.bind(this);
|
1606
1690
|
this.open_stream = open_stream.bind(this);
|
1607
1691
|
this.resolve_config = resolve_config.bind(this);
|
1692
|
+
this.upload = upload.bind(this);
|
1608
1693
|
}
|
1609
|
-
|
1694
|
+
fetch(input, init) {
|
1610
1695
|
return fetch(input, init);
|
1611
1696
|
}
|
1612
|
-
|
1613
|
-
if (typeof window
|
1697
|
+
async stream(url) {
|
1698
|
+
if (typeof window === "undefined" || typeof EventSource === "undefined") {
|
1699
|
+
try {
|
1700
|
+
const EventSourceModule = await import("eventsource");
|
1701
|
+
return new EventSourceModule.default(url.toString());
|
1702
|
+
} catch (error) {
|
1703
|
+
console.error("Failed to load EventSource module:", error);
|
1704
|
+
throw error;
|
1705
|
+
}
|
1706
|
+
} else {
|
1614
1707
|
return new EventSource(url.toString());
|
1615
1708
|
}
|
1616
|
-
return null;
|
1617
1709
|
}
|
1618
1710
|
async init() {
|
1619
1711
|
var _a;
|
@@ -1626,11 +1718,11 @@ class Client {
|
|
1626
1718
|
await this._resolve_config().then(async ({ config }) => {
|
1627
1719
|
if (config) {
|
1628
1720
|
this.config = config;
|
1629
|
-
if (this.config) {
|
1721
|
+
if (this.config && this.config.connect_heartbeat) {
|
1630
1722
|
const heartbeat_url = new URL(
|
1631
1723
|
`${this.config.root}/heartbeat/${this.session_hash}`
|
1632
1724
|
);
|
1633
|
-
this.heartbeat_event = this.
|
1725
|
+
this.heartbeat_event = await this.stream(heartbeat_url);
|
1634
1726
|
if (this.config.space_id && this.options.hf_token) {
|
1635
1727
|
this.jwt = await get_jwt(
|
1636
1728
|
this.config.space_id,
|
@@ -1641,7 +1733,7 @@ class Client {
|
|
1641
1733
|
}
|
1642
1734
|
});
|
1643
1735
|
} catch (e) {
|
1644
|
-
throw Error(
|
1736
|
+
throw Error(CONFIG_ERROR_MSG + e.message);
|
1645
1737
|
}
|
1646
1738
|
this.api_info = await this.view_api();
|
1647
1739
|
this.api_map = map_names_to_ids(((_a = this.config) == null ? void 0 : _a.dependencies) || []);
|
@@ -1668,7 +1760,7 @@ class Client {
|
|
1668
1760
|
try {
|
1669
1761
|
config = await this.resolve_config(`${http_protocol}//${host}`);
|
1670
1762
|
if (!config) {
|
1671
|
-
throw new Error(
|
1763
|
+
throw new Error(CONFIG_ERROR_MSG);
|
1672
1764
|
}
|
1673
1765
|
return this.config_success(config);
|
1674
1766
|
} catch (e) {
|
@@ -1703,7 +1795,7 @@ class Client {
|
|
1703
1795
|
try {
|
1704
1796
|
this.api_info = await this.view_api();
|
1705
1797
|
} catch (e) {
|
1706
|
-
console.error(
|
1798
|
+
console.error(API_INFO_ERROR_MSG + e.message);
|
1707
1799
|
}
|
1708
1800
|
return this.prepare_return_obj();
|
1709
1801
|
}
|
@@ -1715,7 +1807,7 @@ class Client {
|
|
1715
1807
|
try {
|
1716
1808
|
this.config = await this._resolve_config();
|
1717
1809
|
if (!this.config) {
|
1718
|
-
throw new Error(
|
1810
|
+
throw new Error(CONFIG_ERROR_MSG);
|
1719
1811
|
}
|
1720
1812
|
const _config = await this.config_success(this.config);
|
1721
1813
|
return _config;
|
@@ -1735,7 +1827,7 @@ class Client {
|
|
1735
1827
|
async component_server(component_id, fn_name, data) {
|
1736
1828
|
var _a;
|
1737
1829
|
if (!this.config) {
|
1738
|
-
throw new Error(
|
1830
|
+
throw new Error(CONFIG_ERROR_MSG);
|
1739
1831
|
}
|
1740
1832
|
const headers = {};
|
1741
1833
|
const { hf_token } = this.options;
|
@@ -1776,14 +1868,11 @@ class Client {
|
|
1776
1868
|
headers.Authorization = `Bearer ${hf_token}`;
|
1777
1869
|
}
|
1778
1870
|
try {
|
1779
|
-
const response = await this.
|
1780
|
-
|
1781
|
-
|
1782
|
-
|
1783
|
-
|
1784
|
-
headers
|
1785
|
-
}
|
1786
|
-
);
|
1871
|
+
const response = await this.fetch(`${root_url}/component_server/`, {
|
1872
|
+
method: "POST",
|
1873
|
+
body,
|
1874
|
+
headers
|
1875
|
+
});
|
1787
1876
|
if (!response.ok) {
|
1788
1877
|
throw new Error(
|
1789
1878
|
"Could not connect to component server: " + response.statusText
|
@@ -1808,11 +1897,14 @@ class Client {
|
|
1808
1897
|
async function client(app_reference, options = {}) {
|
1809
1898
|
return await Client.connect(app_reference, options);
|
1810
1899
|
}
|
1900
|
+
async function duplicate_space(app_reference, options) {
|
1901
|
+
return await Client.duplicate(app_reference, options);
|
1902
|
+
}
|
1811
1903
|
export {
|
1812
1904
|
Client,
|
1813
1905
|
FileData,
|
1814
1906
|
client,
|
1815
|
-
duplicate,
|
1907
|
+
duplicate_space as duplicate,
|
1816
1908
|
predict,
|
1817
1909
|
prepare_files,
|
1818
1910
|
submit,
|