@gradio/client 2.5.1 → 2.6.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 +11 -0
- package/dist/browser.js +544 -443
- package/dist/helpers/init_helpers.d.ts +1 -1
- package/dist/helpers/init_helpers.d.ts.map +1 -1
- package/dist/index.cjs +145 -7
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +139 -8
- package/dist/index.min.js +428 -327
- package/dist/types.d.ts +5 -5
- package/dist/upload.d.ts.map +1 -1
- package/dist/utils/bucket_sync.d.ts +38 -0
- package/dist/utils/bucket_sync.d.ts.map +1 -0
- package/dist/utils/run_history.d.ts +9 -0
- package/dist/utils/run_history.d.ts.map +1 -1
- package/dist/utils/submit.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/helpers/init_helpers.ts +21 -4
- package/src/index.ts +12 -0
- package/src/test/bucket_sync.test.ts +138 -0
- package/src/test/run_history.test.ts +46 -0
- package/src/test/submit.test.ts +38 -1
- package/src/test/upload.test.ts +25 -0
- package/src/types.ts +5 -5
- package/src/upload.ts +5 -1
- package/src/utils/bucket_sync.ts +153 -0
- package/src/utils/run_history.ts +64 -1
- package/src/utils/submit.ts +11 -2
|
@@ -21,7 +21,7 @@ export declare function get_jwt(space: string, token: `hf_${string}`, cookies?:
|
|
|
21
21
|
*/
|
|
22
22
|
export declare function normalise_token_option(options: ClientOptions): void;
|
|
23
23
|
export declare function map_names_to_ids(fns: Config["dependencies"]): Record<string, number>;
|
|
24
|
-
export declare function resolve_config_root(root: string, current_location: string): string;
|
|
24
|
+
export declare function resolve_config_root(root: string, current_location: string, prioritize_current_location?: boolean): string;
|
|
25
25
|
export declare function resolve_config(this: Client, endpoint: string, strip_current_page?: boolean): Promise<Config | undefined>;
|
|
26
26
|
export declare function resolve_cookies(this: Client): Promise<void>;
|
|
27
27
|
export declare function get_cookie_header(http_protocol: string, host: string, auth: [string, string], _fetch: typeof fetch, token?: `hf_${string}`, credentials?: RequestCredentials): Promise<string | null>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init_helpers.d.ts","sourceRoot":"","sources":["../../src/helpers/init_helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAWtD,OAAO,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC;AAG5B;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAC3B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,OAAO,GACtB,MAAM,CAKR;AAED,wBAAsB,OAAO,CAC5B,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,MAAM,EAAE,EACrB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,GACrB,OAAO,CAAC,MAAM,GAAG,KAAK,CAAC,CAezB;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,CAOnE;AAED,wBAAgB,gBAAgB,CAC/B,GAAG,EAAE,MAAM,CAAC,cAAc,CAAC,GACzB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAOxB;AAED,wBAAgB,mBAAmB,CAClC,IAAI,EAAE,MAAM,EACZ,gBAAgB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"init_helpers.d.ts","sourceRoot":"","sources":["../../src/helpers/init_helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAWtD,OAAO,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC;AAG5B;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAC3B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,OAAO,GACtB,MAAM,CAKR;AAED,wBAAsB,OAAO,CAC5B,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,MAAM,EAAE,EACrB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,GACrB,OAAO,CAAC,MAAM,GAAG,KAAK,CAAC,CAezB;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,CAOnE;AAED,wBAAgB,gBAAgB,CAC/B,GAAG,EAAE,MAAM,CAAC,cAAc,CAAC,GACzB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAOxB;AAED,wBAAgB,mBAAmB,CAClC,IAAI,EAAE,MAAM,EACZ,gBAAgB,EAAE,MAAM,EACxB,2BAA2B,UAAQ,GACjC,MAAM,CAqBR;AAED,wBAAsB,cAAc,CACnC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,kBAAkB,UAAO,GACvB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAoE7B;AAsCD,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAsBjE;AAGD,wBAAsB,iBAAiB,CACtC,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EACtB,MAAM,EAAE,OAAO,KAAK,EACpB,KAAK,CAAC,EAAE,MAAM,MAAM,EAAE,EACtB,WAAW,CAAC,EAAE,kBAAkB,GAC9B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAyBxB;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG;IACrD,WAAW,EAAE,IAAI,GAAG,KAAK,CAAC;IAC1B,aAAa,EAAE,OAAO,GAAG,QAAQ,CAAC;IAClC,IAAI,EAAE,MAAM,CAAC;CACb,CAkBA;AAED,eAAO,MAAM,qBAAqB,GAAI,eAAe,MAAM,KAAG,MAAM,EAUnE,CAAC"}
|
package/dist/index.cjs
CHANGED
|
@@ -63,9 +63,11 @@ function map_names_to_ids(fns) {
|
|
|
63
63
|
});
|
|
64
64
|
return apis;
|
|
65
65
|
}
|
|
66
|
-
function resolve_config_root(root, current_location) {
|
|
67
|
-
const root_url = new URL(root, current_location);
|
|
66
|
+
function resolve_config_root(root, current_location, prioritize_current_location = false) {
|
|
68
67
|
const current_url = new URL(current_location);
|
|
68
|
+
const root_url = new URL(root, current_url);
|
|
69
|
+
const is_colab_runtime = root_url.hostname.endsWith(".colab-user-runtimes.internal") || root_url.hostname.endsWith(".codatalab-user-runtimes.internal");
|
|
70
|
+
if (prioritize_current_location || is_colab_runtime) return new URL(new URL(root, current_url).pathname, current_url).toString().replace(/\/$/, "");
|
|
69
71
|
if (root_url.hostname !== current_url.hostname) return root;
|
|
70
72
|
root_url.protocol = current_url.protocol;
|
|
71
73
|
root_url.host = current_url.host;
|
|
@@ -88,7 +90,7 @@ async function resolve_config(endpoint, strip_current_page = true) {
|
|
|
88
90
|
};
|
|
89
91
|
}
|
|
90
92
|
const config = { ...window.gradio_config };
|
|
91
|
-
config.root = resolve_config_root(config.root, location.href);
|
|
93
|
+
config.root = resolve_config_root(config.root, location.href, config.is_colab);
|
|
92
94
|
return config;
|
|
93
95
|
} else if (endpoint) {
|
|
94
96
|
let config_url = join_urls(endpoint, this.deep_link ? CONFIG_URL + "?deep_link=" + this.deep_link : CONFIG_URL);
|
|
@@ -610,10 +612,11 @@ async function upload(file_data, root_url, upload_id, max_file_size) {
|
|
|
610
612
|
if (response.error) throw new Error(response.error);
|
|
611
613
|
else {
|
|
612
614
|
if (response.files) return response.files.map((f, i) => {
|
|
615
|
+
const encoded_path = f.split("/").map((segment) => encodeURIComponent(segment)).join("/");
|
|
613
616
|
return new FileData({
|
|
614
617
|
...file_data[i],
|
|
615
618
|
path: f,
|
|
616
|
-
url: `${root_url}${this.api_prefix}/file=${
|
|
619
|
+
url: `${root_url}${this.api_prefix}/file=${encoded_path}`
|
|
617
620
|
});
|
|
618
621
|
});
|
|
619
622
|
return [];
|
|
@@ -1433,6 +1436,7 @@ function readable_stream(input, init = {}) {
|
|
|
1433
1436
|
var KEY_ROOT = "gradio:run-history:";
|
|
1434
1437
|
var STORAGE_PREFIX = `${KEY_ROOT}v2:`;
|
|
1435
1438
|
var REPLAY_PREFIX = `${KEY_ROOT}replay:v2:`;
|
|
1439
|
+
var DESTINATION_PREFIX = `${KEY_ROOT}destination:v1:`;
|
|
1436
1440
|
var MAX_RUNS = 100;
|
|
1437
1441
|
var MAX_APPS = 8;
|
|
1438
1442
|
/**
|
|
@@ -1470,6 +1474,34 @@ function replay_key(scope) {
|
|
|
1470
1474
|
const key = storage_key(scope);
|
|
1471
1475
|
return key ? key.replace(STORAGE_PREFIX, REPLAY_PREFIX) : null;
|
|
1472
1476
|
}
|
|
1477
|
+
function destination_key(scope) {
|
|
1478
|
+
const key = storage_key(scope);
|
|
1479
|
+
return key ? key.replace(STORAGE_PREFIX, DESTINATION_PREFIX) : null;
|
|
1480
|
+
}
|
|
1481
|
+
function read_run_history_storage_impl(scope) {
|
|
1482
|
+
const key = destination_key(scope);
|
|
1483
|
+
if (!key) return { type: "browser" };
|
|
1484
|
+
try {
|
|
1485
|
+
const value = JSON.parse(window.localStorage.getItem(key) || "null");
|
|
1486
|
+
if (typeof value?.bucket_id === "string") return value.type === "bucket" ? {
|
|
1487
|
+
type: "bucket",
|
|
1488
|
+
bucket_id: value.bucket_id
|
|
1489
|
+
} : {
|
|
1490
|
+
type: "browser",
|
|
1491
|
+
bucket_id: value.bucket_id
|
|
1492
|
+
};
|
|
1493
|
+
return { type: "browser" };
|
|
1494
|
+
} catch {
|
|
1495
|
+
return { type: "browser" };
|
|
1496
|
+
}
|
|
1497
|
+
}
|
|
1498
|
+
function set_run_history_storage_impl(scope, storage) {
|
|
1499
|
+
const key = destination_key(scope);
|
|
1500
|
+
if (!key) return;
|
|
1501
|
+
if (storage.type === "browser" && !storage.bucket_id) window.localStorage.removeItem(key);
|
|
1502
|
+
else window.localStorage.setItem(key, JSON.stringify(storage));
|
|
1503
|
+
notify_run_history_change();
|
|
1504
|
+
}
|
|
1473
1505
|
/** When a run was most recently saved under a key, for deciding what to drop. */
|
|
1474
1506
|
function last_saved_at(key) {
|
|
1475
1507
|
try {
|
|
@@ -1486,7 +1518,7 @@ function last_saved_at(key) {
|
|
|
1486
1518
|
*/
|
|
1487
1519
|
function prune_apps(current_key) {
|
|
1488
1520
|
const keys = Object.keys(window.localStorage).filter((key) => key.startsWith(KEY_ROOT));
|
|
1489
|
-
const stale = [...keys.filter((key) => !key.startsWith(STORAGE_PREFIX) && !key.startsWith(REPLAY_PREFIX)), ...keys.filter((key) => key.startsWith(STORAGE_PREFIX) && key !== current_key).sort((a, b) => last_saved_at(b) - last_saved_at(a)).slice(MAX_APPS - 1)];
|
|
1521
|
+
const stale = [...keys.filter((key) => !key.startsWith(STORAGE_PREFIX) && !key.startsWith(REPLAY_PREFIX) && !key.startsWith(DESTINATION_PREFIX)), ...keys.filter((key) => key.startsWith(STORAGE_PREFIX) && key !== current_key).sort((a, b) => last_saved_at(b) - last_saved_at(a)).slice(MAX_APPS - 1)];
|
|
1490
1522
|
for (const key of stale) try {
|
|
1491
1523
|
window.localStorage.removeItem(key);
|
|
1492
1524
|
window.sessionStorage.removeItem(key.replace(STORAGE_PREFIX, REPLAY_PREFIX));
|
|
@@ -1616,6 +1648,7 @@ function apply_run_history_replay_impl(config) {
|
|
|
1616
1648
|
return run ? restore_run_impl(config, run) : false;
|
|
1617
1649
|
}
|
|
1618
1650
|
function start_run_history_impl(options) {
|
|
1651
|
+
if (read_run_history_storage_impl(options).type === "bucket") return null;
|
|
1619
1652
|
const key = storage_key(options);
|
|
1620
1653
|
if (!key) return null;
|
|
1621
1654
|
prune_apps(key);
|
|
@@ -1695,6 +1728,12 @@ function mark_complete(run, event) {
|
|
|
1695
1728
|
function read_run_history(scope) {
|
|
1696
1729
|
return safely(() => read_run_history_impl(scope), []);
|
|
1697
1730
|
}
|
|
1731
|
+
function read_run_history_storage(scope) {
|
|
1732
|
+
return safely(() => read_run_history_storage_impl(scope), { type: "browser" });
|
|
1733
|
+
}
|
|
1734
|
+
function set_run_history_storage(scope, storage) {
|
|
1735
|
+
safely(() => set_run_history_storage_impl(scope, storage), void 0);
|
|
1736
|
+
}
|
|
1698
1737
|
function clear_run_history(scope) {
|
|
1699
1738
|
safely(() => clear_run_history_impl(scope), void 0);
|
|
1700
1739
|
}
|
|
@@ -1735,7 +1774,7 @@ function submit(endpoint, data = {}, event_data, trigger_id, all_events, additio
|
|
|
1735
1774
|
try {
|
|
1736
1775
|
const { token } = this.options;
|
|
1737
1776
|
const { fetch, app_reference, config, session_hash, api_info, api_map, stream_status, pending_stream_messages, pending_diff_streams, event_callbacks, unclosed_events, post_data, options, api_prefix } = this;
|
|
1738
|
-
const
|
|
1777
|
+
const base_headers = additional_headers || { "x-gradio-user": "api" };
|
|
1739
1778
|
const that = this;
|
|
1740
1779
|
if (!api_info) throw new Error(NO_API_INFO_MSG);
|
|
1741
1780
|
if (!config) throw new Error("Could not resolve app config");
|
|
@@ -1760,6 +1799,11 @@ function submit(endpoint, data = {}, event_data, trigger_id, all_events, additio
|
|
|
1760
1799
|
app_id: config.app_id,
|
|
1761
1800
|
username: config.username
|
|
1762
1801
|
};
|
|
1802
|
+
const history_storage = read_run_history_storage(history_scope);
|
|
1803
|
+
const addt_headers = {
|
|
1804
|
+
...base_headers,
|
|
1805
|
+
...history_enabled && history_storage.type === "bucket" ? { "x-gradio-history-bucket": history_storage.bucket_id } : {}
|
|
1806
|
+
};
|
|
1763
1807
|
const history_run_id = !history_enabled || !is_documented_endpoint ? null : start_run_history({
|
|
1764
1808
|
...history_scope,
|
|
1765
1809
|
endpoint: history_endpoint,
|
|
@@ -1933,7 +1977,7 @@ function submit(endpoint, data = {}, event_data, trigger_id, all_events, additio
|
|
|
1933
1977
|
...payload,
|
|
1934
1978
|
session_hash,
|
|
1935
1979
|
event_id
|
|
1936
|
-
});
|
|
1980
|
+
}, addt_headers);
|
|
1937
1981
|
if (status !== 200) {
|
|
1938
1982
|
fire_event({
|
|
1939
1983
|
type: "status",
|
|
@@ -2595,21 +2639,115 @@ async function duplicate_space(app_reference, options) {
|
|
|
2595
2639
|
return await Client.duplicate(app_reference, options);
|
|
2596
2640
|
}
|
|
2597
2641
|
//#endregion
|
|
2642
|
+
//#region src/utils/bucket_sync.ts
|
|
2643
|
+
/**
|
|
2644
|
+
* Client for the durable run history in an HF Hub bucket
|
|
2645
|
+
* (`/gradio_api/run-history/*`).
|
|
2646
|
+
*
|
|
2647
|
+
* Read-only by design. Records are written by the server from the run it
|
|
2648
|
+
* actually executed — there is no push function here, and nothing in this
|
|
2649
|
+
* module can create a record.
|
|
2650
|
+
*
|
|
2651
|
+
* Every call names the bucket it is talking about. The server holds no
|
|
2652
|
+
* per-session binding, so two tabs (or two apps on one origin) cannot end up
|
|
2653
|
+
* reading each other's history.
|
|
2654
|
+
*/
|
|
2655
|
+
var BUCKET_ID_RE = /^[a-zA-Z0-9_.-]+\/[a-zA-Z0-9_.-][a-zA-Z0-9_./-]*$/;
|
|
2656
|
+
function is_valid_bucket_id(id) {
|
|
2657
|
+
if (!BUCKET_ID_RE.test(id)) return false;
|
|
2658
|
+
return !id.split("/").some((seg) => seg === "" || seg === "." || seg === "..");
|
|
2659
|
+
}
|
|
2660
|
+
function url(root, path, params) {
|
|
2661
|
+
const query = params ? `?${new URLSearchParams(params)}` : "";
|
|
2662
|
+
const base = root.replace(/\/+$/, "");
|
|
2663
|
+
if (base) return `${base}/gradio_api/run-history/${path}${query}`;
|
|
2664
|
+
if (typeof document !== "undefined" && document.baseURI) return new URL(`gradio_api/run-history/${path}${query}`, document.baseURI).toString();
|
|
2665
|
+
return `gradio_api/run-history/${path}${query}`;
|
|
2666
|
+
}
|
|
2667
|
+
async function parse_error(res) {
|
|
2668
|
+
try {
|
|
2669
|
+
const j = await res.json();
|
|
2670
|
+
return typeof j?.detail === "string" ? j.detail : `${res.status}`;
|
|
2671
|
+
} catch {
|
|
2672
|
+
return `${res.status}`;
|
|
2673
|
+
}
|
|
2674
|
+
}
|
|
2675
|
+
async function request(input, init, fallback, pick) {
|
|
2676
|
+
try {
|
|
2677
|
+
const res = await fetch(input, {
|
|
2678
|
+
credentials: "include",
|
|
2679
|
+
...init
|
|
2680
|
+
});
|
|
2681
|
+
if (!res.ok) return {
|
|
2682
|
+
ok: false,
|
|
2683
|
+
status: res.status,
|
|
2684
|
+
data: fallback,
|
|
2685
|
+
detail: await parse_error(res)
|
|
2686
|
+
};
|
|
2687
|
+
return {
|
|
2688
|
+
ok: true,
|
|
2689
|
+
status: res.status,
|
|
2690
|
+
data: pick(await res.json())
|
|
2691
|
+
};
|
|
2692
|
+
} catch (e) {
|
|
2693
|
+
return {
|
|
2694
|
+
ok: false,
|
|
2695
|
+
status: 0,
|
|
2696
|
+
data: fallback,
|
|
2697
|
+
detail: String(e)
|
|
2698
|
+
};
|
|
2699
|
+
}
|
|
2700
|
+
}
|
|
2701
|
+
/**
|
|
2702
|
+
* Create the bucket if it does not exist and confirm it is writable. Stores
|
|
2703
|
+
* nothing server-side — the caller keeps its own choice and names it on every
|
|
2704
|
+
* later request.
|
|
2705
|
+
*/
|
|
2706
|
+
async function connect_bucket(root, bucket_id) {
|
|
2707
|
+
if (!is_valid_bucket_id(bucket_id)) return {
|
|
2708
|
+
ok: false,
|
|
2709
|
+
status: 422,
|
|
2710
|
+
data: null,
|
|
2711
|
+
detail: "invalid bucket id"
|
|
2712
|
+
};
|
|
2713
|
+
return request(url(root, "connect"), {
|
|
2714
|
+
method: "POST",
|
|
2715
|
+
headers: { "Content-Type": "application/json" },
|
|
2716
|
+
body: JSON.stringify({ bucket_id })
|
|
2717
|
+
}, null, () => null);
|
|
2718
|
+
}
|
|
2719
|
+
async function list_user_buckets(root) {
|
|
2720
|
+
return request(url(root, "buckets"), {}, [], (b) => Array.isArray(b?.buckets) ? b.buckets : []);
|
|
2721
|
+
}
|
|
2722
|
+
async function list_bucket_records(root, bucket) {
|
|
2723
|
+
return request(url(root, "records", { bucket }), {}, [], (b) => Array.isArray(b?.records) ? b.records : []);
|
|
2724
|
+
}
|
|
2725
|
+
function asset_url(root, bucket, endpoint, record_id, filename) {
|
|
2726
|
+
return url(root, `records/${encodeURIComponent(endpoint)}/${encodeURIComponent(record_id)}/assets/${encodeURIComponent(filename)}`, { bucket });
|
|
2727
|
+
}
|
|
2728
|
+
//#endregion
|
|
2598
2729
|
exports.Client = Client;
|
|
2599
2730
|
exports.FileData = FileData;
|
|
2600
2731
|
exports.MISSING_CREDENTIALS_MSG = MISSING_CREDENTIALS_MSG;
|
|
2601
2732
|
exports.apply_run_history_replay = apply_run_history_replay;
|
|
2733
|
+
exports.asset_url = asset_url;
|
|
2602
2734
|
exports.clear_run_history = clear_run_history;
|
|
2603
2735
|
exports.client = client;
|
|
2736
|
+
exports.connect_bucket = connect_bucket;
|
|
2604
2737
|
exports.consume_run_history_replay = consume_run_history_replay;
|
|
2605
2738
|
exports.delete_run_history = delete_run_history;
|
|
2606
2739
|
exports.duplicate = duplicate_space;
|
|
2607
2740
|
exports.handle_file = handle_file;
|
|
2741
|
+
exports.is_valid_bucket_id = is_valid_bucket_id;
|
|
2742
|
+
exports.list_bucket_records = list_bucket_records;
|
|
2743
|
+
exports.list_user_buckets = list_user_buckets;
|
|
2608
2744
|
exports.on_run_history_change = on_run_history_change;
|
|
2609
2745
|
exports.predict = predict;
|
|
2610
2746
|
exports.prepare_files = prepare_files;
|
|
2611
2747
|
exports.read_run_history = read_run_history;
|
|
2748
|
+
exports.read_run_history_storage = read_run_history_storage;
|
|
2612
2749
|
exports.run_history_url = run_history_url;
|
|
2750
|
+
exports.set_run_history_storage = set_run_history_storage;
|
|
2613
2751
|
exports.stage_run_history_replay = stage_run_history_replay;
|
|
2614
2752
|
exports.submit = submit;
|
|
2615
2753
|
exports.upload = upload;
|
package/dist/index.d.ts
CHANGED
|
@@ -4,7 +4,8 @@ export { submit } from "./utils/submit";
|
|
|
4
4
|
export { upload_files } from "./utils/upload_files";
|
|
5
5
|
export { FileData, upload, prepare_files } from "./upload";
|
|
6
6
|
export { handle_file } from "./helpers/data";
|
|
7
|
-
export { apply_run_history_replay, clear_run_history, consume_run_history_replay, delete_run_history, on_run_history_change, read_run_history, run_history_url, stage_run_history_replay, type ReplayTarget, type RunHistoryScope, type StoredRunComponent, type StoredRun } from "./utils/run_history";
|
|
7
|
+
export { apply_run_history_replay, clear_run_history, consume_run_history_replay, delete_run_history, on_run_history_change, read_run_history, read_run_history_storage, run_history_url, set_run_history_storage, stage_run_history_replay, type ReplayTarget, type RunHistoryStorage, type RunHistoryScope, type StoredRunComponent, type StoredRun } from "./utils/run_history";
|
|
8
|
+
export { asset_url, connect_bucket, is_valid_bucket_id, list_bucket_records, list_user_buckets, type HistoryRecord, type HistoryResult } from "./utils/bucket_sync";
|
|
8
9
|
export type { SpaceStatus, StatusMessage, Status, client_return, UploadResponse, RenderMessage, LogMessage, Payload, Config, ValidationError } from "./types";
|
|
9
10
|
export { MISSING_CREDENTIALS_MSG } from "./constants";
|
|
10
11
|
export { client } from "./client";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EACN,wBAAwB,EACxB,iBAAiB,EACjB,0BAA0B,EAC1B,kBAAkB,EAClB,qBAAqB,EACrB,gBAAgB,EAChB,eAAe,EACf,wBAAwB,EACxB,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACvB,KAAK,SAAS,EACd,MAAM,qBAAqB,CAAC;AAE7B,YAAY,EACX,WAAW,EACX,aAAa,EACb,MAAM,EACN,aAAa,EACb,cAAc,EACd,aAAa,EACb,UAAU,EACV,OAAO,EACP,MAAM,EACN,eAAe,EACf,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAGtD,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,eAAe,IAAI,SAAS,EAAE,MAAM,UAAU,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EACN,wBAAwB,EACxB,iBAAiB,EACjB,0BAA0B,EAC1B,kBAAkB,EAClB,qBAAqB,EACrB,gBAAgB,EAChB,wBAAwB,EACxB,eAAe,EACf,uBAAuB,EACvB,wBAAwB,EACxB,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACvB,KAAK,SAAS,EACd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACN,SAAS,EACT,cAAc,EACd,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,EACjB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,MAAM,qBAAqB,CAAC;AAE7B,YAAY,EACX,WAAW,EACX,aAAa,EACb,MAAM,EACN,aAAa,EACb,cAAc,EACd,aAAa,EACb,UAAU,EACV,OAAO,EACP,MAAM,EACN,eAAe,EACf,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAGtD,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,eAAe,IAAI,SAAS,EAAE,MAAM,UAAU,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -62,9 +62,11 @@ function map_names_to_ids(fns) {
|
|
|
62
62
|
});
|
|
63
63
|
return apis;
|
|
64
64
|
}
|
|
65
|
-
function resolve_config_root(root, current_location) {
|
|
66
|
-
const root_url = new URL(root, current_location);
|
|
65
|
+
function resolve_config_root(root, current_location, prioritize_current_location = false) {
|
|
67
66
|
const current_url = new URL(current_location);
|
|
67
|
+
const root_url = new URL(root, current_url);
|
|
68
|
+
const is_colab_runtime = root_url.hostname.endsWith(".colab-user-runtimes.internal") || root_url.hostname.endsWith(".codatalab-user-runtimes.internal");
|
|
69
|
+
if (prioritize_current_location || is_colab_runtime) return new URL(new URL(root, current_url).pathname, current_url).toString().replace(/\/$/, "");
|
|
68
70
|
if (root_url.hostname !== current_url.hostname) return root;
|
|
69
71
|
root_url.protocol = current_url.protocol;
|
|
70
72
|
root_url.host = current_url.host;
|
|
@@ -87,7 +89,7 @@ async function resolve_config(endpoint, strip_current_page = true) {
|
|
|
87
89
|
};
|
|
88
90
|
}
|
|
89
91
|
const config = { ...window.gradio_config };
|
|
90
|
-
config.root = resolve_config_root(config.root, location.href);
|
|
92
|
+
config.root = resolve_config_root(config.root, location.href, config.is_colab);
|
|
91
93
|
return config;
|
|
92
94
|
} else if (endpoint) {
|
|
93
95
|
let config_url = join_urls(endpoint, this.deep_link ? CONFIG_URL + "?deep_link=" + this.deep_link : CONFIG_URL);
|
|
@@ -609,10 +611,11 @@ async function upload(file_data, root_url, upload_id, max_file_size) {
|
|
|
609
611
|
if (response.error) throw new Error(response.error);
|
|
610
612
|
else {
|
|
611
613
|
if (response.files) return response.files.map((f, i) => {
|
|
614
|
+
const encoded_path = f.split("/").map((segment) => encodeURIComponent(segment)).join("/");
|
|
612
615
|
return new FileData({
|
|
613
616
|
...file_data[i],
|
|
614
617
|
path: f,
|
|
615
|
-
url: `${root_url}${this.api_prefix}/file=${
|
|
618
|
+
url: `${root_url}${this.api_prefix}/file=${encoded_path}`
|
|
616
619
|
});
|
|
617
620
|
});
|
|
618
621
|
return [];
|
|
@@ -1432,6 +1435,7 @@ function readable_stream(input, init = {}) {
|
|
|
1432
1435
|
var KEY_ROOT = "gradio:run-history:";
|
|
1433
1436
|
var STORAGE_PREFIX = `${KEY_ROOT}v2:`;
|
|
1434
1437
|
var REPLAY_PREFIX = `${KEY_ROOT}replay:v2:`;
|
|
1438
|
+
var DESTINATION_PREFIX = `${KEY_ROOT}destination:v1:`;
|
|
1435
1439
|
var MAX_RUNS = 100;
|
|
1436
1440
|
var MAX_APPS = 8;
|
|
1437
1441
|
/**
|
|
@@ -1469,6 +1473,34 @@ function replay_key(scope) {
|
|
|
1469
1473
|
const key = storage_key(scope);
|
|
1470
1474
|
return key ? key.replace(STORAGE_PREFIX, REPLAY_PREFIX) : null;
|
|
1471
1475
|
}
|
|
1476
|
+
function destination_key(scope) {
|
|
1477
|
+
const key = storage_key(scope);
|
|
1478
|
+
return key ? key.replace(STORAGE_PREFIX, DESTINATION_PREFIX) : null;
|
|
1479
|
+
}
|
|
1480
|
+
function read_run_history_storage_impl(scope) {
|
|
1481
|
+
const key = destination_key(scope);
|
|
1482
|
+
if (!key) return { type: "browser" };
|
|
1483
|
+
try {
|
|
1484
|
+
const value = JSON.parse(window.localStorage.getItem(key) || "null");
|
|
1485
|
+
if (typeof value?.bucket_id === "string") return value.type === "bucket" ? {
|
|
1486
|
+
type: "bucket",
|
|
1487
|
+
bucket_id: value.bucket_id
|
|
1488
|
+
} : {
|
|
1489
|
+
type: "browser",
|
|
1490
|
+
bucket_id: value.bucket_id
|
|
1491
|
+
};
|
|
1492
|
+
return { type: "browser" };
|
|
1493
|
+
} catch {
|
|
1494
|
+
return { type: "browser" };
|
|
1495
|
+
}
|
|
1496
|
+
}
|
|
1497
|
+
function set_run_history_storage_impl(scope, storage) {
|
|
1498
|
+
const key = destination_key(scope);
|
|
1499
|
+
if (!key) return;
|
|
1500
|
+
if (storage.type === "browser" && !storage.bucket_id) window.localStorage.removeItem(key);
|
|
1501
|
+
else window.localStorage.setItem(key, JSON.stringify(storage));
|
|
1502
|
+
notify_run_history_change();
|
|
1503
|
+
}
|
|
1472
1504
|
/** When a run was most recently saved under a key, for deciding what to drop. */
|
|
1473
1505
|
function last_saved_at(key) {
|
|
1474
1506
|
try {
|
|
@@ -1485,7 +1517,7 @@ function last_saved_at(key) {
|
|
|
1485
1517
|
*/
|
|
1486
1518
|
function prune_apps(current_key) {
|
|
1487
1519
|
const keys = Object.keys(window.localStorage).filter((key) => key.startsWith(KEY_ROOT));
|
|
1488
|
-
const stale = [...keys.filter((key) => !key.startsWith(STORAGE_PREFIX) && !key.startsWith(REPLAY_PREFIX)), ...keys.filter((key) => key.startsWith(STORAGE_PREFIX) && key !== current_key).sort((a, b) => last_saved_at(b) - last_saved_at(a)).slice(MAX_APPS - 1)];
|
|
1520
|
+
const stale = [...keys.filter((key) => !key.startsWith(STORAGE_PREFIX) && !key.startsWith(REPLAY_PREFIX) && !key.startsWith(DESTINATION_PREFIX)), ...keys.filter((key) => key.startsWith(STORAGE_PREFIX) && key !== current_key).sort((a, b) => last_saved_at(b) - last_saved_at(a)).slice(MAX_APPS - 1)];
|
|
1489
1521
|
for (const key of stale) try {
|
|
1490
1522
|
window.localStorage.removeItem(key);
|
|
1491
1523
|
window.sessionStorage.removeItem(key.replace(STORAGE_PREFIX, REPLAY_PREFIX));
|
|
@@ -1615,6 +1647,7 @@ function apply_run_history_replay_impl(config) {
|
|
|
1615
1647
|
return run ? restore_run_impl(config, run) : false;
|
|
1616
1648
|
}
|
|
1617
1649
|
function start_run_history_impl(options) {
|
|
1650
|
+
if (read_run_history_storage_impl(options).type === "bucket") return null;
|
|
1618
1651
|
const key = storage_key(options);
|
|
1619
1652
|
if (!key) return null;
|
|
1620
1653
|
prune_apps(key);
|
|
@@ -1694,6 +1727,12 @@ function mark_complete(run, event) {
|
|
|
1694
1727
|
function read_run_history(scope) {
|
|
1695
1728
|
return safely(() => read_run_history_impl(scope), []);
|
|
1696
1729
|
}
|
|
1730
|
+
function read_run_history_storage(scope) {
|
|
1731
|
+
return safely(() => read_run_history_storage_impl(scope), { type: "browser" });
|
|
1732
|
+
}
|
|
1733
|
+
function set_run_history_storage(scope, storage) {
|
|
1734
|
+
safely(() => set_run_history_storage_impl(scope, storage), void 0);
|
|
1735
|
+
}
|
|
1697
1736
|
function clear_run_history(scope) {
|
|
1698
1737
|
safely(() => clear_run_history_impl(scope), void 0);
|
|
1699
1738
|
}
|
|
@@ -1734,7 +1773,7 @@ function submit(endpoint, data = {}, event_data, trigger_id, all_events, additio
|
|
|
1734
1773
|
try {
|
|
1735
1774
|
const { token } = this.options;
|
|
1736
1775
|
const { fetch, app_reference, config, session_hash, api_info, api_map, stream_status, pending_stream_messages, pending_diff_streams, event_callbacks, unclosed_events, post_data, options, api_prefix } = this;
|
|
1737
|
-
const
|
|
1776
|
+
const base_headers = additional_headers || { "x-gradio-user": "api" };
|
|
1738
1777
|
const that = this;
|
|
1739
1778
|
if (!api_info) throw new Error(NO_API_INFO_MSG);
|
|
1740
1779
|
if (!config) throw new Error("Could not resolve app config");
|
|
@@ -1759,6 +1798,11 @@ function submit(endpoint, data = {}, event_data, trigger_id, all_events, additio
|
|
|
1759
1798
|
app_id: config.app_id,
|
|
1760
1799
|
username: config.username
|
|
1761
1800
|
};
|
|
1801
|
+
const history_storage = read_run_history_storage(history_scope);
|
|
1802
|
+
const addt_headers = {
|
|
1803
|
+
...base_headers,
|
|
1804
|
+
...history_enabled && history_storage.type === "bucket" ? { "x-gradio-history-bucket": history_storage.bucket_id } : {}
|
|
1805
|
+
};
|
|
1762
1806
|
const history_run_id = !history_enabled || !is_documented_endpoint ? null : start_run_history({
|
|
1763
1807
|
...history_scope,
|
|
1764
1808
|
endpoint: history_endpoint,
|
|
@@ -1932,7 +1976,7 @@ function submit(endpoint, data = {}, event_data, trigger_id, all_events, additio
|
|
|
1932
1976
|
...payload,
|
|
1933
1977
|
session_hash,
|
|
1934
1978
|
event_id
|
|
1935
|
-
});
|
|
1979
|
+
}, addt_headers);
|
|
1936
1980
|
if (status !== 200) {
|
|
1937
1981
|
fire_event({
|
|
1938
1982
|
type: "status",
|
|
@@ -2594,4 +2638,91 @@ async function duplicate_space(app_reference, options) {
|
|
|
2594
2638
|
return await Client.duplicate(app_reference, options);
|
|
2595
2639
|
}
|
|
2596
2640
|
//#endregion
|
|
2597
|
-
|
|
2641
|
+
//#region src/utils/bucket_sync.ts
|
|
2642
|
+
/**
|
|
2643
|
+
* Client for the durable run history in an HF Hub bucket
|
|
2644
|
+
* (`/gradio_api/run-history/*`).
|
|
2645
|
+
*
|
|
2646
|
+
* Read-only by design. Records are written by the server from the run it
|
|
2647
|
+
* actually executed — there is no push function here, and nothing in this
|
|
2648
|
+
* module can create a record.
|
|
2649
|
+
*
|
|
2650
|
+
* Every call names the bucket it is talking about. The server holds no
|
|
2651
|
+
* per-session binding, so two tabs (or two apps on one origin) cannot end up
|
|
2652
|
+
* reading each other's history.
|
|
2653
|
+
*/
|
|
2654
|
+
var BUCKET_ID_RE = /^[a-zA-Z0-9_.-]+\/[a-zA-Z0-9_.-][a-zA-Z0-9_./-]*$/;
|
|
2655
|
+
function is_valid_bucket_id(id) {
|
|
2656
|
+
if (!BUCKET_ID_RE.test(id)) return false;
|
|
2657
|
+
return !id.split("/").some((seg) => seg === "" || seg === "." || seg === "..");
|
|
2658
|
+
}
|
|
2659
|
+
function url(root, path, params) {
|
|
2660
|
+
const query = params ? `?${new URLSearchParams(params)}` : "";
|
|
2661
|
+
const base = root.replace(/\/+$/, "");
|
|
2662
|
+
if (base) return `${base}/gradio_api/run-history/${path}${query}`;
|
|
2663
|
+
if (typeof document !== "undefined" && document.baseURI) return new URL(`gradio_api/run-history/${path}${query}`, document.baseURI).toString();
|
|
2664
|
+
return `gradio_api/run-history/${path}${query}`;
|
|
2665
|
+
}
|
|
2666
|
+
async function parse_error(res) {
|
|
2667
|
+
try {
|
|
2668
|
+
const j = await res.json();
|
|
2669
|
+
return typeof j?.detail === "string" ? j.detail : `${res.status}`;
|
|
2670
|
+
} catch {
|
|
2671
|
+
return `${res.status}`;
|
|
2672
|
+
}
|
|
2673
|
+
}
|
|
2674
|
+
async function request(input, init, fallback, pick) {
|
|
2675
|
+
try {
|
|
2676
|
+
const res = await fetch(input, {
|
|
2677
|
+
credentials: "include",
|
|
2678
|
+
...init
|
|
2679
|
+
});
|
|
2680
|
+
if (!res.ok) return {
|
|
2681
|
+
ok: false,
|
|
2682
|
+
status: res.status,
|
|
2683
|
+
data: fallback,
|
|
2684
|
+
detail: await parse_error(res)
|
|
2685
|
+
};
|
|
2686
|
+
return {
|
|
2687
|
+
ok: true,
|
|
2688
|
+
status: res.status,
|
|
2689
|
+
data: pick(await res.json())
|
|
2690
|
+
};
|
|
2691
|
+
} catch (e) {
|
|
2692
|
+
return {
|
|
2693
|
+
ok: false,
|
|
2694
|
+
status: 0,
|
|
2695
|
+
data: fallback,
|
|
2696
|
+
detail: String(e)
|
|
2697
|
+
};
|
|
2698
|
+
}
|
|
2699
|
+
}
|
|
2700
|
+
/**
|
|
2701
|
+
* Create the bucket if it does not exist and confirm it is writable. Stores
|
|
2702
|
+
* nothing server-side — the caller keeps its own choice and names it on every
|
|
2703
|
+
* later request.
|
|
2704
|
+
*/
|
|
2705
|
+
async function connect_bucket(root, bucket_id) {
|
|
2706
|
+
if (!is_valid_bucket_id(bucket_id)) return {
|
|
2707
|
+
ok: false,
|
|
2708
|
+
status: 422,
|
|
2709
|
+
data: null,
|
|
2710
|
+
detail: "invalid bucket id"
|
|
2711
|
+
};
|
|
2712
|
+
return request(url(root, "connect"), {
|
|
2713
|
+
method: "POST",
|
|
2714
|
+
headers: { "Content-Type": "application/json" },
|
|
2715
|
+
body: JSON.stringify({ bucket_id })
|
|
2716
|
+
}, null, () => null);
|
|
2717
|
+
}
|
|
2718
|
+
async function list_user_buckets(root) {
|
|
2719
|
+
return request(url(root, "buckets"), {}, [], (b) => Array.isArray(b?.buckets) ? b.buckets : []);
|
|
2720
|
+
}
|
|
2721
|
+
async function list_bucket_records(root, bucket) {
|
|
2722
|
+
return request(url(root, "records", { bucket }), {}, [], (b) => Array.isArray(b?.records) ? b.records : []);
|
|
2723
|
+
}
|
|
2724
|
+
function asset_url(root, bucket, endpoint, record_id, filename) {
|
|
2725
|
+
return url(root, `records/${encodeURIComponent(endpoint)}/${encodeURIComponent(record_id)}/assets/${encodeURIComponent(filename)}`, { bucket });
|
|
2726
|
+
}
|
|
2727
|
+
//#endregion
|
|
2728
|
+
export { Client, FileData, MISSING_CREDENTIALS_MSG, apply_run_history_replay, asset_url, clear_run_history, client, connect_bucket, consume_run_history_replay, delete_run_history, duplicate_space as duplicate, handle_file, is_valid_bucket_id, list_bucket_records, list_user_buckets, on_run_history_change, predict, prepare_files, read_run_history, read_run_history_storage, run_history_url, set_run_history_storage, stage_run_history_replay, submit, upload, upload_files };
|