@gradio/client 0.17.0 → 0.18.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 +16 -0
- package/dist/client.d.ts +15 -4
- 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/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 +219 -176
- 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 +4 -3
- 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/stream.d.ts +1 -1
- package/dist/utils/stream.d.ts.map +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 +50 -24
- package/src/constants.ts +9 -2
- package/src/helpers/api_info.ts +4 -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 +456 -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 +11 -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 +67 -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 +4 -3
- 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/stream.ts +29 -20
- package/src/utils/submit.ts +23 -15
- 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/src/utils/duplicate.ts
CHANGED
@@ -5,6 +5,7 @@ import {
|
|
5
5
|
} from "../helpers/spaces";
|
6
6
|
import type { DuplicateOptions } from "../types";
|
7
7
|
import { Client } from "../client";
|
8
|
+
import { SPACE_METADATA_ERROR_MSG } from "../constants";
|
8
9
|
|
9
10
|
export async function duplicate(
|
10
11
|
app_reference: string,
|
@@ -47,8 +48,12 @@ export async function duplicate(
|
|
47
48
|
|
48
49
|
let original_hardware;
|
49
50
|
|
50
|
-
|
51
|
-
|
51
|
+
try {
|
52
|
+
if (!hardware) {
|
53
|
+
original_hardware = await get_space_hardware(app_reference, hf_token);
|
54
|
+
}
|
55
|
+
} catch (e) {
|
56
|
+
throw Error(SPACE_METADATA_ERROR_MSG + (e as Error).message);
|
52
57
|
}
|
53
58
|
|
54
59
|
const requested_hardware = hardware || original_hardware || "cpu-basic";
|
@@ -80,8 +85,20 @@ export async function duplicate(
|
|
80
85
|
const duplicated_space = await response.json();
|
81
86
|
|
82
87
|
await set_space_timeout(`${user}/${space_name}`, timeout || 300, hf_token);
|
83
|
-
|
88
|
+
|
89
|
+
return await Client.connect(
|
90
|
+
get_space_reference(duplicated_space.url),
|
91
|
+
options
|
92
|
+
);
|
84
93
|
} catch (e: any) {
|
85
94
|
throw new Error(e);
|
86
95
|
}
|
87
96
|
}
|
97
|
+
|
98
|
+
function get_space_reference(url: string): any {
|
99
|
+
const regex = /https:\/\/huggingface.co\/spaces\/([^/]+\/[^/]+)/;
|
100
|
+
const match = url.match(regex);
|
101
|
+
if (match) {
|
102
|
+
return match[1];
|
103
|
+
}
|
104
|
+
}
|
package/src/utils/handle_blob.ts
CHANGED
package/src/utils/post_data.ts
CHANGED
@@ -16,7 +16,7 @@ export async function post_data(
|
|
16
16
|
headers.Authorization = `Bearer ${this.options.hf_token}`;
|
17
17
|
}
|
18
18
|
try {
|
19
|
-
var response = await this.
|
19
|
+
var response = await this.fetch(url, {
|
20
20
|
method: "POST",
|
21
21
|
body: JSON.stringify(body),
|
22
22
|
headers: { ...headers, ...additional_headers }
|
package/src/utils/stream.ts
CHANGED
@@ -7,7 +7,8 @@ export function open_stream(this: Client): void {
|
|
7
7
|
unclosed_events,
|
8
8
|
pending_stream_messages,
|
9
9
|
stream_status,
|
10
|
-
config
|
10
|
+
config,
|
11
|
+
jwt
|
11
12
|
} = this;
|
12
13
|
|
13
14
|
if (!config) {
|
@@ -16,31 +17,35 @@ export function open_stream(this: Client): void {
|
|
16
17
|
|
17
18
|
stream_status.open = true;
|
18
19
|
|
19
|
-
let
|
20
|
+
let stream: EventSource | null = null;
|
20
21
|
let params = new URLSearchParams({
|
21
22
|
session_hash: this.session_hash
|
22
23
|
}).toString();
|
23
24
|
|
24
25
|
let url = new URL(`${config.root}/queue/data?${params}`);
|
25
|
-
event_source = this.eventSource_factory(url);
|
26
26
|
|
27
|
-
if (
|
28
|
-
|
27
|
+
if (jwt) {
|
28
|
+
url.searchParams.set("__sign", jwt);
|
29
29
|
}
|
30
30
|
|
31
|
-
|
31
|
+
stream = this.stream_factory(url);
|
32
|
+
|
33
|
+
if (!stream) {
|
34
|
+
console.warn("Cannot connect to SSE endpoint: " + url.toString());
|
35
|
+
return;
|
36
|
+
}
|
37
|
+
|
38
|
+
stream.onmessage = async function (event: MessageEvent) {
|
32
39
|
let _data = JSON.parse(event.data);
|
33
40
|
if (_data.msg === "close_stream") {
|
34
|
-
close_stream(stream_status,
|
41
|
+
close_stream(stream_status, stream);
|
35
42
|
return;
|
36
43
|
}
|
37
44
|
const event_id = _data.event_id;
|
38
45
|
if (!event_id) {
|
39
46
|
await Promise.all(
|
40
|
-
Object.keys(event_callbacks).map(
|
41
|
-
(
|
42
|
-
// @ts-ignore
|
43
|
-
event_callbacks[event_id](_data) // todo: check event_callbacks
|
47
|
+
Object.keys(event_callbacks).map((event_id) =>
|
48
|
+
event_callbacks[event_id](_data)
|
44
49
|
)
|
45
50
|
);
|
46
51
|
} else if (event_callbacks[event_id] && config) {
|
@@ -50,11 +55,16 @@ export function open_stream(this: Client): void {
|
|
50
55
|
) {
|
51
56
|
unclosed_events.delete(event_id);
|
52
57
|
if (unclosed_events.size === 0) {
|
53
|
-
close_stream(stream_status,
|
58
|
+
close_stream(stream_status, stream);
|
54
59
|
}
|
55
60
|
}
|
56
|
-
let fn = event_callbacks[event_id];
|
57
|
-
|
61
|
+
let fn: (data: any) => void = event_callbacks[event_id];
|
62
|
+
|
63
|
+
if (typeof window !== "undefined") {
|
64
|
+
window.setTimeout(fn, 0, _data); // need to do this to put the event on the end of the event loop, so the browser can refresh between callbacks and not freeze in case of quick generations. See https://github.com/gradio-app/gradio/pull/7055
|
65
|
+
} else {
|
66
|
+
setImmediate(fn, _data);
|
67
|
+
}
|
58
68
|
} else {
|
59
69
|
if (!pending_stream_messages[event_id]) {
|
60
70
|
pending_stream_messages[event_id] = [];
|
@@ -62,27 +72,26 @@ export function open_stream(this: Client): void {
|
|
62
72
|
pending_stream_messages[event_id].push(_data);
|
63
73
|
}
|
64
74
|
};
|
65
|
-
|
75
|
+
stream.onerror = async function () {
|
66
76
|
await Promise.all(
|
67
77
|
Object.keys(event_callbacks).map((event_id) =>
|
68
|
-
// @ts-ignore
|
69
78
|
event_callbacks[event_id]({
|
70
79
|
msg: "unexpected_error",
|
71
80
|
message: BROKEN_CONNECTION_MSG
|
72
81
|
})
|
73
82
|
)
|
74
83
|
);
|
75
|
-
close_stream(stream_status,
|
84
|
+
close_stream(stream_status, stream);
|
76
85
|
};
|
77
86
|
}
|
78
87
|
|
79
88
|
export function close_stream(
|
80
89
|
stream_status: { open: boolean },
|
81
|
-
|
90
|
+
stream: EventSource | null
|
82
91
|
): void {
|
83
|
-
if (stream_status &&
|
92
|
+
if (stream_status && stream) {
|
84
93
|
stream_status.open = false;
|
85
|
-
|
94
|
+
stream?.close();
|
86
95
|
}
|
87
96
|
}
|
88
97
|
|
package/src/utils/submit.ts
CHANGED
@@ -31,7 +31,7 @@ export function submit(
|
|
31
31
|
try {
|
32
32
|
const { hf_token } = this.options;
|
33
33
|
const {
|
34
|
-
|
34
|
+
fetch,
|
35
35
|
app_reference,
|
36
36
|
config,
|
37
37
|
session_hash,
|
@@ -56,7 +56,7 @@ export function submit(
|
|
56
56
|
);
|
57
57
|
|
58
58
|
let websocket: WebSocket;
|
59
|
-
let
|
59
|
+
let stream: EventSource | null;
|
60
60
|
let protocol = config.protocol ?? "ws";
|
61
61
|
|
62
62
|
const _endpoint = typeof endpoint === "number" ? "/predict" : endpoint;
|
@@ -125,7 +125,7 @@ export function submit(
|
|
125
125
|
}
|
126
126
|
cancel_request = { fn_index, session_hash };
|
127
127
|
} else {
|
128
|
-
|
128
|
+
stream?.close();
|
129
129
|
cancel_request = { event_id };
|
130
130
|
}
|
131
131
|
|
@@ -134,7 +134,7 @@ export function submit(
|
|
134
134
|
throw new Error("Could not resolve app config");
|
135
135
|
}
|
136
136
|
|
137
|
-
await
|
137
|
+
await fetch(`${config.root}/reset`, {
|
138
138
|
headers: { "Content-Type": "application/json" },
|
139
139
|
method: "POST",
|
140
140
|
body: JSON.stringify(cancel_request)
|
@@ -155,7 +155,7 @@ export function submit(
|
|
155
155
|
}
|
156
156
|
}
|
157
157
|
|
158
|
-
this.handle_blob(
|
158
|
+
this.handle_blob(config.root, data, endpoint_info).then(
|
159
159
|
async (_payload) => {
|
160
160
|
payload = {
|
161
161
|
data: _payload || [],
|
@@ -368,15 +368,19 @@ export function submit(
|
|
368
368
|
}${params}`
|
369
369
|
);
|
370
370
|
|
371
|
-
|
371
|
+
if (this.jwt) {
|
372
|
+
url.searchParams.set("__sign", this.jwt);
|
373
|
+
}
|
372
374
|
|
373
|
-
|
374
|
-
|
375
|
-
|
375
|
+
stream = this.stream_factory(url);
|
376
|
+
|
377
|
+
if (!stream) {
|
378
|
+
return Promise.reject(
|
379
|
+
new Error("Cannot connect to SSE endpoint: " + url.toString())
|
376
380
|
);
|
377
381
|
}
|
378
382
|
|
379
|
-
|
383
|
+
stream.onmessage = async function (event: MessageEvent) {
|
380
384
|
const _data = JSON.parse(event.data);
|
381
385
|
const { type, status, data } = handle_message(
|
382
386
|
_data,
|
@@ -393,7 +397,7 @@ export function submit(
|
|
393
397
|
...status
|
394
398
|
});
|
395
399
|
if (status.stage === "error") {
|
396
|
-
|
400
|
+
stream?.close();
|
397
401
|
}
|
398
402
|
} else if (type === "data") {
|
399
403
|
event_id = _data.event_id as string;
|
@@ -412,7 +416,7 @@ export function submit(
|
|
412
416
|
fn_index,
|
413
417
|
time: new Date()
|
414
418
|
});
|
415
|
-
|
419
|
+
stream?.close();
|
416
420
|
}
|
417
421
|
} else if (type === "complete") {
|
418
422
|
complete = status;
|
@@ -456,7 +460,7 @@ export function submit(
|
|
456
460
|
endpoint: _endpoint,
|
457
461
|
fn_index
|
458
462
|
});
|
459
|
-
|
463
|
+
stream?.close();
|
460
464
|
}
|
461
465
|
}
|
462
466
|
};
|
@@ -476,7 +480,11 @@ export function submit(
|
|
476
480
|
fn_index,
|
477
481
|
time: new Date()
|
478
482
|
});
|
479
|
-
let hostname =
|
483
|
+
let hostname = "";
|
484
|
+
if (typeof window !== "undefined") {
|
485
|
+
hostname = window?.location?.hostname;
|
486
|
+
}
|
487
|
+
|
480
488
|
let hfhubdev = "dev.spaces.huggingface.tech";
|
481
489
|
const origin = hostname.includes(".dev.")
|
482
490
|
? `https://moon-${hostname.split(".")[1]}.${hfhubdev}`
|
@@ -623,7 +631,7 @@ export function submit(
|
|
623
631
|
time: new Date()
|
624
632
|
});
|
625
633
|
if (["sse_v2", "sse_v2.1"].includes(protocol)) {
|
626
|
-
close_stream(stream_status,
|
634
|
+
close_stream(stream_status, stream);
|
627
635
|
stream_status.open = false;
|
628
636
|
}
|
629
637
|
}
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import type { Client } from "..";
|
2
|
-
import { BROKEN_CONNECTION_MSG } from "../constants";
|
2
|
+
import { BROKEN_CONNECTION_MSG, UPLOAD_URL } from "../constants";
|
3
3
|
import type { UploadResponse } from "../types";
|
4
4
|
|
5
5
|
export async function upload_files(
|
@@ -11,11 +11,14 @@ export async function upload_files(
|
|
11
11
|
const headers: {
|
12
12
|
Authorization?: string;
|
13
13
|
} = {};
|
14
|
-
if (this
|
14
|
+
if (this?.options?.hf_token) {
|
15
15
|
headers.Authorization = `Bearer ${this.options.hf_token}`;
|
16
16
|
}
|
17
|
+
|
17
18
|
const chunkSize = 1000;
|
18
19
|
const uploadResponses = [];
|
20
|
+
let response: Response;
|
21
|
+
|
19
22
|
for (let i = 0; i < files.length; i += chunkSize) {
|
20
23
|
const chunk = files.slice(i, i + chunkSize);
|
21
24
|
const formData = new FormData();
|
@@ -25,17 +28,19 @@ export async function upload_files(
|
|
25
28
|
try {
|
26
29
|
const upload_url = upload_id
|
27
30
|
? `${root_url}/upload?upload_id=${upload_id}`
|
28
|
-
: `${root_url}
|
29
|
-
|
31
|
+
: `${root_url}/${UPLOAD_URL}`;
|
32
|
+
|
33
|
+
response = await this.fetch(upload_url, {
|
30
34
|
method: "POST",
|
31
35
|
body: formData,
|
32
36
|
headers
|
33
37
|
});
|
34
38
|
} catch (e) {
|
35
|
-
|
39
|
+
throw new Error(BROKEN_CONNECTION_MSG + (e as Error).message);
|
36
40
|
}
|
37
41
|
if (!response.ok) {
|
38
|
-
|
42
|
+
const error_text = await response.text();
|
43
|
+
return { error: `HTTP ${response.status}: ${error_text}` };
|
39
44
|
}
|
40
45
|
const output: UploadResponse["files"] = await response.json();
|
41
46
|
if (output) {
|
package/src/utils/view_api.ts
CHANGED
@@ -28,7 +28,7 @@ export async function view_api(this: Client): Promise<any> {
|
|
28
28
|
let response: Response;
|
29
29
|
|
30
30
|
if (semiver(config?.version || "2.0.0", "3.30") < 0) {
|
31
|
-
response = await this.
|
31
|
+
response = await this.fetch(SPACE_FETCHER_URL, {
|
32
32
|
method: "POST",
|
33
33
|
body: JSON.stringify({
|
34
34
|
serialize: false,
|
@@ -37,12 +37,9 @@ export async function view_api(this: Client): Promise<any> {
|
|
37
37
|
headers
|
38
38
|
});
|
39
39
|
} else {
|
40
|
-
response = await this.
|
41
|
-
|
42
|
-
|
43
|
-
headers
|
44
|
-
}
|
45
|
-
);
|
40
|
+
response = await this.fetch(`${config?.root}/${API_INFO_URL}`, {
|
41
|
+
headers
|
42
|
+
});
|
46
43
|
}
|
47
44
|
|
48
45
|
if (!response.ok) {
|
package/vite.config.js
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
import { defineConfig } from "vite";
|
2
2
|
import { svelte } from "@sveltejs/vite-plugin-svelte";
|
3
3
|
|
4
|
+
const TEST_MODE = process.env.TEST_MODE || "happy-dom";
|
5
|
+
|
4
6
|
export default defineConfig({
|
5
7
|
build: {
|
6
8
|
lib: {
|
@@ -17,6 +19,11 @@ export default defineConfig({
|
|
17
19
|
},
|
18
20
|
plugins: [svelte()],
|
19
21
|
|
22
|
+
mode: process.env.MODE || "development",
|
23
|
+
test: {
|
24
|
+
include: ["./src/test/*.test.*"],
|
25
|
+
environment: TEST_MODE
|
26
|
+
},
|
20
27
|
ssr: {
|
21
28
|
target: "node",
|
22
29
|
format: "esm",
|
@@ -1,173 +0,0 @@
|
|
1
|
-
import { test, describe, assert } from "vitest";
|
2
|
-
import { readFileSync } from "fs";
|
3
|
-
import { join, dirname } from "path";
|
4
|
-
import { fileURLToPath } from "url";
|
5
|
-
import { Blob } from "node:buffer";
|
6
|
-
|
7
|
-
const __dirname = dirname(fileURLToPath(import.meta.url));
|
8
|
-
const image_path = join(
|
9
|
-
__dirname,
|
10
|
-
"..",
|
11
|
-
"..",
|
12
|
-
"..",
|
13
|
-
"demo",
|
14
|
-
"kitchen_sink",
|
15
|
-
"files",
|
16
|
-
"lion.jpg"
|
17
|
-
);
|
18
|
-
|
19
|
-
import { walk_and_store_blobs } from "../helpers/data";
|
20
|
-
import { Client } from "..";
|
21
|
-
|
22
|
-
describe.skip("extract blob parts", () => {
|
23
|
-
test("convert Buffer to Blob", async () => {
|
24
|
-
const image = readFileSync(image_path);
|
25
|
-
await Client.connect("gradio/hello_world_main");
|
26
|
-
const parts = walk_and_store_blobs({
|
27
|
-
data: {
|
28
|
-
image
|
29
|
-
}
|
30
|
-
});
|
31
|
-
|
32
|
-
assert.isTrue(parts[0].blob instanceof Blob);
|
33
|
-
});
|
34
|
-
|
35
|
-
test("leave node Blob as Blob", async () => {
|
36
|
-
const image = new Blob([readFileSync(image_path)]);
|
37
|
-
|
38
|
-
await Client.connect("gradio/hello_world_main");
|
39
|
-
const parts = walk_and_store_blobs({
|
40
|
-
data: {
|
41
|
-
image
|
42
|
-
}
|
43
|
-
});
|
44
|
-
|
45
|
-
assert.isTrue(parts[0].blob instanceof Blob);
|
46
|
-
});
|
47
|
-
|
48
|
-
test("handle deep structures", async () => {
|
49
|
-
const image = new Blob([readFileSync(image_path)]);
|
50
|
-
|
51
|
-
await Client.connect("gradio/hello_world_main");
|
52
|
-
const parts = walk_and_store_blobs({
|
53
|
-
a: {
|
54
|
-
b: {
|
55
|
-
data: {
|
56
|
-
image
|
57
|
-
}
|
58
|
-
}
|
59
|
-
}
|
60
|
-
});
|
61
|
-
|
62
|
-
assert.isTrue(parts[0].blob instanceof Blob);
|
63
|
-
});
|
64
|
-
|
65
|
-
test("handle deep structures with arrays", async () => {
|
66
|
-
const image = new Blob([readFileSync(image_path)]);
|
67
|
-
|
68
|
-
await Client.connect("gradio/hello_world_main");
|
69
|
-
const parts = walk_and_store_blobs({
|
70
|
-
a: [
|
71
|
-
{
|
72
|
-
b: [
|
73
|
-
{
|
74
|
-
data: [
|
75
|
-
{
|
76
|
-
image
|
77
|
-
}
|
78
|
-
]
|
79
|
-
}
|
80
|
-
]
|
81
|
-
}
|
82
|
-
]
|
83
|
-
});
|
84
|
-
|
85
|
-
assert.isTrue(parts[0].blob instanceof Blob);
|
86
|
-
});
|
87
|
-
|
88
|
-
test("handle deep structures with arrays 2", async () => {
|
89
|
-
const image = new Blob([readFileSync(image_path)]);
|
90
|
-
|
91
|
-
await Client.connect("gradio/hello_world_main");
|
92
|
-
const obj = {
|
93
|
-
a: [
|
94
|
-
{
|
95
|
-
b: [
|
96
|
-
{
|
97
|
-
data: [[image], image, [image, [image]]]
|
98
|
-
}
|
99
|
-
]
|
100
|
-
}
|
101
|
-
]
|
102
|
-
};
|
103
|
-
const parts = walk_and_store_blobs(obj);
|
104
|
-
|
105
|
-
function map_path(
|
106
|
-
obj: Record<string, any>,
|
107
|
-
parts: { path: string[]; blob: any }[]
|
108
|
-
) {
|
109
|
-
const { path, blob } = parts[parts.length - 1];
|
110
|
-
let ref = obj;
|
111
|
-
path.forEach((p) => (ref = ref[p]));
|
112
|
-
|
113
|
-
return ref === blob;
|
114
|
-
}
|
115
|
-
|
116
|
-
assert.isTrue(parts[0].blob instanceof Blob);
|
117
|
-
// assert.isTrue(map_path(obj, parts));
|
118
|
-
});
|
119
|
-
});
|
120
|
-
|
121
|
-
describe("handle_blob", () => {
|
122
|
-
test("handle blobs", async () => {
|
123
|
-
const image = new Blob([readFileSync(image_path)]);
|
124
|
-
|
125
|
-
const app = await Client.connect("gradio/hello_world_main");
|
126
|
-
const obj = [
|
127
|
-
{
|
128
|
-
a: [
|
129
|
-
{
|
130
|
-
b: [
|
131
|
-
{
|
132
|
-
data: [[image], image, [image, [image]]]
|
133
|
-
}
|
134
|
-
]
|
135
|
-
}
|
136
|
-
]
|
137
|
-
}
|
138
|
-
];
|
139
|
-
|
140
|
-
const parts = await app.handle_blob(app.config.root, obj, undefined);
|
141
|
-
//@ts-ignore
|
142
|
-
// assert.isString(parts.data[0].a[0].b[0].data[0][0]);
|
143
|
-
});
|
144
|
-
});
|
145
|
-
|
146
|
-
describe.skip("private space", () => {
|
147
|
-
test("can access a private space", async () => {
|
148
|
-
const image = new Blob([readFileSync(image_path)]);
|
149
|
-
|
150
|
-
const app = await Client.connect("pngwn/hello_world", {
|
151
|
-
hf_token: "hf_"
|
152
|
-
});
|
153
|
-
|
154
|
-
console.log(app);
|
155
|
-
const obj = [
|
156
|
-
{
|
157
|
-
a: [
|
158
|
-
{
|
159
|
-
b: [
|
160
|
-
{
|
161
|
-
data: [[image], image, [image, [image]]]
|
162
|
-
}
|
163
|
-
]
|
164
|
-
}
|
165
|
-
]
|
166
|
-
}
|
167
|
-
];
|
168
|
-
|
169
|
-
const parts = await app.handle_blob(app.config.root, obj, undefined);
|
170
|
-
//@ts-ignore
|
171
|
-
assert.isString(parts.data[0].a[0].b[0].data[0][0]);
|
172
|
-
});
|
173
|
-
});
|