File size: 2,869 Bytes
0ad74ed |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
import {
get_space_hardware,
hardware_types,
set_space_timeout
} from "../helpers/spaces";
import type { DuplicateOptions } from "../types";
import { Client } from "../client";
import { SPACE_METADATA_ERROR_MSG } from "../constants";
import {
get_cookie_header,
parse_and_set_cookies
} from "../helpers/init_helpers";
import { process_endpoint } from "../helpers/api_info";
export async function duplicate(
app_reference: string,
options: DuplicateOptions
): Promise<Client> {
const { hf_token, private: _private, hardware, timeout, auth } = options;
if (hardware && !hardware_types.includes(hardware)) {
throw new Error(
`Invalid hardware type provided. Valid types are: ${hardware_types
.map((v) => `"${v}"`)
.join(",")}.`
);
}
const { http_protocol, host } = await process_endpoint(
app_reference,
hf_token
);
let cookies: string[] | null = null;
if (auth) {
const cookie_header = await get_cookie_header(
http_protocol,
host,
auth,
fetch
);
if (cookie_header) cookies = parse_and_set_cookies(cookie_header);
}
const headers = {
Authorization: `Bearer ${hf_token}`,
"Content-Type": "application/json",
...(cookies ? { Cookie: cookies.join("; ") } : {})
};
const user = (
await (
await fetch(`https://huggingface.co/api/whoami-v2`, {
headers
})
).json()
).name;
const space_name = app_reference.split("/")[1];
const body: {
repository: string;
private?: boolean;
hardware?: string;
} = {
repository: `${user}/${space_name}`
};
if (_private) {
body.private = true;
}
let original_hardware;
try {
if (!hardware) {
original_hardware = await get_space_hardware(app_reference, hf_token);
}
} catch (e) {
throw Error(SPACE_METADATA_ERROR_MSG + (e as Error).message);
}
const requested_hardware = hardware || original_hardware || "cpu-basic";
body.hardware = requested_hardware;
try {
const response = await fetch(
`https://huggingface.co/api/spaces/${app_reference}/duplicate`,
{
method: "POST",
headers,
body: JSON.stringify(body)
}
);
if (response.status === 409) {
try {
const client = await Client.connect(`${user}/${space_name}`, options);
return client;
} catch (error) {
console.error("Failed to connect Client instance:", error);
throw error;
}
} else if (response.status !== 200) {
throw new Error(response.statusText);
}
const duplicated_space = await response.json();
await set_space_timeout(`${user}/${space_name}`, timeout || 300, hf_token);
return await Client.connect(
get_space_reference(duplicated_space.url),
options
);
} catch (e: any) {
throw new Error(e);
}
}
function get_space_reference(url: string): any {
const regex = /https:\/\/huggingface.co\/spaces\/([^/]+\/[^/]+)/;
const match = url.match(regex);
if (match) {
return match[1];
}
}
|