Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
machineuser
commited on
Commit
·
388ac76
1
Parent(s):
767bfd8
Sync widgets demo
Browse files
packages/widgets/README.md
CHANGED
|
@@ -6,13 +6,26 @@ Open-source version of the inference widgets from huggingface.co
|
|
| 6 |
|
| 7 |
**Demo page:** https://huggingface.co/spaces/huggingfacejs/inference-widgets
|
| 8 |
|
| 9 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10 |
|
| 11 |
```console
|
| 12 |
pnpm install
|
| 13 |
pnpm dev
|
| 14 |
```
|
| 15 |
|
| 16 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 17 |
|
| 18 |
-
|
|
|
|
| 6 |
|
| 7 |
**Demo page:** https://huggingface.co/spaces/huggingfacejs/inference-widgets
|
| 8 |
|
| 9 |
+
## Publishing
|
| 10 |
+
|
| 11 |
+
Because `@huggingface/widgets` depends on `@huggingface/tasks`, you need to publish `@huggingface/tasks` first, and then `@huggingface/widgets`. There should be a CI check to prevent publishing `@huggingface/widgets` if `@huggingface/tasks` hasn't been published yet.
|
| 12 |
+
|
| 13 |
+
## Demo
|
| 14 |
+
|
| 15 |
+
You can run the demo locally:
|
| 16 |
|
| 17 |
```console
|
| 18 |
pnpm install
|
| 19 |
pnpm dev
|
| 20 |
```
|
| 21 |
|
| 22 |
+
If you want to try the "Sign-in with HF" feature locally, you will need to https://huggingface.co/settings/applications/new an OAuth application with `"openid"` and `"inference-api"` scopes and `http://localhost:5173/auth/callback/huggingface` as the redirect URL.
|
| 23 |
+
|
| 24 |
+
Then you can create a `.env.local` file with the following content:
|
| 25 |
+
|
| 26 |
+
```env
|
| 27 |
+
OAUTH_CLIENT_ID=...
|
| 28 |
+
OAUTH_CLIENT_SECRET=...
|
| 29 |
+
```
|
| 30 |
|
| 31 |
+
If you want to try the "Sign-in with HF" feature in a Space, you can just duplicate https://huggingface.co/spaces/huggingfacejs/inference-widgets, it should work out of the box thanks to the metadata in the `README.md` file.
|
packages/widgets/package.json
CHANGED
|
@@ -38,6 +38,8 @@
|
|
| 38 |
"svelte": "^3.59.2"
|
| 39 |
},
|
| 40 |
"devDependencies": {
|
|
|
|
|
|
|
| 41 |
"@fontsource/ibm-plex-mono": "^5.0.8",
|
| 42 |
"@fontsource/source-sans-pro": "^5.0.8",
|
| 43 |
"@sveltejs/adapter-node": "^1.3.1",
|
|
|
|
| 38 |
"svelte": "^3.59.2"
|
| 39 |
},
|
| 40 |
"devDependencies": {
|
| 41 |
+
"@auth/core": "^0.18.3",
|
| 42 |
+
"@auth/sveltekit": "^0.3.14",
|
| 43 |
"@fontsource/ibm-plex-mono": "^5.0.8",
|
| 44 |
"@fontsource/source-sans-pro": "^5.0.8",
|
| 45 |
"@sveltejs/adapter-node": "^1.3.1",
|
packages/widgets/pnpm-lock.yaml
CHANGED
|
@@ -10,6 +10,12 @@ dependencies:
|
|
| 10 |
version: link:../tasks
|
| 11 |
|
| 12 |
devDependencies:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 13 |
'@fontsource/ibm-plex-mono':
|
| 14 |
specifier: ^5.0.8
|
| 15 |
version: 5.0.8
|
|
@@ -68,6 +74,35 @@ packages:
|
|
| 68 |
engines: {node: '>=10'}
|
| 69 |
dev: true
|
| 70 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 71 |
/@esbuild/[email protected]:
|
| 72 |
resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==}
|
| 73 |
engines: {node: '>=12'}
|
|
@@ -367,6 +402,10 @@ packages:
|
|
| 367 |
fastq: 1.15.0
|
| 368 |
dev: true
|
| 369 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 370 |
/@polka/[email protected]:
|
| 371 |
resolution: {integrity: sha512-C16M+IYz0rgRhWZdCmK+h58JMv8vijAA61gmz2rspCSwKwzBebpdcsiUmwrtJRdphuY30i6BSLEOP8ppbNLyLg==}
|
| 372 |
dev: true
|
|
@@ -1230,6 +1269,10 @@ packages:
|
|
| 1230 |
hasBin: true
|
| 1231 |
dev: true
|
| 1232 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1233 | |
| 1234 |
resolution: {integrity: sha512-dwXFwByc/ajSV6m5bcKAPwe4yDDF6D614pxmIi5odytzxRlwqF6nwoiCek80Ixc7Cvma5awClxrzFtxCQvcM8w==}
|
| 1235 |
dev: true
|
|
@@ -1440,6 +1483,10 @@ packages:
|
|
| 1440 |
npm-normalize-package-bin: 2.0.0
|
| 1441 |
dev: true
|
| 1442 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1443 | |
| 1444 |
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
|
| 1445 |
engines: {node: '>=0.10.0'}
|
|
@@ -1604,11 +1651,28 @@ packages:
|
|
| 1604 |
source-map-js: 1.0.2
|
| 1605 |
dev: true
|
| 1606 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1607 | |
| 1608 |
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
|
| 1609 |
engines: {node: '>= 0.8.0'}
|
| 1610 |
dev: true
|
| 1611 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1612 | |
| 1613 |
resolution: {integrity: sha512-O53y7vbePxuGFmEjgcrafMSlDpOJwOkj8YdexOt7yWlv7SB3rXoT3mHknyMJ3lf2UFH5Bmt6tnIkHcOTR6dEoA==}
|
| 1614 |
engines: {node: '>=16'}
|
|
|
|
| 10 |
version: link:../tasks
|
| 11 |
|
| 12 |
devDependencies:
|
| 13 |
+
'@auth/core':
|
| 14 |
+
specifier: ^0.18.3
|
| 15 |
+
version: 0.18.3
|
| 16 |
+
'@auth/sveltekit':
|
| 17 |
+
specifier: ^0.3.14
|
| 18 |
+
version: 0.3.14(@sveltejs/[email protected])([email protected])
|
| 19 |
'@fontsource/ibm-plex-mono':
|
| 20 |
specifier: ^5.0.8
|
| 21 |
version: 5.0.8
|
|
|
|
| 74 |
engines: {node: '>=10'}
|
| 75 |
dev: true
|
| 76 |
|
| 77 |
+
/@auth/[email protected]:
|
| 78 |
+
resolution: {integrity: sha512-YXQWxi3pKxngt+2vo3dq8+wDANlUH8nhQgX6EVdd3Enfe3vweBtHqzaWrtWzQnVb8wdGxdhxaoOlYroEBE+/yw==}
|
| 79 |
+
peerDependencies:
|
| 80 |
+
nodemailer: ^6.8.0
|
| 81 |
+
peerDependenciesMeta:
|
| 82 |
+
nodemailer:
|
| 83 |
+
optional: true
|
| 84 |
+
dependencies:
|
| 85 |
+
'@panva/hkdf': 1.1.1
|
| 86 |
+
cookie: 0.5.0
|
| 87 |
+
jose: 5.1.2
|
| 88 |
+
oauth4webapi: 2.4.0
|
| 89 |
+
preact: 10.11.3
|
| 90 |
+
preact-render-to-string: 5.2.3([email protected])
|
| 91 |
+
dev: true
|
| 92 |
+
|
| 93 |
+
/@auth/[email protected](@sveltejs/[email protected])([email protected]):
|
| 94 |
+
resolution: {integrity: sha512-Ealyi4uM4V42tk4UhhRQ+iZKah0OOp12siXwgDsCj1uBOCeZwL97RkvdMDX7pg18zBP/h2qFAuMWjW5q7bSYxA==}
|
| 95 |
+
peerDependencies:
|
| 96 |
+
'@sveltejs/kit': ^1.0.0
|
| 97 |
+
svelte: ^3.54.0 || ^4.0.0
|
| 98 |
+
dependencies:
|
| 99 |
+
'@auth/core': 0.18.3
|
| 100 |
+
'@sveltejs/kit': 1.27.4([email protected])([email protected])
|
| 101 |
+
svelte: 3.59.2
|
| 102 |
+
transitivePeerDependencies:
|
| 103 |
+
- nodemailer
|
| 104 |
+
dev: true
|
| 105 |
+
|
| 106 |
/@esbuild/[email protected]:
|
| 107 |
resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==}
|
| 108 |
engines: {node: '>=12'}
|
|
|
|
| 402 |
fastq: 1.15.0
|
| 403 |
dev: true
|
| 404 |
|
| 405 |
+
/@panva/[email protected]:
|
| 406 |
+
resolution: {integrity: sha512-dhPeilub1NuIG0X5Kvhh9lH4iW3ZsHlnzwgwbOlgwQ2wG1IqFzsgHqmKPk3WzsdWAeaxKJxgM0+W433RmN45GA==}
|
| 407 |
+
dev: true
|
| 408 |
+
|
| 409 |
/@polka/[email protected]:
|
| 410 |
resolution: {integrity: sha512-C16M+IYz0rgRhWZdCmK+h58JMv8vijAA61gmz2rspCSwKwzBebpdcsiUmwrtJRdphuY30i6BSLEOP8ppbNLyLg==}
|
| 411 |
dev: true
|
|
|
|
| 1269 |
hasBin: true
|
| 1270 |
dev: true
|
| 1271 |
|
| 1272 | |
| 1273 |
+
resolution: {integrity: sha512-X7TOC/d8KPvx4wPUuLHVgTSdoWw0UW5TQOUwhvCvj+ZPfsf9vUPhhksYPjNBWVGPQ/6yd/JrL1gQxBnIDwYdFg==}
|
| 1274 |
+
dev: true
|
| 1275 |
+
|
| 1276 | |
| 1277 |
resolution: {integrity: sha512-dwXFwByc/ajSV6m5bcKAPwe4yDDF6D614pxmIi5odytzxRlwqF6nwoiCek80Ixc7Cvma5awClxrzFtxCQvcM8w==}
|
| 1278 |
dev: true
|
|
|
|
| 1483 |
npm-normalize-package-bin: 2.0.0
|
| 1484 |
dev: true
|
| 1485 |
|
| 1486 | |
| 1487 |
+
resolution: {integrity: sha512-ZWl8ov8HeGVyc9Icl1cag76HvIcDAp23eIIT+UVGir+dEu8BMgMlvZeZwqLVd0P8DqaumH4N+QLQXN69G1QjSA==}
|
| 1488 |
+
dev: true
|
| 1489 |
+
|
| 1490 | |
| 1491 |
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
|
| 1492 |
engines: {node: '>=0.10.0'}
|
|
|
|
| 1651 |
source-map-js: 1.0.2
|
| 1652 |
dev: true
|
| 1653 |
|
| 1654 | |
| 1655 |
+
resolution: {integrity: sha512-aPDxUn5o3GhWdtJtW0svRC2SS/l8D9MAgo2+AWml+BhDImb27ALf04Q2d+AHqUUOc6RdSXFIBVa2gxzgMKgtZA==}
|
| 1656 |
+
peerDependencies:
|
| 1657 |
+
preact: '>=10'
|
| 1658 |
+
dependencies:
|
| 1659 |
+
preact: 10.11.3
|
| 1660 |
+
pretty-format: 3.8.0
|
| 1661 |
+
dev: true
|
| 1662 |
+
|
| 1663 | |
| 1664 |
+
resolution: {integrity: sha512-eY93IVpod/zG3uMF22Unl8h9KkrcKIRs2EGar8hwLZZDU1lkjph303V9HZBwufh2s736U6VXuhD109LYqPoffg==}
|
| 1665 |
+
dev: true
|
| 1666 |
+
|
| 1667 | |
| 1668 |
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
|
| 1669 |
engines: {node: '>= 0.8.0'}
|
| 1670 |
dev: true
|
| 1671 |
|
| 1672 | |
| 1673 |
+
resolution: {integrity: sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==}
|
| 1674 |
+
dev: true
|
| 1675 |
+
|
| 1676 | |
| 1677 |
resolution: {integrity: sha512-O53y7vbePxuGFmEjgcrafMSlDpOJwOkj8YdexOt7yWlv7SB3rXoT3mHknyMJ3lf2UFH5Bmt6tnIkHcOTR6dEoA==}
|
| 1678 |
engines: {node: '>=16'}
|
packages/widgets/src/app.d.ts
CHANGED
|
@@ -7,6 +7,16 @@ declare global {
|
|
| 7 |
// interface PageData {}
|
| 8 |
// interface Platform {}
|
| 9 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10 |
}
|
| 11 |
|
| 12 |
export {};
|
|
|
|
| 7 |
// interface PageData {}
|
| 8 |
// interface Platform {}
|
| 9 |
}
|
| 10 |
+
|
| 11 |
+
export interface Session {
|
| 12 |
+
access_token?: string;
|
| 13 |
+
}
|
| 14 |
+
}
|
| 15 |
+
|
| 16 |
+
declare module "@auth/core/types" {
|
| 17 |
+
export interface Session {
|
| 18 |
+
access_token?: string;
|
| 19 |
+
}
|
| 20 |
}
|
| 21 |
|
| 22 |
export {};
|
packages/widgets/src/hooks.server.ts
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { env } from "$env/dynamic/private";
|
| 2 |
+
import { skipCSRFCheck } from "@auth/core";
|
| 3 |
+
import { SvelteKitAuth } from "@auth/sveltekit";
|
| 4 |
+
import type { Handle } from "@sveltejs/kit";
|
| 5 |
+
import { sequence } from "@sveltejs/kit/hooks";
|
| 6 |
+
|
| 7 |
+
const handleSSO =
|
| 8 |
+
env.OAUTH_CLIENT_ID && env.OAUTH_CLIENT_SECRET
|
| 9 |
+
? SvelteKitAuth({
|
| 10 |
+
// Should be fine as long as your reverse proxy is configured to only accept traffic with the correct host header
|
| 11 |
+
trustHost: true,
|
| 12 |
+
/**
|
| 13 |
+
* SvelteKit has built-in CSRF protection, so we can skip the check
|
| 14 |
+
*/
|
| 15 |
+
skipCSRFCheck: skipCSRFCheck,
|
| 16 |
+
providers: [
|
| 17 |
+
{
|
| 18 |
+
name: "Hugging Face",
|
| 19 |
+
id: "huggingface",
|
| 20 |
+
type: "oidc",
|
| 21 |
+
clientId: env.OAUTH_CLIENT_ID,
|
| 22 |
+
clientSecret: env.OAUTH_CLIENT_SECRET,
|
| 23 |
+
issuer: "https://huggingface.co",
|
| 24 |
+
wellKnown: "https://huggingface.co/.well-known/openid-configuration",
|
| 25 |
+
/** Add "inference-api" scope and remove "email" scope */
|
| 26 |
+
authorization: { params: { scope: "openid profile inference-api" } },
|
| 27 |
+
checks: ["state" as never, "pkce" as never],
|
| 28 |
+
},
|
| 29 |
+
],
|
| 30 |
+
secret: env.OAUTH_CLIENT_SECRET,
|
| 31 |
+
/**
|
| 32 |
+
* Get the access_token without an account in DB, to make calls to the inference API
|
| 33 |
+
*/
|
| 34 |
+
callbacks: {
|
| 35 |
+
async jwt({ token, account }) {
|
| 36 |
+
if (account) {
|
| 37 |
+
return {
|
| 38 |
+
...token,
|
| 39 |
+
access_token: account.access_token,
|
| 40 |
+
};
|
| 41 |
+
}
|
| 42 |
+
return token;
|
| 43 |
+
},
|
| 44 |
+
async session({ session, token }) {
|
| 45 |
+
return {
|
| 46 |
+
...session,
|
| 47 |
+
access_token: token.access_token,
|
| 48 |
+
};
|
| 49 |
+
},
|
| 50 |
+
},
|
| 51 |
+
})
|
| 52 |
+
: null;
|
| 53 |
+
|
| 54 |
+
const handleGlobal: Handle = async ({ event, resolve }) => {
|
| 55 |
+
const response = await resolve(event);
|
| 56 |
+
return response;
|
| 57 |
+
};
|
| 58 |
+
|
| 59 |
+
export const handle = handleSSO ? sequence(handleSSO, handleGlobal) : handleGlobal;
|
packages/widgets/src/routes/+layout.server.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { env } from "$env/dynamic/private";
|
| 2 |
+
import type { LayoutServerLoad } from "./$types.js";
|
| 3 |
+
|
| 4 |
+
export const load: LayoutServerLoad = async ({ locals }) => {
|
| 5 |
+
const session = await locals.getSession();
|
| 6 |
+
|
| 7 |
+
return {
|
| 8 |
+
access_token: session?.access_token,
|
| 9 |
+
supportsOAuth: !!env.OAUTH_CLIENT_ID && !!env.OAUTH_CLIENT_SECRET,
|
| 10 |
+
};
|
| 11 |
+
};
|
packages/widgets/src/routes/+page.svelte
CHANGED
|
@@ -5,17 +5,27 @@
|
|
| 5 |
import InferenceWidget from "$lib/components/InferenceWidget/InferenceWidget.svelte";
|
| 6 |
import ModeSwitcher from "$lib/components/DemoThemeSwitcher/DemoThemeSwitcher.svelte";
|
| 7 |
import { onMount } from "svelte";
|
|
|
|
| 8 |
|
| 9 |
-
let
|
|
|
|
| 10 |
|
| 11 |
function storeHFToken() {
|
| 12 |
window.localStorage.setItem("hf_token", apiToken);
|
| 13 |
}
|
| 14 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 15 |
onMount(() => {
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
|
|
|
|
|
|
| 19 |
}
|
| 20 |
});
|
| 21 |
|
|
@@ -526,10 +536,24 @@
|
|
| 526 |
<div class="flex flex-col gap-6 py-12 px-4">
|
| 527 |
<ModeSwitcher />
|
| 528 |
|
| 529 |
-
|
| 530 |
-
|
| 531 |
-
|
| 532 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 533 |
|
| 534 |
<div>
|
| 535 |
<h1 class="mb-8 text-4xl font-semibold">Showcase of all types of inference widgets running</h1>
|
|
|
|
| 5 |
import InferenceWidget from "$lib/components/InferenceWidget/InferenceWidget.svelte";
|
| 6 |
import ModeSwitcher from "$lib/components/DemoThemeSwitcher/DemoThemeSwitcher.svelte";
|
| 7 |
import { onMount } from "svelte";
|
| 8 |
+
import { browser } from "$app/environment";
|
| 9 |
|
| 10 |
+
export let data;
|
| 11 |
+
let apiToken = data.access_token || "";
|
| 12 |
|
| 13 |
function storeHFToken() {
|
| 14 |
window.localStorage.setItem("hf_token", apiToken);
|
| 15 |
}
|
| 16 |
|
| 17 |
+
/**
|
| 18 |
+
* If we are in an iframe, we need to open the auth page in a new tab
|
| 19 |
+
* to avoid issues with third-party cookies in a space
|
| 20 |
+
*/
|
| 21 |
+
const isIframe = browser && window.self !== window.parent;
|
| 22 |
+
|
| 23 |
onMount(() => {
|
| 24 |
+
if (!data.supportsOAuth) {
|
| 25 |
+
const token = window.localStorage.getItem("hf_token");
|
| 26 |
+
if (token) {
|
| 27 |
+
apiToken = token;
|
| 28 |
+
}
|
| 29 |
}
|
| 30 |
});
|
| 31 |
|
|
|
|
| 536 |
<div class="flex flex-col gap-6 py-12 px-4">
|
| 537 |
<ModeSwitcher />
|
| 538 |
|
| 539 |
+
{#if data.supportsOAuth}
|
| 540 |
+
{#if !data.access_token}
|
| 541 |
+
<form class="contents" method="post" action="/auth/signin/huggingface" target={isIframe ? "_blank" : ""}>
|
| 542 |
+
<button type="submit" title="Sign in with Hugging Face">
|
| 543 |
+
<img
|
| 544 |
+
src="https://huggingface.co/datasets/huggingface/badges/resolve/main/sign-in-with-huggingface-xl-dark.svg"
|
| 545 |
+
alt="Sign in with Hugging Face"
|
| 546 |
+
class="h-12 w-auto"
|
| 547 |
+
/>
|
| 548 |
+
</button>
|
| 549 |
+
</form>
|
| 550 |
+
{/if}
|
| 551 |
+
{:else}
|
| 552 |
+
<label>
|
| 553 |
+
<div class="text-xl font-semibold">First, Enter HF token</div>
|
| 554 |
+
<input class="form-input" type="text" bind:value={apiToken} placeholder="hf_..." on:change={storeHFToken} />
|
| 555 |
+
</label>
|
| 556 |
+
{/if}
|
| 557 |
|
| 558 |
<div>
|
| 559 |
<h1 class="mb-8 text-4xl font-semibold">Showcase of all types of inference widgets running</h1>
|