gradio

Форк
0
/
ApiDocs.svelte 
363 строки · 8.6 Кб
1
<script lang="ts">
2
	/* eslint-disable */
3
	import { onMount, createEventDispatcher } from "svelte";
4
	import type { ComponentMeta, Dependency } from "../types";
5
	import { post_data } from "@gradio/client";
6
	import NoApi from "./NoApi.svelte";
7
	import type { client } from "@gradio/client";
8

9
	import { represent_value } from "./utils";
10

11
	import ApiBanner from "./ApiBanner.svelte";
12
	import ResponseObject from "./ResponseObject.svelte";
13
	import InstallSnippet from "./InstallSnippet.svelte";
14
	import CodeSnippets from "./CodeSnippets.svelte";
15

16
	import python from "./img/python.svg";
17
	import javascript from "./img/javascript.svg";
18

19
	export let instance_map: {
20
		[id: number]: ComponentMeta;
21
	};
22
	export let dependencies: Dependency[];
23
	export let root: string;
24
	export let app: Awaited<ReturnType<typeof client>>;
25
	export let space_id: string | null;
26

27
	const js_docs =
28
		"https://www.gradio.app/guides/getting-started-with-the-js-client";
29
	const py_docs =
30
		"https://www.gradio.app/guides/getting-started-with-the-python-client";
31
	const spaces_docs_suffix = "#connecting-to-a-hugging-face-space";
32

33
	let api_count = dependencies.filter(
34
		(dependency) => dependency.show_api
35
	).length;
36

37
	if (root === "") {
38
		root = location.protocol + "//" + location.host + location.pathname;
39
	}
40
	if (!root.endsWith("/")) {
41
		root += "/";
42
	}
43

44
	let current_language: "python" | "javascript" = "python";
45

46
	const langs = [
47
		["python", python],
48
		["javascript", javascript]
49
	] as const;
50

51
	let is_running = false;
52

53
	let dependency_inputs = dependencies.map((dependency) =>
54
		dependency.inputs.map((_id) => {
55
			let default_data = instance_map[_id].documentation?.example_data;
56
			if (default_data === undefined) {
57
				default_data = "";
58
			} else if (typeof default_data === "object") {
59
				default_data = JSON.stringify(default_data);
60
			}
61
			return default_data;
62
		})
63
	);
64

65
	let dependency_outputs: any[][] = dependencies.map(
66
		(dependency) => new Array(dependency.outputs.length)
67
	);
68

69
	let dependency_failures: boolean[][] = dependencies.map((dependency) =>
70
		new Array(dependency.inputs.length).fill(false)
71
	);
72

73
	async function get_info(): Promise<{
74
		named_endpoints: any;
75
		unnamed_endpoints: any;
76
	}> {
77
		let response = await fetch(root + "info");
78
		let data = await response.json();
79
		return data;
80
	}
81
	async function get_js_info(): Promise<Record<string, any>> {
82
		let js_api_info = await app.view_api();
83
		return js_api_info;
84
	}
85

86
	let info: {
87
		named_endpoints: any;
88
		unnamed_endpoints: any;
89
	};
90

91
	let js_info: Record<string, any>;
92

93
	get_info().then((data) => {
94
		info = data;
95
	});
96

97
	get_js_info().then((js_api_info) => {
98
		js_info = js_api_info;
99
	});
100

101
	async function run(index: number): Promise<void> {
102
		is_running = true;
103
		let dependency = dependencies[index];
104
		let attempted_component_index = 0;
105
		try {
106
			var inputs = dependency_inputs[index].map((input_val, i) => {
107
				attempted_component_index = i;
108
				let component = instance_map[dependency.inputs[i]];
109
				// @ts-ignore
110
				input_val = represent_value(
111
					input_val,
112
					component.documentation?.type?.input_payload ||
113
						component.documentation?.type?.payload
114
				);
115
				dependency_failures[index][attempted_component_index] = false;
116
				return input_val;
117
			});
118
		} catch (err) {
119
			dependency_failures[index][attempted_component_index] = true;
120
			is_running = false;
121
			return;
122
		}
123
		let [response, status_code] = await post_data(
124
			`${root}run/${dependency.api_name}`,
125
			{
126
				data: inputs
127
			}
128
		);
129
		is_running = false;
130
		if (status_code == 200) {
131
			dependency_outputs[index] = response.data.map(
132
				(output_val: any, i: number) => {
133
					let component = instance_map[dependency.outputs[i]];
134

135
					return represent_value(
136
						output_val,
137
						component.documentation?.type?.response_object ||
138
							component.documentation?.type?.payload,
139
						"js"
140
					);
141
				}
142
			);
143
		} else {
144
			dependency_failures[index] = new Array(
145
				dependency_failures[index].length
146
			).fill(true);
147
		}
148
	}
149

150
	onMount(() => {
151
		document.body.style.overflow = "hidden";
152
		if ("parentIFrame" in window) {
153
			window.parentIFrame?.scrollTo(0, 0);
154
		}
155
		return () => {
156
			document.body.style.overflow = "auto";
157
		};
158
	});
159
</script>
160

161
{#if info}
162
	{#if api_count}
163
		<div class="banner-wrap">
164
			<ApiBanner on:close root={space_id || root} {api_count} />
165
		</div>
166
		<div class="docs-wrap">
167
			<div class="client-doc">
168
				<p>
169
					Use the <code class="library">gradio_client</code>
170
					Python library (<a href={py_docs} target="_blank">docs</a>) or the
171
					<code class="library">@gradio/client</code>
172
					Javascript package (<a href={js_docs} target="_blank">docs</a>) to
173
					query the app via API.
174
				</p>
175
			</div>
176
			<div class="endpoint">
177
				<div class="snippets">
178
					{#each langs as [language, img]}
179
						<li
180
							class="snippet
181
							{current_language === language ? 'current-lang' : 'inactive-lang'}"
182
							on:click={() => (current_language = language)}
183
						>
184
							<img src={img} alt="" />
185
							{language}
186
						</li>
187
					{/each}
188
				</div>
189

190
				<p class="padded">
191
					1. Install the client if you don't already have it installed.
192
				</p>
193

194
				<InstallSnippet {current_language} />
195

196
				<p class="padded">
197
					2. Find the API endpoint below corresponding to your desired function
198
					in the app. Copy the code snippet, replacing the placeholder values
199
					with your own input data.
200
					{#if space_id}If this is a private Space, you may need to pass your
201
						Hugging Face token as well (<a
202
							href={(current_language == "python" ? py_docs : js_docs) +
203
								spaces_docs_suffix}
204
							class="underline"
205
							target="_blank">read more</a
206
						>).{/if} Run the code, that's it!
207
				</p>
208

209
				{#each dependencies as dependency, dependency_index}
210
					{#if dependency.show_api}
211
						<div class="endpoint-container">
212
							<CodeSnippets
213
								named={true}
214
								endpoint_parameters={info.named_endpoints[
215
									"/" + dependency.api_name
216
								].parameters}
217
								js_parameters={js_info.named_endpoints[
218
									"/" + dependency.api_name
219
								].parameters}
220
								{dependency}
221
								{dependency_index}
222
								{current_language}
223
								root={space_id || root}
224
								{dependency_failures}
225
							/>
226

227
							<!-- <TryButton
228
							named={true}
229
							{dependency_index}
230
							{run}
231
						/> -->
232

233
							<ResponseObject
234
								endpoint_returns={info.named_endpoints[
235
									"/" + dependency.api_name
236
								].returns}
237
								js_returns={js_info.named_endpoints["/" + dependency.api_name]
238
									.returns}
239
								{is_running}
240
								{current_language}
241
							/>
242
						</div>
243
					{/if}
244
				{/each}
245
			</div>
246
		</div>
247
	{:else}
248
		<NoApi {root} on:close />
249
	{/if}
250
{/if}
251

252
<style>
253
	.banner-wrap {
254
		position: relative;
255
		border-bottom: 1px solid var(--border-color-primary);
256
		padding: var(--size-4) var(--size-6);
257
		font-size: var(--text-md);
258
	}
259

260
	@media (--screen-md) {
261
		.banner-wrap {
262
			font-size: var(--text-xl);
263
		}
264
	}
265

266
	.docs-wrap {
267
		display: flex;
268
		flex-direction: column;
269
		gap: var(--spacing-xxl);
270
	}
271

272
	.endpoint {
273
		border-radius: var(--radius-md);
274
		background: var(--background-fill-primary);
275
		padding: var(--size-6);
276
		padding-top: var(--size-1);
277
		font-size: var(--text-md);
278
	}
279

280
	.client-doc {
281
		padding-top: var(--size-6);
282
		padding-right: var(--size-6);
283
		padding-left: var(--size-6);
284
		font-size: var(--text-md);
285
	}
286

287
	.library {
288
		border: 1px solid var(--border-color-accent);
289
		border-radius: var(--radius-sm);
290
		background: var(--color-accent-soft);
291
		padding: var(--size-1);
292
		color: var(--color-accent);
293
		font-size: var(--text-md);
294
	}
295

296
	.snippets {
297
		display: flex;
298
		align-items: center;
299
		margin-bottom: var(--size-4);
300
	}
301

302
	.snippets > * + * {
303
		margin-left: var(--size-2);
304
	}
305

306
	.snippet {
307
		display: flex;
308
		align-items: center;
309
		border: 1px solid var(--border-color-primary);
310

311
		border-radius: var(--radius-md);
312
		padding: var(--size-1) var(--size-1-5);
313
		color: var(--body-text-color-subdued);
314
		color: var(--body-text-color);
315
		line-height: 1;
316
		user-select: none;
317
		text-transform: capitalize;
318
	}
319

320
	.current-lang {
321
		border: 1px solid var(--body-text-color-subdued);
322
		color: var(--body-text-color);
323
	}
324

325
	.inactive-lang {
326
		cursor: pointer;
327
		color: var(--body-text-color-subdued);
328
	}
329

330
	.inactive-lang:hover,
331
	.inactive-lang:focus {
332
		box-shadow: var(--shadow-drop);
333
		color: var(--body-text-color);
334
	}
335

336
	.snippet img {
337
		margin-right: var(--size-1-5);
338
		width: var(--size-3);
339
	}
340

341
	.header {
342
		margin-top: var(--size-6);
343
		font-size: var(--text-xl);
344
	}
345

346
	.endpoint-container {
347
		margin-top: var(--size-3);
348
		margin-bottom: var(--size-3);
349
		border: 1px solid var(--border-color-primary);
350
		border-radius: var(--radius-xl);
351
		padding: var(--size-3);
352
		padding-top: 0;
353
	}
354

355
	a {
356
		text-decoration: underline;
357
	}
358

359
	p.padded {
360
		padding: 15px 0px;
361
		font-size: var(--text-lg);
362
	}
363
</style>
364

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.