@gradio/client 0.1.4 → 0.3.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 +24 -1
- package/README.md +32 -32
- package/dist/client.d.ts +15 -12
- package/dist/client.d.ts.map +1 -1
- package/dist/index.js +93 -76
- package/dist/types.d.ts +11 -5
- package/dist/types.d.ts.map +1 -1
- package/dist/utils.d.ts +3 -3
- package/dist/utils.d.ts.map +1 -1
- package/package.json +3 -2
- package/src/client.ts +155 -111
- package/src/globals.d.ts +1 -3
- package/src/types.ts +12 -5
- package/src/utils.ts +14 -13
package/src/client.ts
CHANGED
@@ -66,10 +66,10 @@ export async function duplicate(
|
|
66
66
|
hf_token: `hf_${string}`;
|
67
67
|
private?: boolean;
|
68
68
|
status_callback: SpaceStatusCallback;
|
69
|
-
hardware?: typeof hardware_types[number];
|
69
|
+
hardware?: (typeof hardware_types)[number];
|
70
70
|
timeout?: number;
|
71
71
|
}
|
72
|
-
) {
|
72
|
+
): Promise<client_return> {
|
73
73
|
const { hf_token, private: _private, hardware, timeout } = options;
|
74
74
|
|
75
75
|
if (hardware && !hardware_types.includes(hardware)) {
|
@@ -115,38 +115,57 @@ export async function duplicate(
|
|
115
115
|
|
116
116
|
if (response.status === 409) {
|
117
117
|
return client(`${user}/${space_name}`, options);
|
118
|
-
}
|
119
|
-
|
118
|
+
}
|
119
|
+
const duplicated_space = await response.json();
|
120
120
|
|
121
|
-
|
121
|
+
let original_hardware;
|
122
122
|
|
123
|
-
|
124
|
-
|
125
|
-
|
123
|
+
if (!hardware) {
|
124
|
+
original_hardware = await get_space_hardware(app_reference, hf_token);
|
125
|
+
}
|
126
126
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
127
|
+
const requested_hardware = hardware || original_hardware || "cpu-basic";
|
128
|
+
await set_space_hardware(
|
129
|
+
`${user}/${space_name}`,
|
130
|
+
requested_hardware,
|
131
|
+
hf_token
|
132
|
+
);
|
133
133
|
|
134
|
-
|
135
|
-
|
136
|
-
timeout || 300,
|
137
|
-
hf_token
|
138
|
-
);
|
139
|
-
return client(duplicated_space.url, options);
|
140
|
-
}
|
134
|
+
await set_space_timeout(`${user}/${space_name}`, timeout || 300, hf_token);
|
135
|
+
return client(duplicated_space.url, options);
|
141
136
|
} catch (e: any) {
|
142
137
|
throw new Error(e);
|
143
138
|
}
|
144
139
|
}
|
145
140
|
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
141
|
+
interface Client {
|
142
|
+
post_data: (
|
143
|
+
url: string,
|
144
|
+
body: unknown,
|
145
|
+
token?: `hf_${string}`
|
146
|
+
) => Promise<[PostResponse, number]>;
|
147
|
+
upload_files: (
|
148
|
+
root: string,
|
149
|
+
files: File[],
|
150
|
+
token?: `hf_${string}`
|
151
|
+
) => Promise<UploadResponse>;
|
152
|
+
client: (
|
153
|
+
app_reference: string,
|
154
|
+
options: {
|
155
|
+
hf_token?: `hf_${string}`;
|
156
|
+
status_callback?: SpaceStatusCallback;
|
157
|
+
normalise_files?: boolean;
|
158
|
+
}
|
159
|
+
) => Promise<client_return>;
|
160
|
+
handle_blob: (
|
161
|
+
endpoint: string,
|
162
|
+
data: unknown[],
|
163
|
+
api_info: ApiInfo<JsApiData>,
|
164
|
+
token?: `hf_${string}`
|
165
|
+
) => Promise<unknown[]>;
|
166
|
+
}
|
167
|
+
|
168
|
+
export function api_factory(fetch_implementation: typeof fetch): Client {
|
150
169
|
return { post_data, upload_files, client, handle_blob };
|
151
170
|
|
152
171
|
async function post_data(
|
@@ -176,7 +195,7 @@ export function api_factory(fetch_implementation: typeof fetch) {
|
|
176
195
|
|
177
196
|
async function upload_files(
|
178
197
|
root: string,
|
179
|
-
files:
|
198
|
+
files: (Blob | File)[],
|
180
199
|
token?: `hf_${string}`
|
181
200
|
): Promise<UploadResponse> {
|
182
201
|
const headers: {
|
@@ -185,22 +204,27 @@ export function api_factory(fetch_implementation: typeof fetch) {
|
|
185
204
|
if (token) {
|
186
205
|
headers.Authorization = `Bearer ${token}`;
|
187
206
|
}
|
188
|
-
|
189
|
-
const
|
190
|
-
files.
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
method: "POST",
|
196
|
-
body: formData,
|
197
|
-
headers
|
207
|
+
const chunkSize = 1000;
|
208
|
+
const uploadResponses = [];
|
209
|
+
for (let i = 0; i < files.length; i += chunkSize) {
|
210
|
+
const chunk = files.slice(i, i + chunkSize);
|
211
|
+
const formData = new FormData();
|
212
|
+
chunk.forEach((file) => {
|
213
|
+
formData.append("files", file);
|
198
214
|
});
|
199
|
-
|
200
|
-
|
215
|
+
try {
|
216
|
+
var response = await fetch_implementation(`${root}/upload`, {
|
217
|
+
method: "POST",
|
218
|
+
body: formData,
|
219
|
+
headers
|
220
|
+
});
|
221
|
+
} catch (e) {
|
222
|
+
return { error: BROKEN_CONNECTION_MSG };
|
223
|
+
}
|
224
|
+
const output: UploadResponse["files"] = await response.json();
|
225
|
+
uploadResponses.push(...output);
|
201
226
|
}
|
202
|
-
|
203
|
-
return { files: output };
|
227
|
+
return { files: uploadResponses };
|
204
228
|
}
|
205
229
|
|
206
230
|
async function client(
|
@@ -242,7 +266,7 @@ export function api_factory(fetch_implementation: typeof fetch) {
|
|
242
266
|
jwt = await get_jwt(space_id, hf_token);
|
243
267
|
}
|
244
268
|
|
245
|
-
async function config_success(_config: Config) {
|
269
|
+
async function config_success(_config: Config): Promise<client_return> {
|
246
270
|
config = _config;
|
247
271
|
api_map = map_names_to_ids(_config?.dependencies || []);
|
248
272
|
try {
|
@@ -257,7 +281,7 @@ export function api_factory(fetch_implementation: typeof fetch) {
|
|
257
281
|
};
|
258
282
|
}
|
259
283
|
let api: ApiInfo<JsApiData>;
|
260
|
-
async function handle_space_sucess(status: SpaceStatus) {
|
284
|
+
async function handle_space_sucess(status: SpaceStatus): Promise<void> {
|
261
285
|
if (status_callback) status_callback(status);
|
262
286
|
if (status.status === "running")
|
263
287
|
try {
|
@@ -310,37 +334,50 @@ export function api_factory(fetch_implementation: typeof fetch) {
|
|
310
334
|
}
|
311
335
|
}
|
312
336
|
|
313
|
-
/**
|
314
|
-
* Run a prediction.
|
315
|
-
* @param endpoint - The prediction endpoint to use.
|
316
|
-
* @param status_callback - A function that is called with the current status of the prediction immediately and every time it updates.
|
317
|
-
* @return Returns the data for the prediction or an error message.
|
318
|
-
*/
|
319
337
|
function predict(
|
320
338
|
endpoint: string,
|
321
339
|
data: unknown[],
|
322
340
|
event_data?: unknown
|
323
|
-
) {
|
341
|
+
): Promise<unknown> {
|
324
342
|
let data_returned = false;
|
325
343
|
let status_complete = false;
|
344
|
+
let dependency;
|
345
|
+
if (typeof endpoint === "number") {
|
346
|
+
dependency = config.dependencies[endpoint];
|
347
|
+
} else {
|
348
|
+
const trimmed_endpoint = endpoint.replace(/^\//, "");
|
349
|
+
dependency = config.dependencies[api_map[trimmed_endpoint]];
|
350
|
+
}
|
351
|
+
|
352
|
+
if (dependency.types.continuous) {
|
353
|
+
throw new Error(
|
354
|
+
"Cannot call predict on this function as it may run forever. Use submit instead"
|
355
|
+
);
|
356
|
+
}
|
357
|
+
|
326
358
|
return new Promise((res, rej) => {
|
327
359
|
const app = submit(endpoint, data, event_data);
|
360
|
+
let result;
|
328
361
|
|
329
362
|
app
|
330
363
|
.on("data", (d) => {
|
331
|
-
|
364
|
+
// if complete message comes before data, resolve here
|
332
365
|
if (status_complete) {
|
333
366
|
app.destroy();
|
367
|
+
res(d);
|
334
368
|
}
|
335
|
-
|
369
|
+
data_returned = true;
|
370
|
+
result = d;
|
336
371
|
})
|
337
372
|
.on("status", (status) => {
|
338
373
|
if (status.stage === "error") rej(status);
|
339
|
-
if (status.stage === "complete" && data_returned) {
|
340
|
-
app.destroy();
|
341
|
-
}
|
342
374
|
if (status.stage === "complete") {
|
343
375
|
status_complete = true;
|
376
|
+
app.destroy();
|
377
|
+
// if complete message comes after data, resolve here
|
378
|
+
if (data_returned) {
|
379
|
+
res(result);
|
380
|
+
}
|
344
381
|
}
|
345
382
|
});
|
346
383
|
});
|
@@ -478,6 +515,7 @@ export function api_factory(fetch_implementation: typeof fetch) {
|
|
478
515
|
fire_event({
|
479
516
|
type: "status",
|
480
517
|
stage: "error",
|
518
|
+
broken: true,
|
481
519
|
message: BROKEN_CONNECTION_MSG,
|
482
520
|
queue: true,
|
483
521
|
endpoint: _endpoint,
|
@@ -513,6 +551,14 @@ export function api_factory(fetch_implementation: typeof fetch) {
|
|
513
551
|
websocket.send(JSON.stringify({ ...payload, session_hash }));
|
514
552
|
} else if (type === "complete") {
|
515
553
|
complete = status;
|
554
|
+
} else if (type === "log") {
|
555
|
+
fire_event({
|
556
|
+
type: "log",
|
557
|
+
log: data.log,
|
558
|
+
level: data.level,
|
559
|
+
endpoint: _endpoint,
|
560
|
+
fn_index
|
561
|
+
});
|
516
562
|
} else if (type === "generating") {
|
517
563
|
fire_event({
|
518
564
|
type: "status",
|
@@ -565,7 +611,7 @@ export function api_factory(fetch_implementation: typeof fetch) {
|
|
565
611
|
}
|
566
612
|
});
|
567
613
|
|
568
|
-
function fire_event<K extends EventType>(event: Event<K>) {
|
614
|
+
function fire_event<K extends EventType>(event: Event<K>): void {
|
569
615
|
const narrowed_listener_map: ListenerMap<K> = listener_map;
|
570
616
|
const listeners = narrowed_listener_map[event.type] || [];
|
571
617
|
listeners?.forEach((l) => l(event));
|
@@ -574,7 +620,7 @@ export function api_factory(fetch_implementation: typeof fetch) {
|
|
574
620
|
function on<K extends EventType>(
|
575
621
|
eventType: K,
|
576
622
|
listener: EventListener<K>
|
577
|
-
) {
|
623
|
+
): SubmitReturn {
|
578
624
|
const narrowed_listener_map: ListenerMap<K> = listener_map;
|
579
625
|
const listeners = narrowed_listener_map[eventType] || [];
|
580
626
|
narrowed_listener_map[eventType] = listeners;
|
@@ -586,7 +632,7 @@ export function api_factory(fetch_implementation: typeof fetch) {
|
|
586
632
|
function off<K extends EventType>(
|
587
633
|
eventType: K,
|
588
634
|
listener: EventListener<K>
|
589
|
-
) {
|
635
|
+
): SubmitReturn {
|
590
636
|
const narrowed_listener_map: ListenerMap<K> = listener_map;
|
591
637
|
let listeners = narrowed_listener_map[eventType] || [];
|
592
638
|
listeners = listeners?.filter((l) => l !== listener);
|
@@ -595,7 +641,7 @@ export function api_factory(fetch_implementation: typeof fetch) {
|
|
595
641
|
return { on, off, cancel, destroy };
|
596
642
|
}
|
597
643
|
|
598
|
-
async function cancel() {
|
644
|
+
async function cancel(): Promise<void> {
|
599
645
|
const _status: Status = {
|
600
646
|
stage: "complete",
|
601
647
|
queue: false,
|
@@ -633,7 +679,7 @@ export function api_factory(fetch_implementation: typeof fetch) {
|
|
633
679
|
}
|
634
680
|
}
|
635
681
|
|
636
|
-
function destroy() {
|
682
|
+
function destroy(): void {
|
637
683
|
for (const event_type in listener_map) {
|
638
684
|
listener_map[event_type as "data" | "status"].forEach((fn) => {
|
639
685
|
off(event_type as "data" | "status", fn);
|
@@ -706,7 +752,7 @@ export function api_factory(fetch_implementation: typeof fetch) {
|
|
706
752
|
async function handle_blob(
|
707
753
|
endpoint: string,
|
708
754
|
data: unknown[],
|
709
|
-
api_info
|
755
|
+
api_info: ApiInfo<JsApiData>,
|
710
756
|
token?: `hf_${string}`
|
711
757
|
): Promise<unknown[]> {
|
712
758
|
const blob_refs = await walk_and_store_blobs(
|
@@ -723,9 +769,8 @@ export function api_factory(fetch_implementation: typeof fetch) {
|
|
723
769
|
const file_url = (await upload_files(endpoint, [blob], token))
|
724
770
|
.files[0];
|
725
771
|
return { path, file_url, type };
|
726
|
-
} else {
|
727
|
-
return { path, base64: data, type };
|
728
772
|
}
|
773
|
+
return { path, base64: data, type };
|
729
774
|
})
|
730
775
|
).then((r) => {
|
731
776
|
r.forEach(({ path, file_url, base64, type }) => {
|
@@ -759,27 +804,26 @@ function transform_output(
|
|
759
804
|
remote_url?: string
|
760
805
|
): unknown[] {
|
761
806
|
return data.map((d, i) => {
|
762
|
-
if (api_info
|
807
|
+
if (api_info?.returns?.[i]?.component === "File") {
|
763
808
|
return normalise_file(d, root_url, remote_url);
|
764
|
-
} else if (api_info
|
809
|
+
} else if (api_info?.returns?.[i]?.component === "Gallery") {
|
765
810
|
return d.map((img) => {
|
766
811
|
return Array.isArray(img)
|
767
812
|
? [normalise_file(img[0], root_url, remote_url), img[1]]
|
768
813
|
: [normalise_file(img, root_url, remote_url), null];
|
769
814
|
});
|
770
|
-
} else if (typeof d === "object" && d
|
815
|
+
} else if (typeof d === "object" && d?.is_file) {
|
771
816
|
return normalise_file(d, root_url, remote_url);
|
772
|
-
} else {
|
773
|
-
return d;
|
774
817
|
}
|
818
|
+
return d;
|
775
819
|
});
|
776
820
|
}
|
777
821
|
|
778
822
|
function normalise_file(
|
779
|
-
file:
|
823
|
+
file: FileData[],
|
780
824
|
root: string,
|
781
825
|
root_url: string | null
|
782
|
-
):
|
826
|
+
): FileData[];
|
783
827
|
function normalise_file(
|
784
828
|
file: FileData | string,
|
785
829
|
root: string,
|
@@ -790,11 +834,7 @@ function normalise_file(
|
|
790
834
|
root: string,
|
791
835
|
root_url: string | null
|
792
836
|
): null;
|
793
|
-
function normalise_file(
|
794
|
-
file,
|
795
|
-
root,
|
796
|
-
root_url
|
797
|
-
): Array<FileData> | FileData | null {
|
837
|
+
function normalise_file(file, root, root_url): FileData[] | FileData | null {
|
798
838
|
if (file == null) return null;
|
799
839
|
if (typeof file === "string") {
|
800
840
|
return {
|
@@ -802,7 +842,7 @@ function normalise_file(
|
|
802
842
|
data: file
|
803
843
|
};
|
804
844
|
} else if (Array.isArray(file)) {
|
805
|
-
const normalized_file:
|
845
|
+
const normalized_file: (FileData | null)[] = [];
|
806
846
|
|
807
847
|
for (const x of file) {
|
808
848
|
if (x === null) {
|
@@ -812,7 +852,7 @@ function normalise_file(
|
|
812
852
|
}
|
813
853
|
}
|
814
854
|
|
815
|
-
return normalized_file as
|
855
|
+
return normalized_file as FileData[];
|
816
856
|
} else if (file.is_file) {
|
817
857
|
if (!root_url) {
|
818
858
|
file.data = root + "/file=" + file.name;
|
@@ -858,7 +898,7 @@ function get_type(
|
|
858
898
|
component: string,
|
859
899
|
serializer: string,
|
860
900
|
signature_type: "return" | "parameter"
|
861
|
-
) {
|
901
|
+
): string {
|
862
902
|
switch (type.type) {
|
863
903
|
case "string":
|
864
904
|
return "string";
|
@@ -882,11 +922,10 @@ function get_type(
|
|
882
922
|
return signature_type === "parameter"
|
883
923
|
? "(Blob | File | Buffer)[]"
|
884
924
|
: `{ name: string; data: string; size?: number; is_file?: boolean; orig_name?: string}[]`;
|
885
|
-
} else {
|
886
|
-
return signature_type === "parameter"
|
887
|
-
? "Blob | File | Buffer"
|
888
|
-
: `{ name: string; data: string; size?: number; is_file?: boolean; orig_name?: string}`;
|
889
925
|
}
|
926
|
+
return signature_type === "parameter"
|
927
|
+
? "Blob | File | Buffer"
|
928
|
+
: `{ name: string; data: string; size?: number; is_file?: boolean; orig_name?: string}`;
|
890
929
|
} else if (serializer === "GallerySerializable") {
|
891
930
|
return signature_type === "parameter"
|
892
931
|
? "[(Blob | File | Buffer), (string | null)][]"
|
@@ -897,16 +936,15 @@ function get_type(
|
|
897
936
|
function get_description(
|
898
937
|
type: { type: any; description: string },
|
899
938
|
serializer: string
|
900
|
-
) {
|
939
|
+
): string {
|
901
940
|
if (serializer === "GallerySerializable") {
|
902
941
|
return "array of [file, label] tuples";
|
903
942
|
} else if (serializer === "ListStringSerializable") {
|
904
943
|
return "array of strings";
|
905
944
|
} else if (serializer === "FileSerializable") {
|
906
945
|
return "array of files or single file";
|
907
|
-
} else {
|
908
|
-
return type.description;
|
909
946
|
}
|
947
|
+
return type.description;
|
910
948
|
}
|
911
949
|
|
912
950
|
function transform_api_info(
|
@@ -974,7 +1012,7 @@ async function get_jwt(
|
|
974
1012
|
}
|
975
1013
|
}
|
976
1014
|
|
977
|
-
function update_object(object, newValue, stack) {
|
1015
|
+
function update_object(object, newValue, stack): void {
|
978
1016
|
while (stack.length > 1) {
|
979
1017
|
object = object[stack.shift()];
|
980
1018
|
}
|
@@ -988,7 +1026,14 @@ export async function walk_and_store_blobs(
|
|
988
1026
|
path = [],
|
989
1027
|
root = false,
|
990
1028
|
api_info = undefined
|
991
|
-
)
|
1029
|
+
): Promise<
|
1030
|
+
{
|
1031
|
+
path: string[];
|
1032
|
+
data: string | false;
|
1033
|
+
type: string;
|
1034
|
+
blob: Blob | false;
|
1035
|
+
}[]
|
1036
|
+
> {
|
992
1037
|
if (Array.isArray(param)) {
|
993
1038
|
let blob_refs = [];
|
994
1039
|
|
@@ -1035,10 +1080,9 @@ export async function walk_and_store_blobs(
|
|
1035
1080
|
data = Buffer.from(buffer).toString("base64");
|
1036
1081
|
}
|
1037
1082
|
|
1038
|
-
return [{ path, data, type }];
|
1039
|
-
} else {
|
1040
|
-
return [{ path: path, blob: param, type }];
|
1083
|
+
return [{ path, data, type, blob: false }];
|
1041
1084
|
}
|
1085
|
+
return [{ path: path, blob: param, type, data: false }];
|
1042
1086
|
} else if (typeof param === "object") {
|
1043
1087
|
let blob_refs = [];
|
1044
1088
|
for (let key in param) {
|
@@ -1057,12 +1101,11 @@ export async function walk_and_store_blobs(
|
|
1057
1101
|
}
|
1058
1102
|
}
|
1059
1103
|
return blob_refs;
|
1060
|
-
} else {
|
1061
|
-
return [];
|
1062
1104
|
}
|
1105
|
+
return [];
|
1063
1106
|
}
|
1064
1107
|
|
1065
|
-
function image_to_data_uri(blob: Blob) {
|
1108
|
+
function image_to_data_uri(blob: Blob): Promise<string | ArrayBuffer> {
|
1066
1109
|
return new Promise((resolve, _) => {
|
1067
1110
|
const reader = new FileReader();
|
1068
1111
|
reader.onloadend = () => resolve(reader.result);
|
@@ -1070,7 +1113,7 @@ function image_to_data_uri(blob: Blob) {
|
|
1070
1113
|
});
|
1071
1114
|
}
|
1072
1115
|
|
1073
|
-
function skip_queue(id: number, config: Config) {
|
1116
|
+
function skip_queue(id: number, config: Config): boolean {
|
1074
1117
|
return (
|
1075
1118
|
!(config?.dependencies?.[id]?.queue === null
|
1076
1119
|
? config.enable_queue
|
@@ -1090,7 +1133,8 @@ async function resolve_config(
|
|
1090
1133
|
if (
|
1091
1134
|
typeof window !== "undefined" &&
|
1092
1135
|
window.gradio_config &&
|
1093
|
-
location.origin !== "http://localhost:9876"
|
1136
|
+
location.origin !== "http://localhost:9876" &&
|
1137
|
+
!window.gradio_config.dev_mode
|
1094
1138
|
) {
|
1095
1139
|
const path = window.gradio_config.root;
|
1096
1140
|
const config = window.gradio_config;
|
@@ -1106,9 +1150,8 @@ async function resolve_config(
|
|
1106
1150
|
config.path = config.path ?? "";
|
1107
1151
|
config.root = endpoint;
|
1108
1152
|
return config;
|
1109
|
-
} else {
|
1110
|
-
throw new Error("Could not get config.");
|
1111
1153
|
}
|
1154
|
+
throw new Error("Could not get config.");
|
1112
1155
|
}
|
1113
1156
|
|
1114
1157
|
throw new Error("No config or app endpoint found");
|
@@ -1118,7 +1161,7 @@ async function check_space_status(
|
|
1118
1161
|
id: string,
|
1119
1162
|
type: "subdomain" | "space_name",
|
1120
1163
|
status_callback: SpaceStatusCallback
|
1121
|
-
) {
|
1164
|
+
): Promise<void> {
|
1122
1165
|
let endpoint =
|
1123
1166
|
type === "subdomain"
|
1124
1167
|
? `https://huggingface.co/api/spaces/by-subdomain/${id}`
|
@@ -1211,7 +1254,7 @@ function handle_message(
|
|
1211
1254
|
data: any,
|
1212
1255
|
last_status: Status["stage"]
|
1213
1256
|
): {
|
1214
|
-
type: "hash" | "data" | "update" | "complete" | "generating" | "none";
|
1257
|
+
type: "hash" | "data" | "update" | "complete" | "generating" | "log" | "none";
|
1215
1258
|
data?: any;
|
1216
1259
|
status?: Status;
|
1217
1260
|
} {
|
@@ -1256,6 +1299,8 @@ function handle_message(
|
|
1256
1299
|
success: data.success
|
1257
1300
|
}
|
1258
1301
|
};
|
1302
|
+
case "log":
|
1303
|
+
return { type: "log", data: data };
|
1259
1304
|
case "process_generating":
|
1260
1305
|
return {
|
1261
1306
|
type: "generating",
|
@@ -1281,20 +1326,19 @@ function handle_message(
|
|
1281
1326
|
success: data.success
|
1282
1327
|
}
|
1283
1328
|
};
|
1284
|
-
} else {
|
1285
|
-
return {
|
1286
|
-
type: "complete",
|
1287
|
-
status: {
|
1288
|
-
queue,
|
1289
|
-
message: !data.success ? data.output.error : undefined,
|
1290
|
-
stage: data.success ? "complete" : "error",
|
1291
|
-
code: data.code,
|
1292
|
-
progress_data: data.progress_data,
|
1293
|
-
eta: data.output.average_duration
|
1294
|
-
},
|
1295
|
-
data: data.success ? data.output : null
|
1296
|
-
};
|
1297
1329
|
}
|
1330
|
+
return {
|
1331
|
+
type: "complete",
|
1332
|
+
status: {
|
1333
|
+
queue,
|
1334
|
+
message: !data.success ? data.output.error : undefined,
|
1335
|
+
stage: data.success ? "complete" : "error",
|
1336
|
+
code: data.code,
|
1337
|
+
progress_data: data.progress_data,
|
1338
|
+
eta: data.output.average_duration
|
1339
|
+
},
|
1340
|
+
data: data.success ? data.output : null
|
1341
|
+
};
|
1298
1342
|
|
1299
1343
|
case "process_starts":
|
1300
1344
|
return {
|
package/src/globals.d.ts
CHANGED
@@ -1,11 +1,9 @@
|
|
1
1
|
declare global {
|
2
2
|
interface Window {
|
3
3
|
__gradio_mode__: "app" | "website";
|
4
|
-
launchGradio: Function;
|
5
|
-
launchGradioFromSpaces: Function;
|
6
4
|
gradio_config: Config;
|
7
|
-
scoped_css_attach: (link: HTMLLinkElement) => void;
|
8
5
|
__is_colab__: boolean;
|
6
|
+
__gradio_space__: string | null;
|
9
7
|
}
|
10
8
|
}
|
11
9
|
|
package/src/types.ts
CHANGED
@@ -21,7 +21,7 @@ export interface Config {
|
|
21
21
|
}
|
22
22
|
|
23
23
|
export interface Payload {
|
24
|
-
data:
|
24
|
+
data: unknown[];
|
25
25
|
fn_index?: number;
|
26
26
|
event_data?: unknown;
|
27
27
|
time?: Date;
|
@@ -33,7 +33,7 @@ export interface PostResponse {
|
|
33
33
|
}
|
34
34
|
export interface UploadResponse {
|
35
35
|
error?: string;
|
36
|
-
files?:
|
36
|
+
files?: string[];
|
37
37
|
}
|
38
38
|
|
39
39
|
export interface Status {
|
@@ -41,20 +41,26 @@ export interface Status {
|
|
41
41
|
code?: string;
|
42
42
|
success?: boolean;
|
43
43
|
stage: "pending" | "error" | "complete" | "generating";
|
44
|
+
broken?: boolean;
|
44
45
|
size?: number;
|
45
46
|
position?: number;
|
46
47
|
eta?: number;
|
47
48
|
message?: string;
|
48
|
-
progress_data?:
|
49
|
+
progress_data?: {
|
49
50
|
progress: number | null;
|
50
51
|
index: number | null;
|
51
52
|
length: number | null;
|
52
53
|
unit: string | null;
|
53
54
|
desc: string | null;
|
54
|
-
}
|
55
|
+
}[];
|
55
56
|
time?: Date;
|
56
57
|
}
|
57
58
|
|
59
|
+
export interface LogMessage {
|
60
|
+
log: string;
|
61
|
+
level: "warning" | "info";
|
62
|
+
}
|
63
|
+
|
58
64
|
export interface SpaceStatusNormal {
|
59
65
|
status: "sleeping" | "running" | "building" | "error" | "stopped";
|
60
66
|
detail:
|
@@ -83,11 +89,12 @@ export type SpaceStatus = SpaceStatusNormal | SpaceStatusError;
|
|
83
89
|
export type status_callback_function = (a: Status) => void;
|
84
90
|
export type SpaceStatusCallback = (a: SpaceStatus) => void;
|
85
91
|
|
86
|
-
export type EventType = "data" | "status";
|
92
|
+
export type EventType = "data" | "status" | "log";
|
87
93
|
|
88
94
|
export interface EventMap {
|
89
95
|
data: Payload;
|
90
96
|
status: Status;
|
97
|
+
log: LogMessage;
|
91
98
|
}
|
92
99
|
|
93
100
|
export type Event<K extends EventType> = {
|
package/src/utils.ts
CHANGED
@@ -14,13 +14,12 @@ export function determine_protocol(endpoint: string): {
|
|
14
14
|
host: host,
|
15
15
|
http_protocol: protocol as "http:" | "https:"
|
16
16
|
};
|
17
|
-
} else {
|
18
|
-
return {
|
19
|
-
ws_protocol: protocol === "https:" ? "wss" : "ws",
|
20
|
-
http_protocol: protocol as "http:" | "https:",
|
21
|
-
host
|
22
|
-
};
|
23
17
|
}
|
18
|
+
return {
|
19
|
+
ws_protocol: protocol === "https:" ? "wss" : "ws",
|
20
|
+
http_protocol: protocol as "http:" | "https:",
|
21
|
+
host
|
22
|
+
};
|
24
23
|
}
|
25
24
|
|
26
25
|
// default to secure if no protocol is provided
|
@@ -87,7 +86,9 @@ export async function process_endpoint(
|
|
87
86
|
};
|
88
87
|
}
|
89
88
|
|
90
|
-
export function map_names_to_ids(
|
89
|
+
export function map_names_to_ids(
|
90
|
+
fns: Config["dependencies"]
|
91
|
+
): Record<string, number> {
|
91
92
|
let apis: Record<string, number> = {};
|
92
93
|
|
93
94
|
fns.forEach(({ api_name }, i) => {
|
@@ -99,7 +100,7 @@ export function map_names_to_ids(fns: Config["dependencies"]) {
|
|
99
100
|
|
100
101
|
const RE_DISABLED_DISCUSSION =
|
101
102
|
/^(?=[^]*\b[dD]iscussions{0,1}\b)(?=[^]*\b[dD]isabled\b)[^]*$/;
|
102
|
-
export async function discussions_enabled(space_id: string) {
|
103
|
+
export async function discussions_enabled(space_id: string): Promise<boolean> {
|
103
104
|
try {
|
104
105
|
const r = await fetch(
|
105
106
|
`https://huggingface.co/api/spaces/${space_id}/discussions`,
|
@@ -110,7 +111,7 @@ export async function discussions_enabled(space_id: string) {
|
|
110
111
|
const error = r.headers.get("x-error-message");
|
111
112
|
|
112
113
|
if (error && RE_DISABLED_DISCUSSION.test(error)) return false;
|
113
|
-
|
114
|
+
return true;
|
114
115
|
} catch (e) {
|
115
116
|
return false;
|
116
117
|
}
|
@@ -119,7 +120,7 @@ export async function discussions_enabled(space_id: string) {
|
|
119
120
|
export async function get_space_hardware(
|
120
121
|
space_id: string,
|
121
122
|
token: `hf_${string}`
|
122
|
-
) {
|
123
|
+
): Promise<(typeof hardware_types)[number]> {
|
123
124
|
const headers: { Authorization?: string } = {};
|
124
125
|
if (token) {
|
125
126
|
headers.Authorization = `Bearer ${token}`;
|
@@ -144,9 +145,9 @@ export async function get_space_hardware(
|
|
144
145
|
|
145
146
|
export async function set_space_hardware(
|
146
147
|
space_id: string,
|
147
|
-
new_hardware: typeof hardware_types[number],
|
148
|
+
new_hardware: (typeof hardware_types)[number],
|
148
149
|
token: `hf_${string}`
|
149
|
-
) {
|
150
|
+
): Promise<(typeof hardware_types)[number]> {
|
150
151
|
const headers: { Authorization?: string } = {};
|
151
152
|
if (token) {
|
152
153
|
headers.Authorization = `Bearer ${token}`;
|
@@ -175,7 +176,7 @@ export async function set_space_timeout(
|
|
175
176
|
space_id: string,
|
176
177
|
timeout: number,
|
177
178
|
token: `hf_${string}`
|
178
|
-
) {
|
179
|
+
): Promise<number> {
|
179
180
|
const headers: { Authorization?: string } = {};
|
180
181
|
if (token) {
|
181
182
|
headers.Authorization = `Bearer ${token}`;
|