Spaces:
Running
Running
| const c = console; | |
| const ENDPOINT = "https://huggingface.co"; | |
| async function whoami(token: string): Promise<{ name: string }> { | |
| const path = `${ENDPOINT}/api/whoami-v2`; | |
| const res = await fetch(path, { | |
| headers: { | |
| Authorization: `Bearer ${token}`, | |
| } | |
| }); | |
| return await res.json(); | |
| } | |
| /** | |
| * @returns `str`: full URL to the newly created repo. | |
| */ | |
| async function createRepo( | |
| token: string, | |
| repoName: string, | |
| repoType: "model" | "dataset" | "space", | |
| ): Promise<string> { | |
| const path = `${ENDPOINT}/api/repos/create`; | |
| const res = await fetch(path, { | |
| method: "POST", | |
| headers: { | |
| Authorization: `Bearer ${token}`, | |
| "Content-Type": "application/json", | |
| }, | |
| body: JSON.stringify({ | |
| name: repoName, | |
| type: repoType, | |
| }) | |
| }); | |
| const output = await res.json(); | |
| if (!res.ok) { | |
| throw new Error(`Error ${res.status}: ${output.error ?? output}`); | |
| } | |
| return output.url; | |
| } | |
| /** | |
| * @returns `str`: URL to the newly uploaded blob. | |
| */ | |
| async function uploadFile( | |
| token: string, | |
| repoId: string, | |
| repoType: "model" | "dataset" | "space", | |
| filename: string, | |
| blob: Blob, | |
| ): Promise<string> { | |
| const prefix = (repoType === "dataset") ? "/datasets" | |
| : (repoType === "space") ? "/spaces" | |
| : ""; | |
| const path = `${ENDPOINT}/api${prefix}/${repoId}/upload/main/${filename}`; | |
| const res = await fetch(path, { | |
| method: "POST", | |
| headers: { | |
| Authorization: `Bearer ${token}`, | |
| }, | |
| body: blob | |
| }); | |
| const output = await res.json(); | |
| if (!res.ok) { | |
| throw new Error(`Error ${res.status}: ${output.error ?? output}`); | |
| } | |
| return output.url; | |
| } | |
| const FILES_TO_UPLOAD = [ | |
| "./mobilenet/model.json", | |
| "./mobilenet/group1-shard1of2", | |
| "./mobilenet/group1-shard2of2", | |
| "./mobilenet/coffee.jpg", | |
| "./mobilenet/README.md", | |
| ]; | |
| function filenameFromURL(url: string): string { | |
| return url.substring(url.lastIndexOf("/") + 1); | |
| } | |
| window.addEventListener("load", function () { | |
| const tokenEl = document.querySelector<HTMLInputElement>("#token")!; | |
| const repoNameEl = document.querySelector<HTMLInputElement>("#repo_name")!; | |
| const button = document.querySelector("#submit")!; | |
| const output = document.querySelector("#logs")!; | |
| const storedToken = window.localStorage.getItem("hf_token"); | |
| if (storedToken) { | |
| tokenEl.value = storedToken; | |
| /// ^to help in dev. | |
| } | |
| repoNameEl.value = `tfjs-mobilenet-${Date.now() % 1_000}`; | |
| /// "random" repo name | |
| button.addEventListener("click", async function () { | |
| const token = tokenEl.value; | |
| const repoName = repoNameEl.value; | |
| if (!token || !repoName) { | |
| alert("You need a token and a repo name"); | |
| return; | |
| } | |
| button.setAttribute("disabled", "disabled"); | |
| try { | |
| const fullUrl = await createRepo(token, repoName, "model"); | |
| const repoId = fullUrl.replace(ENDPOINT, "").replace(/^\//, ""); | |
| for (const file of FILES_TO_UPLOAD) { | |
| const blob = await (await fetch(file)).blob(); | |
| await uploadFile(token, repoId, "model", filenameFromURL(file), blob); | |
| } | |
| button.insertAdjacentHTML( | |
| "afterend", | |
| `<div class="text-green-500 mb-6">π Upload complete! Model page is <a target="_blank" class="text-bold underline" href="${fullUrl}">${fullUrl}</a></div>` | |
| ); | |
| } catch (err) { | |
| output.append("\n"+err); | |
| } | |
| button.removeAttribute("disabled"); | |
| }); | |
| }); | |