API Docs Fixes (#3287)

* fix audio api docs

* fix type and desc for every component

* fix indentation

* fix chatbot example

* fix checkbox example

* fix types in run and code snippets

* fix dataframe dataset file video

* some syntax highlighting

* changelog

* formatting

* type fixes

* clarify wording for audio, video, file

* better indentation

* show actual url in description

* add copy buttons

* formatting and types
This commit is contained in:
Ali Abdalla 2023-02-24 13:13:13 -08:00 committed by GitHub
parent be4986de8a
commit e54042b43b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 350 additions and 129 deletions

View File

@ -31,6 +31,7 @@ By [@freddyaboulton](https://github.com/freddyaboulton) in [PR 3297](https://git
## Bug Fixes:
- Ensure `mirror_webcam` is always respected by [@pngwn](https://github.com/pngwn) in [PR 3245](https://github.com/gradio-app/gradio/pull/3245)
- Fix issue where updated markdown links were not being opened in a new tab by [@gante](https://github.com/gante) in [PR 3236](https://github.com/gradio-app/gradio/pull/3236)
- API Docs Fixes by [@aliabd](https://github.com/aliabd) in [PR 3287](https://github.com/gradio-app/gradio/pull/3287)
- Added a timeout to queue messages as some demos were experiencing infinitely growing queues from active jobs waiting forever for clients to respond by [@freddyaboulton](https://github.com/freddyaboulton) in [PR 3196](https://github.com/gradio-app/gradio/pull/3196)
- Fixes the height of rendered LaTeX images so that they match the height of surrounding text by [@abidlabs](https://github.com/abidlabs) in [PR 3258](https://github.com/gradio-app/gradio/pull/3258) and in [PR 3276](https://github.com/gradio-app/gradio/pull/3276)
- Fix bug where matplotlib images where always too small on the front end by [@freddyaboulton](https://github.com/freddyaboulton) in [PR 3274](https://github.com/gradio-app/gradio/pull/3274)

View File

@ -58,7 +58,11 @@
var inputs = dependency_inputs[index].map((input_val, i) => {
attempted_component_index = i;
let component = instance_map[dependency.inputs[i]];
input_val = represent_value(input_val, component.documentation?.type);
input_val = represent_value(
input_val,
component.documentation?.type?.input_payload ||
component.documentation?.type?.payload
);
dependency_failures[index][attempted_component_index] = false;
return input_val;
});
@ -81,7 +85,8 @@
return represent_value(
output_val,
component.documentation?.type,
component.documentation?.type?.response_object ||
component.documentation?.type?.payload,
"js"
);
}
@ -130,6 +135,7 @@
{dependency_index}
{is_running}
{dependency_outputs}
{root}
/>
<CodeSnippets
{instance_map}

View File

@ -1,5 +1,6 @@
<script lang="ts">
import type { ComponentMeta, Dependency } from "../components/types";
import CopyButton from "./CopyButton.svelte";
import { represent_value } from "./utils";
import python from "./img/python.svg";
@ -20,6 +21,9 @@
["python", python],
["javascript", javascript]
] as const;
let python_code: HTMLElement;
let js_code: HTMLElement;
</script>
<h4>
@ -45,42 +49,66 @@
</div>
<code>
{#if current_language === "python"}
<pre>import requests
<div class="copy">
<CopyButton code={python_code?.innerText} />
</div>
<div bind:this={python_code}>
<pre>import requests
response = requests.post("{root + "run/" + dependency.api_name}", json=&lbrace;
response = requests.post(<span class="token string"
>"{root + "run/" + dependency.api_name}"</span
>, json=&lbrace;
"data": [{#each dependency_inputs[dependency_index] as component_value, component_index}<br
/><!--
--> {represent_value(
component_value,
instance_map[dependencies[dependency_index].inputs[component_index]]
.documentation?.type,
"py"
)},{/each}
/><!--
--> <span class="token string"
>{represent_value(
component_value,
instance_map[
dependencies[dependency_index].inputs[component_index]
].documentation?.type?.input_payload ||
instance_map[
dependencies[dependency_index].inputs[component_index]
].documentation?.type?.payload,
"py"
)}</span
>,{/each}
]
&rbrace;).json()
data = response["data"]</pre>
data = response[<span class="token string">"data"</span>]</pre>
</div>
{:else if current_language === "javascript"}
<pre>const response = await fetch("{root +
"run/" +
dependency.api_name}", &lbrace;
<div class="copy">
<CopyButton code={js_code?.innerText} />
</div>
<div bind:this={js_code}>
<pre>const response = await fetch(<span class="token string"
>"{root + "run/" + dependency.api_name}"</span
>, &lbrace;
method: "POST",
headers: &lbrace; "Content-Type": "application/json" &rbrace;,
body: JSON.stringify(&lbrace;
data: [{#each dependency_inputs[dependency_index] as component_value, component_index}<br
/><!--
--> {represent_value(
component_value,
instance_map[dependencies[dependency_index].inputs[component_index]]
.documentation?.type,
"js"
)},{/each}
/><!--
--> <span class="token string"
>{represent_value(
component_value,
instance_map[
dependencies[dependency_index].inputs[component_index]
].documentation?.type?.input_payload ||
instance_map[
dependencies[dependency_index].inputs[component_index]
].documentation?.type?.payload,
"js"
)}</span
>,{/each}
]
&rbrace;)
&rbrace;);
const data = await data.json();
const data = await <span class="token string">response</span>.json();
</pre>
</div>
{:else if current_language === "gradio client"}
<pre class="client">Hello World</pre>
{/if}
@ -163,4 +191,20 @@ const data = await data.json();
white-space: pre-wrap;
overflow-wrap: break-word;
}
.token.string {
display: contents;
color: var(--color-accent-base);
}
code {
position: relative;
}
.copy {
position: absolute;
top: 0;
right: 0;
margin: 1rem;
}
</style>

View File

@ -0,0 +1,17 @@
<script lang="ts">
import { Button } from "@gradio/button";
export let code: string;
let copy_text = "copy";
function copy() {
navigator.clipboard.writeText(code);
copy_text = "copied!";
setTimeout(() => {
copy_text = "copy";
}, 1500);
}
</script>
<Button size="sm" on:click={copy}>
{copy_text}
</Button>

View File

@ -25,34 +25,37 @@
<div class="payload-details">
&#123;
<br />
&nbsp;&nbsp;"data": [
<div class="first-level">"data": [</div>
<br />
{#each dependency.inputs as component_id, component_index}
&nbsp;&nbsp;&nbsp;&nbsp;
<input
class=""
type="text"
bind:value={dependency_inputs[dependency_index][component_index]}
/>
{#if dependency_failures[dependency_index][component_index]}
<span class="error">ERROR</span>
{/if}
<span class="type">
: {instance_map[component_id].documentation?.type},
</span>
<span class="desc">
// represents {instance_map[component_id].documentation?.description} of
{format_label(instance_map[component_id].props.label)}
<div class="second-level">
<input
class=""
type="text"
bind:value={dependency_inputs[dependency_index][component_index]}
/>
{#if dependency_failures[dependency_index][component_index]}
<span class="error">ERROR</span>
{/if}
<span class="name">
{instance_map[component_id].props.name}
<span class="type">
: {instance_map[component_id].documentation?.type?.input_payload ||
instance_map[component_id].documentation?.type?.payload},
</span>
component
</span>
<span class="desc">
// represents {instance_map[component_id].documentation?.description
?.input_payload ||
instance_map[component_id].documentation?.description?.payload} of
{format_label(instance_map[component_id].props.label)}
<span class="name">
{instance_map[component_id].props.name}
</span>
component
</span>
</div>
<br />
{/each}
&nbsp;&nbsp;]
<br />
<div class="second-level">]</div>
&#125;
</div>
@ -155,4 +158,12 @@
.name {
text-transform: capitalize;
}
.first-level {
margin-left: 2rem;
}
.second-level {
margin-left: 6rem;
}
</style>

View File

@ -11,6 +11,13 @@
export let dependency_outputs: any[][];
export let is_running: boolean;
export let root: string;
const format_url = (desc: string | undefined, data: string | undefined) =>
desc
?.replace("{ROOT}", root)
?.replace("{name}", data ? JSON.parse(`${data}`)?.name : "{name}");
</script>
<h4>
@ -23,38 +30,46 @@
<div class:hide={is_running}>
&#123;
<br />
&nbsp;&nbsp;"data": [
<div class="first-level">"data": [</div>
<br />
{#each dependency.outputs as component_id, component_index}
&nbsp;&nbsp;&nbsp;{#if dependency_outputs[dependency_index][component_index] !== undefined}
<input
disabled
type="text"
bind:value={dependency_outputs[dependency_index][component_index]}
/>
:
{/if}
<span class="type">
{instance_map[component_id].documentation?.type},
</span>
<span class="desc">
// represents {instance_map[component_id].documentation?.description} of
{((label) => {
return label ? "'" + label + "'" : "the";
})(instance_map[component_id].props.label)}
<span class="name capitalize">
{instance_map[component_id].props.name}
<div class="second-level">
{#if dependency_outputs[dependency_index][component_index] !== undefined}
<input
disabled
type="text"
bind:value={dependency_outputs[dependency_index][component_index]}
/>
:
{/if}
<span class="type">
{instance_map[component_id].documentation?.type?.response_object ||
instance_map[component_id].documentation?.type?.payload},
</span>
component
</span>
<span class="desc">
// represents {format_url(
instance_map[component_id].documentation?.description
?.response_object ||
instance_map[component_id].documentation?.description?.payload,
dependency_outputs[dependency_index][component_index]
)} of
{((label) => {
return label ? "'" + label + "'" : "the";
})(instance_map[component_id].props.label)}
<span class="name capitalize">
{instance_map[component_id].props.name}
</span>
component
</span>
</div>
<br />
{/each}
&nbsp;&nbsp;],
<br />
&nbsp;&nbsp;"duration": (float)
<span class="desc">// number of seconds to run function call</span>
<div class="second-level">],</div>
<br />
<div class="first-level">
"duration": (float)
<span class="desc">// number of seconds to run function call</span>
</div>
&#125;
</div>
{#if is_running}
@ -146,4 +161,12 @@
.hide {
display: none;
}
.first-level {
margin-left: 2rem;
}
.second-level {
margin-left: 6rem;
}
</style>

View File

@ -2,8 +2,15 @@ export { default as Component } from "./Audio.svelte";
export const modes = ["static", "dynamic"];
export const document = () => ({
type: "{ name: string; data: string }",
description: "audio data as base64 string",
type: {
input_payload: "{ name: string; data: string }",
response_object: "{ name: string; data: string, is_file: boolean }"
},
description: {
input_payload: "audio data as object with filename and base64 string",
response_object:
"object that includes path to audio file. The URL: {ROOT}file={name} contains the data"
},
example_data: {
name: "audio.wav",
data: "data:audio/wav;base64,UklGRiQAAABXQVZFZm10IBAAAAABAAEARKwAAIhYAQACABAAZGF0YQAAAAA="

View File

@ -2,7 +2,11 @@ export { default as Component } from "./Button.svelte";
export const modes = ["static", "dynamic"];
export const document = (config: Record<string, any>) => ({
type: "string",
description: "button label",
type: {
payload: "string"
},
description: {
payload: "button label"
},
example_data: config.value || "Run"
});

View File

@ -2,10 +2,16 @@ export { default as Component } from "./Chatbot.svelte";
export const modes = ["static"];
export const document = (config: Record<string, any>) => ({
type: "Array<[string, string]>",
description: "Represents list of message pairs of chat message.",
example_data: config.value ?? [
["Hi", "Hello"],
["1 + 1", "2"]
]
type: {
payload: "Array<[string, string]>"
},
description: {
payload: "list of message pairs of"
},
example_data: config.value?.length
? config.value
: [
["Hi", "Hello"],
["1 + 1", "2"]
]
});

View File

@ -2,7 +2,11 @@ export { default as Component } from "./Checkbox.svelte";
export const modes = ["static", "dynamic"];
export const document = (config: Record<string, any>) => ({
type: "boolean",
description: "checked status",
example_data: config.value ?? true
type: {
payload: "boolean"
},
description: {
payload: "checked status"
},
example_data: config.value
});

View File

@ -2,7 +2,11 @@ export { default as Component } from "./CheckboxGroup.svelte";
export const modes = ["static", "dynamic"];
export const document = (config: Record<string, any>) => ({
type: "Array<string>",
description: "list of selected choices",
type: {
payload: "Array<string>"
},
description: {
payload: "list of selected choices"
},
example_data: config.choices.length ? [config.choices[0]] : []
});

View File

@ -2,7 +2,11 @@ export { default as Component } from "./ColorPicker.svelte";
export const modes = ["static", "dynamic"];
export const document = (config: Record<string, any>) => ({
type: "string",
description: "hex color code",
type: {
payload: "string"
},
description: {
payload: "hex color code"
},
example_data: config.value ?? "#000000"
});

View File

@ -2,7 +2,11 @@ export { default as Component } from "./DataFrame.svelte";
export const modes = ["static", "dynamic"];
export const document = (config: Record<string, any>) => ({
type: " { data: Array<Array<string | number>>; headers: Array<string> }",
description: "hex color code",
example_data: config.value ?? "#000000"
type: {
payload: "{ data: Array<Array<string | number>>; headers: Array<string> }"
},
description: {
payload: "an object with an array of data and an array of headers"
},
example_data: config.value
});

View File

@ -2,7 +2,11 @@ export { default as Component } from "./Dataset.svelte";
export const modes = ["dynamic"];
export const document = () => ({
type: "number",
description: "index of selected row",
type: {
payload: "number"
},
description: {
payload: "index of selected row"
},
example_data: 0
});

View File

@ -2,7 +2,11 @@ export { default as Component } from "./Dropdown.svelte";
export const modes = ["static", "dynamic"];
export const document = (config: Record<string, any>) => ({
type: "string",
description: "selected choice",
type: {
payload: "string"
},
description: {
payload: "selected choice"
},
example_data: config.choices.length ? config.choices[0] : ""
});

View File

@ -2,8 +2,16 @@ export { default as Component } from "./File.svelte";
export const modes = ["static", "dynamic"];
export const document = (config: Record<string, any>) => ({
type: "{ name: string; data: string }",
description: "file name and base64 data as an object",
type: {
input_payload: "{ name: string; data: string }",
response_object:
"{ orig_name: string; name: string, size: number, data: string, is_file: boolean}"
},
description: {
input_payload: "object with file name and base64 data",
response_object:
"object that includes path to file. The URL: {ROOT}file={name} contains the data"
},
example_data: {
name: "zip.zip",
data: "data:@file/octet-stream;base64,UEsFBgAAAAAAAAAAAAAAAAAAAAAAAA=="

View File

@ -2,6 +2,10 @@ export { default as Component } from "./Gallery.svelte";
export const modes = ["static"];
export const document = (config: Record<string, any>) => ({
type: "Array<{ name: string } | [{ name: string }, string]>",
description: "list of objects with filename and optional caption"
type: {
payload: "Array<{ name: string } | [{ name: string }, string]>"
},
description: {
payload: "list of objects, with filename and optional caption,"
}
});

View File

@ -2,6 +2,10 @@ export { default as Component } from "./HTML.svelte";
export const modes = ["static"];
export const document = (config: Record<string, any>) => ({
type: "string",
description: "HTML output"
type: {
payload: "string"
},
description: {
payload: "HTML output"
}
});

View File

@ -2,6 +2,10 @@ export { default as Component } from "./HighlightedText.svelte";
export const modes = ["static"];
export const document = (config: Record<string, any>) => ({
type: "Array<[string, string | number]>",
description: "list of text spans and corresponding label / value"
type: {
payload: "Array<[string, string | number]>"
},
description: {
payload: "list of text spans and corresponding label / value"
}
});

View File

@ -3,8 +3,12 @@ export { default as ExampleComponent } from "../Dataset/ExampleComponents/Image.
export const modes = ["static", "dynamic"];
export const document = (config: Record<string, any>) => ({
type: "string",
description: "image data as base64 string",
type: {
payload: "string"
},
description: {
payload: "image data as base64 string"
},
example_data:
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAACklEQVR4nGMAAQAABQABDQottAAAAABJRU5ErkJggg=="
});

View File

@ -2,6 +2,10 @@ export { default as Component } from "./Json.svelte";
export const modes = ["static"];
export const document = (config: Record<string, any>) => ({
type: "Object | Array",
description: "JSON object"
type: {
payload: "Object | Array"
},
description: {
payload: "JSON object"
}
});

View File

@ -2,6 +2,11 @@ export { default as Component } from "./Label.svelte";
export const modes = ["static"];
export const document = (config: Record<string, any>) => ({
type: "{ label: string; confidences?: Array<{ label: string; confidence: number }>",
description: "output label and optional set of confidences per label"
type: {
payload:
"{ label: string; confidences?: Array<{ label: string; confidence: number }>"
},
description: {
payload: "output label and optional set of confidences per label"
}
});

View File

@ -2,6 +2,10 @@ export { default as Component } from "./Markdown.svelte";
export const modes = ["static"];
export const document = (config: Record<string, any>) => ({
type: "string",
description: "HTML rendering of markdown"
type: {
payload: "string"
},
description: {
payload: "HTML rendering of markdown"
}
});

View File

@ -3,6 +3,10 @@ export { default as ExampleComponent } from "../Dataset/ExampleComponents/Model3
export const modes = ["static", "dynamic"];
export const document = (config: Record<string, any>) => ({
type: "{ name: string; data: string }",
description: "file name and base64 data of Model3D object"
type: {
payload: "{ name: string; data: string }"
},
description: {
payload: "object with file name and base64 data"
}
});

View File

@ -2,7 +2,11 @@ export { default as Component } from "./Number.svelte";
export const modes = ["static", "dynamic"];
export const document = (config: Record<string, any>) => ({
type: "number",
description: "numeric value",
type: {
payload: "number"
},
description: {
payload: "numeric value"
},
example_data: config.value ?? 1
});

View File

@ -2,7 +2,11 @@ export { default as Component } from "./Radio.svelte";
export const modes = ["static", "dynamic"];
export const document = (config: Record<string, any>) => ({
type: "string",
description: "selected choice",
type: {
payload: "string"
},
description: {
payload: "selected choice"
},
example_data: config.choices.length > 1 ? config.choices[0] : ""
});

View File

@ -2,7 +2,11 @@ export { default as Component } from "./Slider.svelte";
export const modes = ["static", "dynamic"];
export const document = (config: Record<string, any>) => ({
type: "number",
description: "selected value",
type: {
payload: "number"
},
description: {
payload: "selected value"
},
example_data: config.value ?? config.minimum
});

View File

@ -2,7 +2,11 @@ export { default as Component } from "./State.svelte";
export const modes = ["static"];
export const document = (config: Record<string, any>) => ({
type: "Any",
description: "stored state value",
type: {
payload: "Any"
},
description: {
payload: "stored state value"
},
example_data: ""
});

View File

@ -2,7 +2,11 @@ export { default as Component } from "./Textbox.svelte";
export const modes = ["static", "dynamic"];
export const document = (config: Record<string, any>) => ({
type: "string",
description: "text string",
type: {
payload: "string"
},
description: {
payload: "text string"
},
example_data: config.value || "hello world"
});

View File

@ -2,6 +2,10 @@ export { default as Component } from "./TimeSeries.svelte";
export const modes = ["static", "dynamic"];
export const document = (config: Record<string, any>) => ({
type: "{data: Array<Array<number>> | string; headers?: Array<string>;}",
description: "dataset of series"
type: {
payload: "{data: Array<Array<number>> | string; headers?: Array<string>;}"
},
description: {
payload: "dataset of series"
}
});

View File

@ -2,6 +2,13 @@ export { default as Component } from "./Video.svelte";
export const modes = ["static", "dynamic"];
export const document = (config: Record<string, any>) => ({
type: "{ name: string; data: string }",
description: "file name and base64 data of video file"
type: {
input_payload: "{ name: string; data: string }",
response_object: "{ name: string; data: string, is_file: boolean }"
},
description: {
input_payload: "object with file name and base64 data",
response_object:
"object that includes path to video file. The URL: {ROOT}file={name} contains the data"
}
});

View File

@ -33,9 +33,15 @@ export interface Dependency {
cancels: Array<number>;
}
interface TypeDescription {
input_payload?: string;
response_object?: string;
payload?: string;
}
export interface Documentation {
type?: string;
description?: string;
type?: TypeDescription;
description?: TypeDescription;
example_data?: string;
}