|
<script> |
|
import { Client } from "@gradio/client"; |
|
import EndpointInputs from "../../lib/EndpointInputs.svelte"; |
|
import ResponsePreview from "../../lib/ResponsePreview.svelte"; |
|
|
|
let api = "gradio/cancel_events"; |
|
|
|
|
|
|
|
|
|
let hf_token = "hf_"; |
|
|
|
|
|
|
|
let app; |
|
|
|
|
|
|
|
let app_info; |
|
|
|
|
|
|
|
let named = []; |
|
|
|
|
|
|
|
let unnamed = []; |
|
|
|
|
|
|
|
let active_endpoint = ""; |
|
|
|
{{data: any[]; fn_index: number; endpoint: string|number}} |
|
*/ |
|
let response_data = { data: [], fn_index: 0, endpoint: "" }; |
|
|
|
|
|
|
|
let request_data = []; |
|
async function connect() { |
|
named = []; |
|
unnamed = []; |
|
app_info = undefined; |
|
active_endpoint = ""; |
|
response_data = { data: [], fn_index: 0, endpoint: "" }; |
|
if (!api || (hf_token && !hf_token.startsWith("hf_"))) return; |
|
|
|
app = await Client.connect(api, { |
|
hf_token |
|
}); |
|
|
|
const { named_endpoints, unnamed_endpoints } = await app.view_api(); |
|
|
|
named = Object.keys(named_endpoints); |
|
unnamed = Object.keys(unnamed_endpoints); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
async function select_endpoint(type, _endpoint) { |
|
response_data = { data: [], fn_index: 0, endpoint: "" }; |
|
const _endpoint_info = (await app.view_api())?.[`${type}_endpoints`]?.[ |
|
type === "unnamed" ? parseInt(_endpoint) : _endpoint |
|
]; |
|
if (!_endpoint_info) return; |
|
|
|
app_info = _endpoint_info; |
|
active_endpoint = type === "unnamed" ? parseInt(_endpoint) : _endpoint; |
|
} |
|
|
|
|
|
|
|
|
|
let job; |
|
|
|
|
|
|
|
|
|
let status = "idle"; |
|
|
|
async function submit() { |
|
response_data = { data: [], fn_index: 0, endpoint: "" }; |
|
|
|
job = app.submit(active_endpoint, request_data); |
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
function cancel() { |
|
job.cancel(); |
|
} |
|
|
|
let endpoint_type_text = ""; |
|
$: { |
|
if (!app_info) { |
|
endpoint_type_text = ""; |
|
} else if (!app_info.type.continuos && app_info.type.generator) { |
|
endpoint_type_text = |
|
"This endpoint generates values over time and can be cancelled."; |
|
} else if (app_info.type.continuos && app_info.type.generator) { |
|
endpoint_type_text = |
|
"This endpoint generates values over time and will continue to yield values until cancelled."; |
|
} else { |
|
endpoint_type_text = "This endpoint runs once and cannot be cancelled."; |
|
} |
|
} |
|
</script> |
|
|
|
<h2>Client Browser</h2> |
|
|
|
<p> |
|
Enter a space <code>user-space/name</code> to test the client in a browser environment |
|
with any space. |
|
</p> |
|
<p> |
|
You may optionally provide a <code>hf_token</code> to test a private space |
|
</p> |
|
|
|
<div class="input-wrap"> |
|
<label for=""> |
|
<span>Space Name</span> |
|
<input type="text" placeholder="user/space-name" bind:value={api} /> |
|
</label> |
|
|
|
<label for=""> |
|
<span>Hugging Face Token <i>(optional)</i></span> |
|
<input type="text" placeholder="hf_..." bind:value={hf_token} /> |
|
</label> |
|
</div> |
|
|
|
<button on:click={connect}>Connect</button> |
|
|
|
{#if named.length || unnamed.length} |
|
<div class="endpoints"> |
|
<div class="endpoint"> |
|
<h3>Named endpoints</h3> |
|
{#if named.length} |
|
{#each named as endpoint} |
|
<button |
|
class="endpoint-button" |
|
class:selected={endpoint === active_endpoint} |
|
on:click={() => select_endpoint("named", endpoint)} |
|
>{endpoint}</button |
|
> |
|
{/each} |
|
{:else} |
|
<p>There are no named endpoints</p> |
|
{/if} |
|
</div> |
|
|
|
<div class="endpoint"> |
|
<h3>Unnamed endpoints</h3> |
|
|
|
{#if unnamed.length} |
|
{#each unnamed as endpoint} |
|
<button |
|
class="endpoint-button" |
|
class:selected={parseInt(endpoint) === active_endpoint} |
|
on:click={() => select_endpoint("unnamed", endpoint)} |
|
>{endpoint}</button |
|
> |
|
{/each} |
|
{:else} |
|
<p>There are no unnamed endpoints</p> |
|
{/if} |
|
</div> |
|
</div> |
|
{/if} |
|
|
|
{#if app_info} |
|
<hr /> |
|
<p> |
|
This endpoint accepts {app_info.parameters.length |
|
? app_info.parameters.length |
|
: "no"} piece{app_info.parameters.length < 1 || |
|
app_info.parameters.length > 1 |
|
? "s" |
|
: ""} of data and returns {app_info.returns.length |
|
? app_info.returns.length |
|
: "no"} piece{app_info.returns.length < 1 || app_info.returns.length > 1 |
|
? "s" |
|
: ""} of data. {endpoint_type_text} |
|
</p> |
|
<hr /> |
|
<div class="app_info"> |
|
<div> |
|
<EndpointInputs app_info={app_info.parameters} bind:request_data /> |
|
<button class="submit" on:click={submit}>Submit Request</button> |
|
{#if app_info.type.generator || app_info.type.continuous} |
|
<button class="cancel" on:click={cancel}>Cancel Request</button> |
|
{/if} |
|
</div> |
|
<div> |
|
<ResponsePreview {status} app_info={app_info.returns} {response_data} /> |
|
</div> |
|
</div> |
|
{/if} |
|
|
|
<style> |
|
label { |
|
display: flex; |
|
flex-direction: column; |
|
gap: var(--size-1); |
|
width: 100%; |
|
} |
|
|
|
label:first-child input { |
|
margin-right: -1px; |
|
border-top-left-radius: 2px; |
|
} |
|
|
|
label:last-child input { |
|
border-top-right-radius: 2px; |
|
} |
|
|
|
input { |
|
outline: none; |
|
border-bottom: none; |
|
border-radius: 0px; |
|
} |
|
|
|
input:focus-visible { |
|
z-index: 1; |
|
border-color: var(--color-accent); |
|
} |
|
|
|
.input-wrap { |
|
display: flex; |
|
margin-top: var(--size-6); |
|
} |
|
|
|
button { |
|
border-bottom-right-radius: 2px; |
|
border-bottom-left-radius: 2px; |
|
background: var(--color-accent); |
|
padding: var(--size-2) var(--size-2-5); |
|
width: 100%; |
|
color: var(--background-fill-primary); |
|
font-weight: bold; |
|
font-size: var(--scale-0); |
|
|
|
} |
|
|
|
.endpoints button { |
|
background: var(--color-orange-200); |
|
width: auto; |
|
color: var(--body-text-color); |
|
} |
|
button.selected { |
|
background: var(--color-accent); |
|
color: white; |
|
} |
|
|
|
.endpoints { |
|
display: flex; |
|
gap: var(--size-10); |
|
margin-top: var(--size-10); |
|
} |
|
|
|
.endpoint { |
|
width: 100%; |
|
} |
|
|
|
.app_info { |
|
display: flex; |
|
gap: var(--size-10); |
|
margin-top: var(--size-10); |
|
} |
|
|
|
.app_info > div { |
|
width: 100%; |
|
} |
|
.submit { |
|
margin-top: var(--size-5); |
|
} |
|
|
|
hr { |
|
margin: var(--size-6) 0; |
|
} |
|
|
|
.cancel { |
|
margin-top: var(--size-2); |
|
background-color: var(--color-red-600); |
|
} |
|
.endpoint-button { |
|
margin-right: var(--size-1); |
|
border-radius: 2px; |
|
} |
|
|
|
button[disabled] { |
|
opacity: 0.2; |
|
} |
|
</style> |
|
|