@gradio/client 0.16.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 +57 -0
- package/README.md +49 -43
- package/dist/client.d.ts +63 -70
- package/dist/client.d.ts.map +1 -1
- package/dist/constants.d.ts +23 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/helpers/api_info.d.ts +25 -0
- package/dist/helpers/api_info.d.ts.map +1 -0
- package/dist/helpers/data.d.ts +8 -0
- package/dist/helpers/data.d.ts.map +1 -0
- package/dist/{utils.d.ts → helpers/init_helpers.d.ts} +6 -18
- package/dist/helpers/init_helpers.d.ts.map +1 -0
- package/dist/helpers/spaces.d.ts +7 -0
- package/dist/helpers/spaces.d.ts.map +1 -0
- package/dist/index.d.ts +8 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1628 -1398
- 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 +153 -49
- 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 +4 -0
- package/dist/utils/duplicate.d.ts.map +1 -0
- package/dist/utils/handle_blob.d.ts +4 -0
- package/dist/utils/handle_blob.d.ts.map +1 -0
- package/dist/utils/post_data.d.ts +4 -0
- package/dist/utils/post_data.d.ts.map +1 -0
- package/dist/utils/predict.d.ts +4 -0
- package/dist/utils/predict.d.ts.map +1 -0
- package/dist/utils/stream.d.ts +8 -0
- package/dist/utils/stream.d.ts.map +1 -0
- package/dist/utils/submit.d.ts +4 -0
- package/dist/utils/submit.d.ts.map +1 -0
- package/dist/utils/upload_files.d.ts +4 -0
- package/dist/utils/upload_files.d.ts.map +1 -0
- package/dist/utils/view_api.d.ts +3 -0
- package/dist/utils/view_api.d.ts.map +1 -0
- package/dist/{wrapper-6f348d45.js → wrapper-CviSselG.js} +259 -17
- package/package.json +10 -3
- package/src/client.ts +314 -1691
- package/src/constants.ts +27 -0
- package/src/globals.d.ts +2 -21
- package/src/helpers/api_info.ts +300 -0
- package/src/helpers/data.ts +133 -0
- package/src/helpers/init_helpers.ts +130 -0
- package/src/helpers/spaces.ts +197 -0
- package/src/index.ts +16 -10
- 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 +201 -59
- package/src/upload.ts +19 -15
- package/src/utils/duplicate.ts +104 -0
- package/src/utils/handle_blob.ts +47 -0
- package/src/utils/post_data.ts +37 -0
- package/src/utils/predict.ts +56 -0
- package/src/utils/stream.ts +175 -0
- package/src/utils/submit.ts +697 -0
- package/src/utils/upload_files.ts +51 -0
- package/src/utils/view_api.ts +67 -0
- package/src/vite-env.d.ts +1 -0
- package/tsconfig.json +15 -2
- package/vite.config.js +11 -17
- package/dist/utils.d.ts.map +0 -1
- package/src/client.node-test.ts +0 -172
- package/src/utils.ts +0 -314
@@ -0,0 +1,197 @@
|
|
1
|
+
import {
|
2
|
+
RUNTIME_URL,
|
3
|
+
SLEEPTIME_URL,
|
4
|
+
SPACE_STATUS_ERROR_MSG
|
5
|
+
} from "../constants";
|
6
|
+
import type { SpaceStatusCallback } from "../types";
|
7
|
+
|
8
|
+
export async function check_space_status(
|
9
|
+
id: string,
|
10
|
+
type: "subdomain" | "space_name",
|
11
|
+
status_callback: SpaceStatusCallback
|
12
|
+
): Promise<void> {
|
13
|
+
let endpoint =
|
14
|
+
type === "subdomain"
|
15
|
+
? `https://huggingface.co/api/spaces/by-subdomain/${id}`
|
16
|
+
: `https://huggingface.co/api/spaces/${id}`;
|
17
|
+
let response;
|
18
|
+
let _status;
|
19
|
+
try {
|
20
|
+
response = await fetch(endpoint);
|
21
|
+
_status = response.status;
|
22
|
+
if (_status !== 200) {
|
23
|
+
throw new Error();
|
24
|
+
}
|
25
|
+
response = await response.json();
|
26
|
+
} catch (e) {
|
27
|
+
status_callback({
|
28
|
+
status: "error",
|
29
|
+
load_status: "error",
|
30
|
+
message: SPACE_STATUS_ERROR_MSG,
|
31
|
+
detail: "NOT_FOUND"
|
32
|
+
});
|
33
|
+
return;
|
34
|
+
}
|
35
|
+
|
36
|
+
if (!response || _status !== 200) return;
|
37
|
+
const {
|
38
|
+
runtime: { stage },
|
39
|
+
id: space_name
|
40
|
+
} = response;
|
41
|
+
|
42
|
+
switch (stage) {
|
43
|
+
case "STOPPED":
|
44
|
+
case "SLEEPING":
|
45
|
+
status_callback({
|
46
|
+
status: "sleeping",
|
47
|
+
load_status: "pending",
|
48
|
+
message: "Space is asleep. Waking it up...",
|
49
|
+
detail: stage
|
50
|
+
});
|
51
|
+
|
52
|
+
setTimeout(() => {
|
53
|
+
check_space_status(id, type, status_callback);
|
54
|
+
}, 1000); // poll for status
|
55
|
+
break;
|
56
|
+
case "PAUSED":
|
57
|
+
status_callback({
|
58
|
+
status: "paused",
|
59
|
+
load_status: "error",
|
60
|
+
message:
|
61
|
+
"This space has been paused by the author. If you would like to try this demo, consider duplicating the space.",
|
62
|
+
detail: stage,
|
63
|
+
discussions_enabled: await discussions_enabled(space_name)
|
64
|
+
});
|
65
|
+
break;
|
66
|
+
case "RUNNING":
|
67
|
+
case "RUNNING_BUILDING":
|
68
|
+
status_callback({
|
69
|
+
status: "running",
|
70
|
+
load_status: "complete",
|
71
|
+
message: "",
|
72
|
+
detail: stage
|
73
|
+
});
|
74
|
+
break;
|
75
|
+
case "BUILDING":
|
76
|
+
status_callback({
|
77
|
+
status: "building",
|
78
|
+
load_status: "pending",
|
79
|
+
message: "Space is building...",
|
80
|
+
detail: stage
|
81
|
+
});
|
82
|
+
|
83
|
+
setTimeout(() => {
|
84
|
+
check_space_status(id, type, status_callback);
|
85
|
+
}, 1000);
|
86
|
+
break;
|
87
|
+
default:
|
88
|
+
status_callback({
|
89
|
+
status: "space_error",
|
90
|
+
load_status: "error",
|
91
|
+
message: "This space is experiencing an issue.",
|
92
|
+
detail: stage,
|
93
|
+
discussions_enabled: await discussions_enabled(space_name)
|
94
|
+
});
|
95
|
+
break;
|
96
|
+
}
|
97
|
+
}
|
98
|
+
|
99
|
+
const RE_DISABLED_DISCUSSION =
|
100
|
+
/^(?=[^]*\b[dD]iscussions{0,1}\b)(?=[^]*\b[dD]isabled\b)[^]*$/;
|
101
|
+
export async function discussions_enabled(space_id: string): Promise<boolean> {
|
102
|
+
try {
|
103
|
+
const r = await fetch(
|
104
|
+
`https://huggingface.co/api/spaces/${space_id}/discussions`,
|
105
|
+
{
|
106
|
+
method: "HEAD"
|
107
|
+
}
|
108
|
+
);
|
109
|
+
const error = r.headers.get("x-error-message");
|
110
|
+
|
111
|
+
if (error && RE_DISABLED_DISCUSSION.test(error)) return false;
|
112
|
+
return true;
|
113
|
+
} catch (e) {
|
114
|
+
return false;
|
115
|
+
}
|
116
|
+
}
|
117
|
+
|
118
|
+
export async function get_space_hardware(
|
119
|
+
space_id: string,
|
120
|
+
hf_token?: `hf_${string}` | undefined
|
121
|
+
): Promise<(typeof hardware_types)[number]> {
|
122
|
+
const headers: { Authorization?: string } = {};
|
123
|
+
if (hf_token) {
|
124
|
+
headers.Authorization = `Bearer ${hf_token}`;
|
125
|
+
}
|
126
|
+
|
127
|
+
try {
|
128
|
+
const res = await fetch(
|
129
|
+
`https://huggingface.co/api/spaces/${space_id}/${RUNTIME_URL}`,
|
130
|
+
{ headers }
|
131
|
+
);
|
132
|
+
|
133
|
+
if (res.status !== 200)
|
134
|
+
throw new Error("Space hardware could not be obtained.");
|
135
|
+
|
136
|
+
const { hardware } = await res.json();
|
137
|
+
|
138
|
+
return hardware.current;
|
139
|
+
} catch (e: any) {
|
140
|
+
throw new Error(e.message);
|
141
|
+
}
|
142
|
+
}
|
143
|
+
|
144
|
+
export async function set_space_timeout(
|
145
|
+
space_id: string,
|
146
|
+
timeout: number,
|
147
|
+
hf_token?: `hf_${string}`
|
148
|
+
): Promise<any> {
|
149
|
+
const headers: { Authorization?: string } = {};
|
150
|
+
if (hf_token) {
|
151
|
+
headers.Authorization = `Bearer ${hf_token}`;
|
152
|
+
}
|
153
|
+
|
154
|
+
const body: {
|
155
|
+
seconds?: number;
|
156
|
+
} = {
|
157
|
+
seconds: timeout
|
158
|
+
};
|
159
|
+
|
160
|
+
try {
|
161
|
+
const res = await fetch(
|
162
|
+
`https://huggingface.co/api/spaces/${space_id}/${SLEEPTIME_URL}`,
|
163
|
+
{
|
164
|
+
method: "POST",
|
165
|
+
headers: { "Content-Type": "application/json", ...headers },
|
166
|
+
body: JSON.stringify(body)
|
167
|
+
}
|
168
|
+
);
|
169
|
+
|
170
|
+
if (res.status !== 200) {
|
171
|
+
throw new Error(
|
172
|
+
"Could not set sleep timeout on duplicated Space. Please visit *ADD HF LINK TO SETTINGS* to set a timeout manually to reduce billing charges."
|
173
|
+
);
|
174
|
+
}
|
175
|
+
|
176
|
+
const response = await res.json();
|
177
|
+
return response;
|
178
|
+
} catch (e: any) {
|
179
|
+
throw new Error(e.message);
|
180
|
+
}
|
181
|
+
}
|
182
|
+
|
183
|
+
export const hardware_types = [
|
184
|
+
"cpu-basic",
|
185
|
+
"cpu-upgrade",
|
186
|
+
"cpu-xl",
|
187
|
+
"t4-small",
|
188
|
+
"t4-medium",
|
189
|
+
"a10g-small",
|
190
|
+
"a10g-large",
|
191
|
+
"a10g-largex2",
|
192
|
+
"a10g-largex4",
|
193
|
+
"a100-large",
|
194
|
+
"zero-a10g",
|
195
|
+
"h100",
|
196
|
+
"h100x8"
|
197
|
+
] as const;
|
package/src/index.ts
CHANGED
@@ -1,11 +1,17 @@
|
|
1
|
-
export {
|
2
|
-
client,
|
3
|
-
post_data,
|
4
|
-
upload_files,
|
5
|
-
duplicate,
|
6
|
-
api_factory
|
7
|
-
} from "./client.js";
|
8
|
-
export type { client_return } from "./client.js";
|
9
|
-
export type { SpaceStatus } from "./types.js";
|
1
|
+
export { Client } from "./client";
|
10
2
|
|
11
|
-
export {
|
3
|
+
export { predict } from "./utils/predict";
|
4
|
+
export { submit } from "./utils/submit";
|
5
|
+
export { upload_files } from "./utils/upload_files";
|
6
|
+
export { FileData, upload, prepare_files } from "./upload";
|
7
|
+
|
8
|
+
export type {
|
9
|
+
SpaceStatus,
|
10
|
+
Status,
|
11
|
+
client_return,
|
12
|
+
UploadResponse
|
13
|
+
} from "./types";
|
14
|
+
|
15
|
+
// todo: remove in @gradio/client v1.0
|
16
|
+
export { client } from "./client";
|
17
|
+
export { duplicate_space as duplicate } from "./client";
|
@@ -0,0 +1,456 @@
|
|
1
|
+
import { QUEUE_FULL_MSG, SPACE_METADATA_ERROR_MSG } from "../constants";
|
2
|
+
import { beforeAll, afterEach, afterAll, it, expect, describe } from "vitest";
|
3
|
+
import {
|
4
|
+
handle_message,
|
5
|
+
get_description,
|
6
|
+
get_type,
|
7
|
+
process_endpoint
|
8
|
+
} from "../helpers/api_info";
|
9
|
+
import { initialise_server } from "./server";
|
10
|
+
|
11
|
+
const server = initialise_server();
|
12
|
+
|
13
|
+
beforeAll(() => server.listen());
|
14
|
+
afterEach(() => server.resetHandlers());
|
15
|
+
afterAll(() => server.close());
|
16
|
+
|
17
|
+
describe("handle_message", () => {
|
18
|
+
it("should return type 'data' when msg is 'send_data'", () => {
|
19
|
+
const data = { msg: "send_data" };
|
20
|
+
const last_status = "pending";
|
21
|
+
const result = handle_message(data, last_status);
|
22
|
+
expect(result).toEqual({ type: "data" });
|
23
|
+
});
|
24
|
+
|
25
|
+
it("should return type 'hash' when msg is 'send_hash'", () => {
|
26
|
+
const data = { msg: "send_hash" };
|
27
|
+
const last_status = "pending";
|
28
|
+
const result = handle_message(data, last_status);
|
29
|
+
expect(result).toEqual({ type: "hash" });
|
30
|
+
});
|
31
|
+
|
32
|
+
it("should return type 'update' with queue full message when msg is 'queue_full'", () => {
|
33
|
+
const data = { msg: "queue_full", code: 500, success: false };
|
34
|
+
const last_status = "pending";
|
35
|
+
const result = handle_message(data, last_status);
|
36
|
+
expect(result).toEqual({
|
37
|
+
type: "update",
|
38
|
+
status: {
|
39
|
+
queue: true,
|
40
|
+
message: QUEUE_FULL_MSG,
|
41
|
+
stage: "error",
|
42
|
+
code: 500,
|
43
|
+
success: false
|
44
|
+
}
|
45
|
+
});
|
46
|
+
});
|
47
|
+
|
48
|
+
it("should return type 'heartbeat' when msg is 'heartbeat'", () => {
|
49
|
+
const data = { msg: "heartbeat" };
|
50
|
+
const last_status = "pending";
|
51
|
+
const result = handle_message(data, last_status);
|
52
|
+
expect(result).toEqual({ type: "heartbeat" });
|
53
|
+
});
|
54
|
+
|
55
|
+
it("should return type 'unexpected_error' with error message when msg is 'unexpected_error'", () => {
|
56
|
+
const data = { msg: "unexpected_error", message: "Something went wrong" };
|
57
|
+
const last_status = "pending";
|
58
|
+
const result = handle_message(data, last_status);
|
59
|
+
expect(result).toEqual({
|
60
|
+
type: "unexpected_error",
|
61
|
+
status: {
|
62
|
+
queue: true,
|
63
|
+
message: "Something went wrong",
|
64
|
+
stage: "error",
|
65
|
+
success: false
|
66
|
+
}
|
67
|
+
});
|
68
|
+
});
|
69
|
+
|
70
|
+
it("should return type 'update' with estimation status when msg is 'estimation'", () => {
|
71
|
+
const data = {
|
72
|
+
msg: "estimation",
|
73
|
+
code: 200,
|
74
|
+
queue_size: 10,
|
75
|
+
rank: 5,
|
76
|
+
rank_eta: 60,
|
77
|
+
success: true
|
78
|
+
};
|
79
|
+
const last_status = "pending";
|
80
|
+
const result = handle_message(data, last_status);
|
81
|
+
expect(result).toEqual({
|
82
|
+
type: "update",
|
83
|
+
status: {
|
84
|
+
queue: true,
|
85
|
+
stage: "pending",
|
86
|
+
code: 200,
|
87
|
+
size: 10,
|
88
|
+
position: 5,
|
89
|
+
eta: 60,
|
90
|
+
success: true
|
91
|
+
}
|
92
|
+
});
|
93
|
+
});
|
94
|
+
|
95
|
+
it("should return type 'update' with progress status when msg is 'progress'", () => {
|
96
|
+
const data = {
|
97
|
+
msg: "progress",
|
98
|
+
code: 200,
|
99
|
+
progress_data: { current: 50, total: 100 },
|
100
|
+
success: true
|
101
|
+
};
|
102
|
+
const last_status = "pending";
|
103
|
+
const result = handle_message(data, last_status);
|
104
|
+
expect(result).toEqual({
|
105
|
+
type: "update",
|
106
|
+
status: {
|
107
|
+
queue: true,
|
108
|
+
stage: "pending",
|
109
|
+
code: 200,
|
110
|
+
progress_data: { current: 50, total: 100 },
|
111
|
+
success: true
|
112
|
+
}
|
113
|
+
});
|
114
|
+
});
|
115
|
+
|
116
|
+
it("should return type 'log' with the provided data when msg is 'log'", () => {
|
117
|
+
const data = { msg: "log", log_data: "Some log message" };
|
118
|
+
const last_status = "pending";
|
119
|
+
const result = handle_message(data, last_status);
|
120
|
+
expect(result).toEqual({
|
121
|
+
type: "log",
|
122
|
+
data: { msg: "log", log_data: "Some log message" }
|
123
|
+
});
|
124
|
+
});
|
125
|
+
|
126
|
+
it("should return type 'generating' with generating status when msg is 'process_generating' and success is true", () => {
|
127
|
+
const data = {
|
128
|
+
msg: "process_generating",
|
129
|
+
success: true,
|
130
|
+
code: 200,
|
131
|
+
progress_data: { current: 50, total: 100 },
|
132
|
+
average_duration: 120,
|
133
|
+
output: { result: "Some result" }
|
134
|
+
};
|
135
|
+
const last_status = "pending";
|
136
|
+
const result = handle_message(data, last_status);
|
137
|
+
expect(result).toEqual({
|
138
|
+
type: "generating",
|
139
|
+
status: {
|
140
|
+
queue: true,
|
141
|
+
message: null,
|
142
|
+
stage: "generating",
|
143
|
+
code: 200,
|
144
|
+
progress_data: { current: 50, total: 100 },
|
145
|
+
eta: 120
|
146
|
+
},
|
147
|
+
data: { result: "Some result" }
|
148
|
+
});
|
149
|
+
});
|
150
|
+
|
151
|
+
it("should return type 'update' with error status when msg is 'process_generating' and success is false", () => {
|
152
|
+
const data = {
|
153
|
+
msg: "process_generating",
|
154
|
+
success: false,
|
155
|
+
code: 500,
|
156
|
+
progress_data: { current: 50, total: 100 },
|
157
|
+
average_duration: 120,
|
158
|
+
output: { error: "Error" }
|
159
|
+
};
|
160
|
+
const last_status = "pending";
|
161
|
+
const result = handle_message(data, last_status);
|
162
|
+
|
163
|
+
expect(result).toEqual({
|
164
|
+
type: "generating",
|
165
|
+
data: null,
|
166
|
+
status: {
|
167
|
+
eta: 120,
|
168
|
+
queue: true,
|
169
|
+
message: "Error",
|
170
|
+
stage: "error",
|
171
|
+
code: 500,
|
172
|
+
progress_data: { current: 50, total: 100 }
|
173
|
+
}
|
174
|
+
});
|
175
|
+
});
|
176
|
+
|
177
|
+
it("should return type 'complete' with success status when msg is 'process_completed' and success is true", () => {
|
178
|
+
const data = {
|
179
|
+
msg: "process_completed",
|
180
|
+
success: true,
|
181
|
+
code: 200,
|
182
|
+
progress_data: { current: 100, total: 100 },
|
183
|
+
output: { result: "Some result" }
|
184
|
+
};
|
185
|
+
const last_status = "pending";
|
186
|
+
const result = handle_message(data, last_status);
|
187
|
+
expect(result).toEqual({
|
188
|
+
type: "complete",
|
189
|
+
status: {
|
190
|
+
queue: true,
|
191
|
+
message: undefined,
|
192
|
+
stage: "complete",
|
193
|
+
code: 200,
|
194
|
+
progress_data: { current: 100, total: 100 }
|
195
|
+
},
|
196
|
+
data: { result: "Some result" }
|
197
|
+
});
|
198
|
+
});
|
199
|
+
|
200
|
+
it("should return type 'update' with error status when msg is 'process_completed' and success is false", () => {
|
201
|
+
const data = {
|
202
|
+
msg: "process_completed",
|
203
|
+
success: false,
|
204
|
+
code: 500,
|
205
|
+
progress_data: { current: 100, total: 100 },
|
206
|
+
output: { error: "Some error message" }
|
207
|
+
};
|
208
|
+
const last_status = "pending";
|
209
|
+
const result = handle_message(data, last_status);
|
210
|
+
expect(result).toEqual({
|
211
|
+
type: "update",
|
212
|
+
status: {
|
213
|
+
queue: true,
|
214
|
+
message: "Some error message",
|
215
|
+
stage: "error",
|
216
|
+
code: 500,
|
217
|
+
success: false
|
218
|
+
}
|
219
|
+
});
|
220
|
+
});
|
221
|
+
|
222
|
+
it("should return type 'update' with pending status when msg is 'process_starts'", () => {
|
223
|
+
const data = {
|
224
|
+
msg: "process_starts",
|
225
|
+
code: 200,
|
226
|
+
rank: 5,
|
227
|
+
success: true,
|
228
|
+
eta: 60
|
229
|
+
};
|
230
|
+
const last_status = "pending";
|
231
|
+
const result = handle_message(data, last_status);
|
232
|
+
expect(result).toEqual({
|
233
|
+
type: "update",
|
234
|
+
status: {
|
235
|
+
queue: true,
|
236
|
+
stage: "pending",
|
237
|
+
code: 200,
|
238
|
+
size: 5,
|
239
|
+
position: 0,
|
240
|
+
success: true,
|
241
|
+
eta: 60
|
242
|
+
}
|
243
|
+
});
|
244
|
+
});
|
245
|
+
|
246
|
+
it("should return type 'none' with error status when msg is unknown", () => {
|
247
|
+
const data = { msg: "unknown" };
|
248
|
+
const last_status = "pending";
|
249
|
+
const result = handle_message(data, last_status);
|
250
|
+
expect(result).toEqual({
|
251
|
+
type: "none",
|
252
|
+
status: { stage: "error", queue: true }
|
253
|
+
});
|
254
|
+
});
|
255
|
+
});
|
256
|
+
|
257
|
+
describe("get_description", () => {
|
258
|
+
it("should return 'array of [file, label] tuples' when serializer is 'GallerySerializable'", () => {
|
259
|
+
const type = { type: "string", description: "param description" };
|
260
|
+
const serializer = "GallerySerializable";
|
261
|
+
const result = get_description(type, serializer);
|
262
|
+
expect(result).toEqual("array of [file, label] tuples");
|
263
|
+
});
|
264
|
+
|
265
|
+
it("should return 'array of strings' when serializer is 'ListStringSerializable'", () => {
|
266
|
+
const type = { type: "string", description: "param description" };
|
267
|
+
const serializer = "ListStringSerializable";
|
268
|
+
const result = get_description(type, serializer);
|
269
|
+
expect(result).toEqual("array of strings");
|
270
|
+
});
|
271
|
+
|
272
|
+
it("should return 'array of files or single file' when serializer is 'FileSerializable'", () => {
|
273
|
+
const type = { type: "string", description: "param description" };
|
274
|
+
const serializer = "FileSerializable";
|
275
|
+
const result = get_description(type, serializer);
|
276
|
+
expect(result).toEqual("array of files or single file");
|
277
|
+
});
|
278
|
+
|
279
|
+
it("should return the type's description when serializer is not 'GallerySerializable', 'ListStringSerializable', or 'FileSerializable'", () => {
|
280
|
+
const type = { type: "string", description: "param description" };
|
281
|
+
const serializer = "SomeOtherSerializer";
|
282
|
+
const result = get_description(type, serializer);
|
283
|
+
expect(result).toEqual(type.description);
|
284
|
+
});
|
285
|
+
});
|
286
|
+
|
287
|
+
describe("get_type", () => {
|
288
|
+
it("should return 'string' when type is 'string'", () => {
|
289
|
+
const type = { type: "string", description: "param description" };
|
290
|
+
const component = "Component";
|
291
|
+
const serializer = "Serializer";
|
292
|
+
const signature_type = "parameter";
|
293
|
+
const result = get_type(type, component, serializer, signature_type);
|
294
|
+
expect(result).toEqual("string");
|
295
|
+
});
|
296
|
+
|
297
|
+
it("should return 'boolean' when type is 'boolean'", () => {
|
298
|
+
const type = { type: "boolean", description: "param description" };
|
299
|
+
const component = "Component";
|
300
|
+
const serializer = "Serializer";
|
301
|
+
const signature_type = "parameter";
|
302
|
+
const result = get_type(type, component, serializer, signature_type);
|
303
|
+
expect(result).toEqual("boolean");
|
304
|
+
});
|
305
|
+
|
306
|
+
it("should return 'number' when type is 'number'", () => {
|
307
|
+
const type = { type: "number", description: "param description" };
|
308
|
+
const component = "Component";
|
309
|
+
const serializer = "Serializer";
|
310
|
+
const signature_type = "parameter";
|
311
|
+
const result = get_type(type, component, serializer, signature_type);
|
312
|
+
expect(result).toEqual("number");
|
313
|
+
});
|
314
|
+
|
315
|
+
it("should return 'any' when serializer is 'JSONSerializable'", () => {
|
316
|
+
const type = { type: "any", description: "param description" };
|
317
|
+
const component = "Component";
|
318
|
+
const serializer = "JSONSerializable";
|
319
|
+
const signature_type = "parameter";
|
320
|
+
const result = get_type(type, component, serializer, signature_type);
|
321
|
+
expect(result).toEqual("any");
|
322
|
+
});
|
323
|
+
|
324
|
+
it("should return 'any' when serializer is 'StringSerializable'", () => {
|
325
|
+
const type = { type: "any", description: "param description" };
|
326
|
+
const component = "Component";
|
327
|
+
const serializer = "StringSerializable";
|
328
|
+
const signature_type = "parameter";
|
329
|
+
const result = get_type(type, component, serializer, signature_type);
|
330
|
+
expect(result).toEqual("any");
|
331
|
+
});
|
332
|
+
|
333
|
+
it("should return 'string[]' when serializer is 'ListStringSerializable'", () => {
|
334
|
+
const type = { type: "any", description: "param description" };
|
335
|
+
const component = "Component";
|
336
|
+
const serializer = "ListStringSerializable";
|
337
|
+
const signature_type = "parameter";
|
338
|
+
const result = get_type(type, component, serializer, signature_type);
|
339
|
+
expect(result).toEqual("string[]");
|
340
|
+
});
|
341
|
+
|
342
|
+
it("should return 'Blob | File | Buffer' when component is 'Image' and signature_type is 'parameter'", () => {
|
343
|
+
const type = { type: "any", description: "param description" };
|
344
|
+
const component = "Image";
|
345
|
+
const serializer = "Serializer";
|
346
|
+
const signature_type = "parameter";
|
347
|
+
const result = get_type(type, component, serializer, signature_type);
|
348
|
+
expect(result).toEqual("Blob | File | Buffer");
|
349
|
+
});
|
350
|
+
|
351
|
+
it("should return 'string' when component is 'Image' and signature_type is 'return'", () => {
|
352
|
+
const type = { type: "string", description: "param description" };
|
353
|
+
const component = "Image";
|
354
|
+
const serializer = "Serializer";
|
355
|
+
const signature_type = "return";
|
356
|
+
const result = get_type(type, component, serializer, signature_type);
|
357
|
+
expect(result).toEqual("string");
|
358
|
+
});
|
359
|
+
|
360
|
+
it("should return '(Blob | File | Buffer)[]' when serializer is 'FileSerializable' and type is an array and signature_type is 'parameter'", () => {
|
361
|
+
const type = { type: "array", description: "param description" };
|
362
|
+
const component = "Component";
|
363
|
+
const serializer = "FileSerializable";
|
364
|
+
const signature_type = "parameter";
|
365
|
+
const result = get_type(type, component, serializer, signature_type);
|
366
|
+
expect(result).toEqual("(Blob | File | Buffer)[]");
|
367
|
+
});
|
368
|
+
|
369
|
+
it("should return 'Blob | File | Buffer' when serializer is 'FileSerializable' and type is not an array and signature_type is 'return'", () => {
|
370
|
+
const type = { type: "any", description: "param description" };
|
371
|
+
const component = "Component";
|
372
|
+
const serializer = "FileSerializable";
|
373
|
+
const signature_type = "return";
|
374
|
+
const result = get_type(type, component, serializer, signature_type);
|
375
|
+
expect(result).toEqual(
|
376
|
+
"{ name: string; data: string; size?: number; is_file?: boolean; orig_name?: string}"
|
377
|
+
);
|
378
|
+
});
|
379
|
+
|
380
|
+
it("should return a FileData object when serializer is 'FileSerializable' and type is not an array and signature_type is 'return'", () => {
|
381
|
+
const type = { type: "any", description: "param description" };
|
382
|
+
const component = "Component";
|
383
|
+
const serializer = "FileSerializable";
|
384
|
+
const signature_type = "return";
|
385
|
+
const result = get_type(type, component, serializer, signature_type);
|
386
|
+
expect(result).toEqual(
|
387
|
+
"{ name: string; data: string; size?: number; is_file?: boolean; orig_name?: string}"
|
388
|
+
);
|
389
|
+
});
|
390
|
+
|
391
|
+
it("should return '[(Blob | File | Buffer), (string | null)][]' when serializer is 'GallerySerializable' and signature_type is 'parameter'", () => {
|
392
|
+
const type = { type: "any", description: "param description" };
|
393
|
+
const component = "Component";
|
394
|
+
const serializer = "GallerySerializable";
|
395
|
+
const signature_type = "parameter";
|
396
|
+
const result = get_type(type, component, serializer, signature_type);
|
397
|
+
expect(result).toEqual("[(Blob | File | Buffer), (string | null)][]");
|
398
|
+
});
|
399
|
+
|
400
|
+
it("should return a FileData object when serializer is 'GallerySerializable' and signature_type is 'return'", () => {
|
401
|
+
const type = { type: "any", description: "param description" };
|
402
|
+
const component = "Component";
|
403
|
+
const serializer = "GallerySerializable";
|
404
|
+
const signature_type = "return";
|
405
|
+
const result = get_type(type, component, serializer, signature_type);
|
406
|
+
expect(result).toEqual(
|
407
|
+
"[{ name: string; data: string; size?: number; is_file?: boolean; orig_name?: string}, (string | null))][]"
|
408
|
+
);
|
409
|
+
});
|
410
|
+
});
|
411
|
+
|
412
|
+
describe("process_endpoint", () => {
|
413
|
+
it("should return space_id, host, ws_protocol, and http_protocol when app_reference is a valid space name", async () => {
|
414
|
+
const app_reference = "hmb/hello_world";
|
415
|
+
const host = "hmb-hello-world.hf.space";
|
416
|
+
|
417
|
+
const hf_token = "hf_token";
|
418
|
+
const expected = {
|
419
|
+
space_id: app_reference,
|
420
|
+
host,
|
421
|
+
ws_protocol: "wss",
|
422
|
+
http_protocol: "https:"
|
423
|
+
};
|
424
|
+
|
425
|
+
const result = await process_endpoint(app_reference, hf_token);
|
426
|
+
expect(result).toEqual(expected);
|
427
|
+
});
|
428
|
+
|
429
|
+
it("should throw an error when fetching space metadata fails", async () => {
|
430
|
+
const app_reference = "hmb/bye_world";
|
431
|
+
const hf_token = "hf_token";
|
432
|
+
|
433
|
+
try {
|
434
|
+
await process_endpoint(app_reference, hf_token);
|
435
|
+
} catch (error) {
|
436
|
+
expect(error.message).toEqual(
|
437
|
+
SPACE_METADATA_ERROR_MSG + "Unexpected end of JSON input"
|
438
|
+
);
|
439
|
+
}
|
440
|
+
});
|
441
|
+
|
442
|
+
it("should return the correct data when app_reference is a valid space domain", async () => {
|
443
|
+
const app_reference = "hmb/hello_world";
|
444
|
+
const host = "hmb-hello-world.hf.space";
|
445
|
+
|
446
|
+
const expected = {
|
447
|
+
space_id: app_reference,
|
448
|
+
host,
|
449
|
+
ws_protocol: "wss",
|
450
|
+
http_protocol: "https:"
|
451
|
+
};
|
452
|
+
|
453
|
+
const result = await process_endpoint("hmb/hello_world");
|
454
|
+
expect(result).toEqual(expected);
|
455
|
+
});
|
456
|
+
});
|