simonduerr's picture
Upload folder using huggingface_hub
514575e verified
<svelte:options accessors={true} />
<script context="module" lang="ts">
export { default as FilePreview } from "./shared/FilePreview.svelte";
export { default as BaseFileUpload } from "./shared/FileUpload.svelte";
export { default as BaseFile } from "./shared/File.svelte";
export { default as BaseExample } from "./Example.svelte";
</script>
<script lang="ts">
import "./style.css";
import type { Gradio, SelectData } from "@gradio/utils";
import File from "./shared/File.svelte";
import FileUpload from "./shared/FileUpload.svelte";
import type { FileData } from "@gradio/client";
import { Block, UploadText } from "@gradio/atoms";
import { StatusTracker } from "@gradio/statustracker";
import type { LoadingStatus } from "@gradio/statustracker";
export let elem_id = "";
export let elem_classes: string[] = [];
export let visible = true;
export let value: null | FileData | FileData[];
export let interactive: boolean;
export let root: string;
export let label: string;
export let show_label: boolean;
export let height: number | undefined = undefined;
//Molecule3D specific arguments
export let reps: any = [];
export let config: any = {};
export let confidenceLabel: string = "";
export let showviewer: boolean = true;
export let _selectable = false;
export let loading_status: LoadingStatus;
export let container = true;
export let scale: number | null = null;
export let min_width: number | undefined = undefined;
export let gradio: Gradio<{
change: never;
error: string;
upload: never;
clear: never;
select: SelectData;
clear_status: LoadingStatus;
delete: FileData;
}>;
export let file_count: "single" | "multiple" | "directory";
export let file_types: string[] = ["file"];
let old_value = value;
$: if (JSON.stringify(old_value) !== JSON.stringify(value)) {
gradio.dispatch("change");
old_value = value;
moldata = null;
retrieveContent(value);
}
let dragging = false;
let pending_upload = false;
let keys_for_reps = {
model: {
type: Number,
default: 0,
},
chain: {
type: String,
default: "",
},
resname: {
type: String,
default: "",
},
style: {
type: String,
default: "cartoon",
choices: ["cartoon", "stick", "sphere", "surface"],
},
color: {
type: String,
default: "whiteCarbon",
choices: [
"whiteCarbon",
"orangeCarbon",
"redCarbon",
"blackCarbon",
"blueCarbon",
"grayCarbon",
"greenCarbon",
"cyanCarbon",
"alphafold",
"default",
"Jmol",
"chain",
"spectrum",
],
},
residue_range: {
type: String,
default: "",
},
around: {
type: Number,
default: 0,
},
byres: {
type: Boolean,
default: false,
},
visible: {
type: Boolean,
default: true,
},
};
let moldata = null;
let allowed_extensions = ["pdb", "sdf", "mol2", "pdb1"];
async function fetchFileContent(url) {
const response = await fetch(url);
const content = await response.text();
return content;
}
let promise = null;
let errors = [];
async function retrieveContent(value) {
if (value == null) {
return [];
} else if (Array.isArray(value)) {
let tempMoldata = [];
// get file extension
for (const element of value) {
let ext = element.orig_name.split(".").pop();
if (!allowed_extensions.includes(ext)) {
errors.push(
`Invalid file extension for ${
element.orig_name
}. Expected one of ${allowed_extensions.join(", ")}, got ${ext}`
);
moldata = null;
continue;
}
tempMoldata.push({
data: await fetchFileContent(element.url),
name: element.orig_name,
format: ext,
asFrames: false,
});
}
moldata = tempMoldata;
} else if (typeof value === "object" && value !== null) {
let ext = value.orig_name.split(".").pop();
if (!allowed_extensions.includes(ext)) {
errors.push(
`Invalid file extension for ${
value.orig_name
}. Expected one of ${allowed_extensions.join(", ")}, got ${ext}`
);
moldata = null;
} else {
let t = await fetchFileContent(value.url);
let ext = value.orig_name.split(".").pop();
if (ext === "pdb1") {
ext = "pdb";
}
moldata = [
{ data: t, name: value.orig_name, format: ext, asFrames: false },
];
}
} else {
moldata = null;
}
// value is object
}
// go through each rep, do a type check and add missing keys to the rep
let lenMoldata = 0;
$: lenMoldata = moldata ? moldata.length : 0;
let representations = [];
//first add all missing keys
$: {
reps.forEach((rep) => {
for (const [key, value] of Object.entries(keys_for_reps)) {
if (rep[key] === undefined) {
rep[key] = value["default"];
}
if (rep[key].constructor != value["type"]) {
errors.push(
`Invalid type for ${key} in reps. Expected ${
value["type"]
}, got ${typeof rep[key]}`
);
}
}
});
// then check if model does exist and add to representations
reps.forEach((rep) => {
if (rep["model"] <= lenMoldata) {
representations.push(rep);
}
});
}
$: promise = retrieveContent(value);
</script>
<Block
{visible}
variant={value ? "solid" : "dashed"}
border_mode={dragging ? "focus" : "base"}
padding={false}
{elem_id}
{elem_classes}
{container}
{scale}
{min_width}
allow_overflow={false}
>
<StatusTracker
autoscroll={gradio.autoscroll}
i18n={gradio.i18n}
{...loading_status}
status={pending_upload
? "generating"
: loading_status?.status || "complete"}
on:clear_status={() => gradio.dispatch("clear_status", loading_status)}
/>
{#if !interactive}
<File
on:select={({ detail }) => gradio.dispatch("select", detail)}
selectable={_selectable}
{value}
{label}
{show_label}
{height}
{representations}
{config}
{confidenceLabel}
{moldata}
{errors}
i18n={gradio.i18n}
molviewer={showviewer}
/>
{:else}
<FileUpload
upload={gradio.client.upload}
stream_handler={gradio.client.stream}
{label}
{show_label}
{value}
{file_count}
{file_types}
selectable={_selectable}
{root}
{height}
{representations}
{config}
{confidenceLabel}
{moldata}
molviewer={showviewer}
max_file_size={gradio.max_file_size}
on:change={({ detail }) => {
value = detail;
}}
on:drag={({ detail }) => (dragging = detail)}
on:clear={() => gradio.dispatch("clear")}
on:select={({ detail }) => gradio.dispatch("select", detail)}
on:notfound={() =>
gradio.dispatch(
"error",
"identifier not found in database, check spelling"
)}
on:upload={() => gradio.dispatch("upload")}
on:error={({ detail }) => {
loading_status = loading_status || {};
loading_status.status = "error";
gradio.dispatch("error", detail);
}}
on:delete={({ detail }) => {
gradio.dispatch("delete", detail);
}}
i18n={gradio.i18n}
>
<UploadText i18n={gradio.i18n} type="file" />
</FileUpload>
{/if}
{#if errors.length > 0 && value !== null}
<div
class="flex m-2 p-4 mb-4 text-sm text-red-800 rounded-lg bg-red-50 dark:bg-gray-800 dark:text-red-400"
role="alert"
>
<svg
class="flex-shrink-0 inline w-4 h-4 mr-3 mt-[2px]"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z"
/>
</svg>
<span class="sr-only">Error in the representations</span>
<div>
<span class="font-medium"
>Couldn't display Molecule. Fix the following problems:</span
>
<ul class="mt-1.5 ml-4 list-disc list-inside">
{#each errors as error}
<li>{error}</li>
{/each}
</ul>
</div>
</div>
{/if}
</Block>