Spaces:
Build error
Build error
File size: 10,433 Bytes
0345768 8ca56b3 fdd6860 0345768 6460cc3 0345768 b775a96 4797320 e4bb5d4 7e0c7d3 0345768 3e317b0 6677ed7 3e317b0 d85840f b8ac61b 3e317b0 4797320 1ec80ac 4797320 8ca56b3 4797320 b7b387b 4797320 8ca56b3 4797320 8ec7dbf b7b387b 0345768 4797320 c500ff5 4797320 c500ff5 4797320 c500ff5 4797320 8805249 4797320 8805249 4797320 bf5fb31 4797320 b219560 9377dea b219560 b0b5c7c b219560 8f8e04c b219560 4797320 8805249 6677ed7 8805249 6677ed7 8805249 41930b6 8805249 41930b6 8805249 41930b6 8805249 41930b6 8805249 41930b6 8805249 41930b6 8805249 027ed4c c500ff5 ba3ba40 c500ff5 4797320 8f8e04c ba3ba40 1ec80ac 4797320 c500ff5 9c0f9b6 0437553 1ec80ac c500ff5 4797320 fdd6860 e1b4bc9 8f8e04c 9c0f9b6 8f8e04c 9c0f9b6 027ed4c f6b0264 4797320 0345768 8f8e04c 8317a79 8f8e04c b8ac61b ba3ba40 428b978 3fc3e48 8f8e04c 0345768 8f8e04c 276e364 8f8e04c ee62d83 c48f5d1 6ed66b8 8530d2f 7a1deb2 8530d2f 8f8e04c |
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 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 |
from typing import List
import numpy as np
import requests
import gradio as gr
import time
import os
from huggingface_hub import (
create_repo,
get_full_repo_name,
upload_file,
)
class SpaceBuilder:
error_message = None
url = None
@classmethod
def split_space_names(cls, names: str) -> List[str]:
"""
Splits and filters the given space_names.
:param names: space names
:return: Name List
"""
name_list = names.split("\n")
filtered_list = []
for name in name_list:
if not (name == "" or name.isspace()):
name = name.replace(" ", "")
filtered_list.append(name)
return filtered_list
@classmethod
def file_as_a_string(cls, name_list: List[str], title: str, description: str) -> str:
"""
Returns the file that is going to be created in the new space as string.
:param name_list: list of space names
:param title: title
:param description: description
:return: file as a string
"""
return (
f"import gradio as gr"
f"\nname_list = {name_list}"
f"\ninterfaces = [gr.Interface.load(name) for name in name_list]"
f"\ngr.mix.Parallel(*interfaces, title=\"{title}\", description=\"{description}\").launch()"
)
@classmethod
def control_input_and_output_types(
cls, interface_list: List["gr.Interface"]
) -> bool:
"""
Controls whether if input and output types of the given interfaces are the same.
:param interface_list: list of interfaces
:return: True if all input and output types are the same
"""
first_input_types = [
type(input) for input in interface_list[0].input_components
]
first_output_types = [
type(output) for output in interface_list[0].output_components
]
for interface in interface_list:
interface_input_types = [
type(input) for input in interface.input_components
]
if not np.all(
interface_input_types == first_input_types
): # Vectorize the comparison and don't use double for loop
cls.error_message = "Provided space input types are different"
return False
interface_output_types = [
type(output) for output in interface.output_components
]
if not np.all(interface_output_types == first_output_types):
cls.error_message = "Provided space output types are different"
return False
return True
@classmethod
def check_space_name_availability(cls, hf_token: str, space_name: str) -> bool:
"""
Check whether if the space_name is currently used.
:param hf_token: hugging_face token
:param space_name:
:return: True if the space_name is available
"""
try:
repo_name = get_full_repo_name(model_id=space_name, token=hf_token)
except Exception as ex:
print(ex)
cls.error_message = "You have given an incorrect HuggingFace token"
return False
try:
url = f"https://huggingface.co/spaces/{repo_name}"
response = requests.get(url)
if response.status_code == 200:
cls.error_message = f"The {repo_name} is already used."
return False
else:
print(f"The space name {repo_name} is available")
return True
except Exception as ex:
print(ex)
cls.error_message = "Can not send a request to https://huggingface.co"
return False
@classmethod
def load_and_check_spaces(cls, names: str) -> bool:
"""
Loads given space inputs as interfaces and checks whether if they are loadable.
:param names: Input space names
:return: True if check is successful
"""
name_list = cls.split_space_names(names)
try:
# We could gather these interfaces in parallel if gradio was supporting async gathering. It will probably be possible after the migration to the FastAPI is completed.
interfaces = [gr.Interface.load(name) for name in name_list]
except Exception as ex:
print(ex)
cls.error_message = (
f"One of the given space cannot be loaded to gradio, sorry for the inconvenience. "
f"\nPlease use different input space names!"
)
return False
if not cls.control_input_and_output_types(interfaces):
return False
else:
print("Loaded and checked input spaces, great it works!")
return True
@classmethod
def create_space(cls, input_space_names: str, target_space_name: str, hf_token: str, title: str, description: str) -> bool:
"""
Creates the target space with the given space names.
:param input_space_names: Input space name_list
:param target_space_name: Target space_name
:param hf_token: HuggingFace Write Token
:param title: Target Interface Title
:param description: Target Interface Description
:return: True if success
"""
name_list = cls.split_space_names(input_space_names)
try:
create_repo(name=target_space_name, token=hf_token, repo_type="space", space_sdk="gradio")
except Exception as ex:
print(ex)
cls.error_message = "Please provide a correct space name as Only regular characters and '-', '_', '.' accepted. '--' and '..' are forbidden. '-' and '.' cannot start or end the name."
return False
repo_name = get_full_repo_name(model_id=target_space_name, token=hf_token)
try:
file_string = cls.file_as_a_string(name_list, title, description)
temp_file = open("temp_file.txt", "w")
temp_file.write(file_string)
temp_file.close()
except Exception as ex:
print(ex)
cls.error_message = "An exception occurred during temporary file writing"
return False
try:
file_url = upload_file(
path_or_fileobj="temp_file.txt",
path_in_repo="app.py",
repo_id=repo_name,
repo_type="space",
token=hf_token,
)
cls.url = f"https://huggingface.co/spaces/{repo_name}"
return True
except Exception as ex:
print(ex)
cls.error_message = (
"An exception occurred during writing app.py to the target space"
)
return False
@staticmethod
def build_space(
model_or_space_names: str, hf_token: str, target_space_name: str, interface_title: str, interface_description: str
) -> str:
"""
Creates a space with given input spaces.
:param model_or_space_names: Multiple model or space names split with new lines
:param hf_token: HuggingFace token
:param target_space_name: Target Space Name
:param interface_title: Target Interface Title
:param interface_description: Target Interface Description
:return:
"""
if (
model_or_space_names== "" or model_or_space_names.isspace()
or target_space_name == "" or target_space_name.isspace()
or interface_title == "" or interface_title.isspace()
or interface_description == "" or interface_description.isspace()
):
return "Please fill all the inputs"
if hf_token == "" or hf_token.isspace():
hf_token = os.environ['HF_SELF_TOKEN']
if not SpaceBuilder.check_space_name_availability(hf_token=hf_token, space_name=target_space_name):
return SpaceBuilder.error_message
if not SpaceBuilder.load_and_check_spaces(names=model_or_space_names):
return SpaceBuilder.error_message
if not SpaceBuilder.create_space(input_space_names=model_or_space_names, target_space_name=target_space_name, hf_token=hf_token, title=interface_title, description=interface_description):
return SpaceBuilder.error_message
url = SpaceBuilder.url
return f"<a href={url}>{url}</a>"
if __name__ == "__main__":
print(f"Gradio Version: {gr.__version__}")
iface = gr.Interface(
fn=SpaceBuilder.build_space,
inputs=[
gr.inputs.Textbox(
lines=4,
placeholder=(
f"Drop model and space links at each line and I will create a new space comparing them. Usage examples:"
f"\nspaces/onnx/GPT-2"
f"\nmodels/gpt2-large"
f"\nmodels/gpt2"
),
),
gr.inputs.Textbox(lines=1, placeholder="HuggingFace Write Token"),
gr.inputs.Textbox(lines=1, placeholder="Name for the target space, ie. space-building-space"),
gr.inputs.Textbox(lines=1, placeholder="Title for the target space interface, ie. Title"),
gr.inputs.Textbox(lines=1, placeholder="Description for the target space interface, ie. Description"),
],
title="Model Comparator Space Builder",
description="Welcome onboard 🤗, I can create a comparative space which will compare the models and/or spaces you provide to me. You can get your HF Write Token from [here](https://huggingface.co/settings/tokens). If you leave HF Token input empty, the space will release under the author's account, [farukozderim](https://huggingface.co/farukozderim). Finally, you can publish spaces as a clone of other spaces if you provide just a single model or space. Have fun :)",
outputs=gr.outputs.HTML(label="URL"),
examples= [
["spaces/onnx/GPT-2 \nmodels/gpt2-large \nmodels/EleutherAI/gpt-j-6B", "", "comparison-space", "example-title", "example-description"],
["spaces/onnx/GPT-2", "", "duplicate-space", "example-title", "example-description"],
["models/EleutherAI/gpt-j-6B", "", "space-from-a-model", "example-title", "example-description"]
],
)
iface.launch()
|