Spaces:
Sleeping
Sleeping
refactor: use client API for spaces-config endpoint
Browse files
src/lib/server/api/routes/groups/misc.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { requiresUser } from "$lib/server/auth";
|
|
| 4 |
import { collections } from "$lib/server/database";
|
| 5 |
import { authCondition } from "$lib/server/auth";
|
| 6 |
import { config } from "$lib/server/config";
|
|
|
|
| 7 |
|
| 8 |
export interface FeatureFlags {
|
| 9 |
searchEnabled: boolean;
|
|
@@ -16,6 +17,8 @@ export interface FeatureFlags {
|
|
| 16 |
isAdmin: boolean;
|
| 17 |
}
|
| 18 |
|
|
|
|
|
|
|
| 19 |
export const misc = new Elysia()
|
| 20 |
.use(authPlugin)
|
| 21 |
.get("/public-config", async () => config.getPublicConfig())
|
|
@@ -71,7 +74,33 @@ export const misc = new Elysia()
|
|
| 71 |
isAdmin: locals.isAdmin,
|
| 72 |
} satisfies FeatureFlags;
|
| 73 |
})
|
| 74 |
-
.get("/spaces-config", () => {
|
| 75 |
-
|
| 76 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 77 |
});
|
|
|
|
| 4 |
import { collections } from "$lib/server/database";
|
| 5 |
import { authCondition } from "$lib/server/auth";
|
| 6 |
import { config } from "$lib/server/config";
|
| 7 |
+
import { Client } from "@gradio/client";
|
| 8 |
|
| 9 |
export interface FeatureFlags {
|
| 10 |
searchEnabled: boolean;
|
|
|
|
| 17 |
isAdmin: boolean;
|
| 18 |
}
|
| 19 |
|
| 20 |
+
export type ApiReturnType = Awaited<ReturnType<typeof Client.prototype.view_api>>;
|
| 21 |
+
|
| 22 |
export const misc = new Elysia()
|
| 23 |
.use(authPlugin)
|
| 24 |
.get("/public-config", async () => config.getPublicConfig())
|
|
|
|
| 74 |
isAdmin: locals.isAdmin,
|
| 75 |
} satisfies FeatureFlags;
|
| 76 |
})
|
| 77 |
+
.get("/spaces-config", async ({ query }) => {
|
| 78 |
+
if (config.COMMUNITY_TOOLS !== "true") {
|
| 79 |
+
throw new Error("Community tools are not enabled");
|
| 80 |
+
}
|
| 81 |
+
|
| 82 |
+
const space = query.space;
|
| 83 |
+
|
| 84 |
+
if (!space) {
|
| 85 |
+
throw new Error("Missing space");
|
| 86 |
+
}
|
| 87 |
+
|
| 88 |
+
// Extract namespace from space URL or use as-is if it's already in namespace format
|
| 89 |
+
let namespace = null;
|
| 90 |
+
if (space.startsWith("https://huggingface.co/spaces/")) {
|
| 91 |
+
namespace = space.split("/").slice(-2).join("/");
|
| 92 |
+
} else if (space.match(/^[^/]+\/[^/]+$/)) {
|
| 93 |
+
namespace = space;
|
| 94 |
+
}
|
| 95 |
+
|
| 96 |
+
if (!namespace) {
|
| 97 |
+
throw new Error("Invalid space name. Specify a namespace or a full URL on huggingface.co.");
|
| 98 |
+
}
|
| 99 |
+
|
| 100 |
+
try {
|
| 101 |
+
const api = await (await Client.connect(namespace)).view_api();
|
| 102 |
+
return api as ApiReturnType;
|
| 103 |
+
} catch (e) {
|
| 104 |
+
throw new Error("Error fetching space API. Is the name correct?");
|
| 105 |
+
}
|
| 106 |
});
|
src/lib/utils/getGradioApi.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
| 1 |
-
import { base } from "$app/paths";
|
| 2 |
-
import type { Client } from "@gradio/client";
|
| 3 |
-
|
| 4 |
-
export type ApiReturnType = Awaited<ReturnType<typeof Client.prototype.view_api>>;
|
| 5 |
-
|
| 6 |
-
export async function getGradioApi(space: string) {
|
| 7 |
-
const api: ApiReturnType = await fetch(`${base}/api/spaces-config?space=${space}`).then(
|
| 8 |
-
async (res) => {
|
| 9 |
-
if (!res.ok) {
|
| 10 |
-
throw new Error(await res.text());
|
| 11 |
-
}
|
| 12 |
-
return res.json();
|
| 13 |
-
}
|
| 14 |
-
);
|
| 15 |
-
return api;
|
| 16 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/routes/api/spaces-config/+server.ts
DELETED
|
@@ -1,45 +0,0 @@
|
|
| 1 |
-
import { config } from "$lib/server/config";
|
| 2 |
-
import { Client } from "@gradio/client";
|
| 3 |
-
|
| 4 |
-
export async function GET({ url }) {
|
| 5 |
-
if (config.COMMUNITY_TOOLS !== "true") {
|
| 6 |
-
return new Response("Community tools are not enabled", { status: 403 });
|
| 7 |
-
}
|
| 8 |
-
|
| 9 |
-
const space = url.searchParams.get("space");
|
| 10 |
-
|
| 11 |
-
if (!space) {
|
| 12 |
-
return new Response("Missing space", { status: 400 });
|
| 13 |
-
}
|
| 14 |
-
// Extract namespace from space URL or use as-is if it's already in namespace format
|
| 15 |
-
let namespace = null;
|
| 16 |
-
if (space.startsWith("https://huggingface.co/spaces/")) {
|
| 17 |
-
namespace = space.split("/").slice(-2).join("/");
|
| 18 |
-
} else if (space.match(/^[^/]+\/[^/]+$/)) {
|
| 19 |
-
namespace = space;
|
| 20 |
-
}
|
| 21 |
-
|
| 22 |
-
if (!namespace) {
|
| 23 |
-
return new Response(
|
| 24 |
-
"Invalid space name. Specify a namespace or a full URL on huggingface.co.",
|
| 25 |
-
{ status: 400 }
|
| 26 |
-
);
|
| 27 |
-
}
|
| 28 |
-
|
| 29 |
-
try {
|
| 30 |
-
const api = await (await Client.connect(namespace)).view_api();
|
| 31 |
-
return new Response(JSON.stringify(api), {
|
| 32 |
-
status: 200,
|
| 33 |
-
headers: {
|
| 34 |
-
"Content-Type": "application/json",
|
| 35 |
-
},
|
| 36 |
-
});
|
| 37 |
-
} catch (e) {
|
| 38 |
-
return new Response("Error fetching space API. Is the name correct?", {
|
| 39 |
-
status: 400,
|
| 40 |
-
headers: {
|
| 41 |
-
"Content-Type": "application/json",
|
| 42 |
-
},
|
| 43 |
-
});
|
| 44 |
-
}
|
| 45 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/routes/tools/ToolEdit.svelte
CHANGED
|
@@ -8,7 +8,6 @@
|
|
| 8 |
import { browser } from "$app/environment";
|
| 9 |
import ToolLogo from "$lib/components/ToolLogo.svelte";
|
| 10 |
import { colors, icons } from "$lib/utils/tools";
|
| 11 |
-
import { getGradioApi } from "$lib/utils/getGradioApi";
|
| 12 |
import { goto } from "$app/navigation";
|
| 13 |
import { base } from "$app/paths";
|
| 14 |
import ToolInputComponent from "./ToolInputComponent.svelte";
|
|
@@ -16,6 +15,7 @@
|
|
| 16 |
|
| 17 |
import CarbonInformation from "~icons/carbon/information";
|
| 18 |
import { page } from "$app/state";
|
|
|
|
| 19 |
|
| 20 |
interface Props {
|
| 21 |
tool?: CommunityToolEditable | undefined;
|
|
@@ -31,6 +31,9 @@
|
|
| 31 |
|
| 32 |
let APIloading = $state(false);
|
| 33 |
let formLoading = $state(false);
|
|
|
|
|
|
|
|
|
|
| 34 |
const dispatch = createEventDispatcher<{ close: void }>();
|
| 35 |
|
| 36 |
onMount(async () => {
|
|
@@ -67,7 +70,13 @@
|
|
| 67 |
|
| 68 |
APIloading = true;
|
| 69 |
|
| 70 |
-
const api = await
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 71 |
|
| 72 |
const newInputs = api.named_endpoints[editableTool.endpoint].parameters.map((param, idx) => {
|
| 73 |
if (tool?.inputs[idx]?.name === param.parameter_name) {
|
|
@@ -319,7 +328,7 @@
|
|
| 319 |
{/if}
|
| 320 |
|
| 321 |
{#if editableTool.baseUrl}
|
| 322 |
-
{#await
|
| 323 |
<p class="text-sm text-gray-500">Loading...</p>
|
| 324 |
{:then api}
|
| 325 |
<div class="flex flex-row flex-wrap gap-4">
|
|
@@ -596,8 +605,8 @@
|
|
| 596 |
No endpoints found in this space. Try another one.
|
| 597 |
</p>
|
| 598 |
{/if}
|
| 599 |
-
{:catch
|
| 600 |
-
<p class="text-sm text-gray-500">{
|
| 601 |
{/await}
|
| 602 |
{/if}
|
| 603 |
</div>
|
|
|
|
| 8 |
import { browser } from "$app/environment";
|
| 9 |
import ToolLogo from "$lib/components/ToolLogo.svelte";
|
| 10 |
import { colors, icons } from "$lib/utils/tools";
|
|
|
|
| 11 |
import { goto } from "$app/navigation";
|
| 12 |
import { base } from "$app/paths";
|
| 13 |
import ToolInputComponent from "./ToolInputComponent.svelte";
|
|
|
|
| 15 |
|
| 16 |
import CarbonInformation from "~icons/carbon/information";
|
| 17 |
import { page } from "$app/state";
|
| 18 |
+
import { throwOnError, useAPIClient } from "$lib/APIClient";
|
| 19 |
|
| 20 |
interface Props {
|
| 21 |
tool?: CommunityToolEditable | undefined;
|
|
|
|
| 31 |
|
| 32 |
let APIloading = $state(false);
|
| 33 |
let formLoading = $state(false);
|
| 34 |
+
|
| 35 |
+
const client = useAPIClient();
|
| 36 |
+
|
| 37 |
const dispatch = createEventDispatcher<{ close: void }>();
|
| 38 |
|
| 39 |
onMount(async () => {
|
|
|
|
| 70 |
|
| 71 |
APIloading = true;
|
| 72 |
|
| 73 |
+
const api = await client["spaces-config"]
|
| 74 |
+
.get({
|
| 75 |
+
query: {
|
| 76 |
+
space: editableTool.baseUrl,
|
| 77 |
+
},
|
| 78 |
+
})
|
| 79 |
+
.then(throwOnError);
|
| 80 |
|
| 81 |
const newInputs = api.named_endpoints[editableTool.endpoint].parameters.map((param, idx) => {
|
| 82 |
if (tool?.inputs[idx]?.name === param.parameter_name) {
|
|
|
|
| 328 |
{/if}
|
| 329 |
|
| 330 |
{#if editableTool.baseUrl}
|
| 331 |
+
{#await client["spaces-config"].get({ query: { space: spaceUrl } }).then(throwOnError)}
|
| 332 |
<p class="text-sm text-gray-500">Loading...</p>
|
| 333 |
{:then api}
|
| 334 |
<div class="flex flex-row flex-wrap gap-4">
|
|
|
|
| 605 |
No endpoints found in this space. Try another one.
|
| 606 |
</p>
|
| 607 |
{/if}
|
| 608 |
+
{:catch rejected}
|
| 609 |
+
<p class="text-sm text-gray-500">{JSON.parse(rejected.message).value}</p>
|
| 610 |
{/await}
|
| 611 |
{/if}
|
| 612 |
</div>
|