Spaces:
Build error
Build error
| from typing import List | |
| import numpy as np | |
| import requests | |
| import gradio as gr | |
| from huggingface_hub import ( | |
| create_repo, | |
| get_full_repo_name, | |
| upload_file, | |
| ) | |
| class SpaceBuilder: | |
| error_message = None | |
| url = None | |
| def split_space_names(cls, names: str) -> List[str]: | |
| """ | |
| Splits and filters the given space_names. | |
| :param names: names | |
| :return: Name List | |
| """ | |
| name_list = names.split("\n") | |
| filtered_list = [] | |
| for name in name_list: | |
| if not (name == "" or name.isspace()): | |
| filtered_list.append(name) | |
| return filtered_list | |
| def file_as_a_string(cls, name_list: List[str]) -> str: | |
| """ | |
| Returns the file that is going to be created in the new space as string. | |
| :param name_list: list of space names | |
| :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).launch()" | |
| ) | |
| def create_space(cls, names: str, space_name: str, hf_token: str) -> bool: | |
| """ | |
| Creates the space. | |
| :param name_list: Input space name_list | |
| :param space_name: Target space_name | |
| :param hf_token: HuggingFace Write Token | |
| :return: True if success | |
| """ | |
| name_list = cls.split_space_names(names) | |
| create_repo(name=space_name, token=hf_token, repo_type="space", space_sdk="gradio") | |
| repo = get_full_repo_name(model_id=space_name, token=hf_token) | |
| try: | |
| file_string = cls.file_as_a_string(name_list) | |
| 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: | |
| cls.url = upload_file( | |
| path_or_fileobj="temp_file.txt", | |
| path_in_repo="app.py", | |
| repo_id=repo, | |
| repo_type="space", | |
| token=hf_token, | |
| ) | |
| return True | |
| except Exception as ex: | |
| print(ex) | |
| cls.error_message = "An exception occurred during writing app.py to the target space" | |
| return False | |
| 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 check is successful | |
| """ | |
| name_list = cls.split_space_names(names) | |
| try: | |
| interfaces = [gr.Interface.load(name) for name in name_list] | |
| except Exception as ex: | |
| print(ex) | |
| cls.error_message = "One of the given models cannot be loaded to gradio, sorry for the inconvenience" | |
| return False | |
| if not cls.control_input_and_output_types(interfaces): | |
| cls.error_message = "Spaces have different input or output types, could not combine them!" | |
| return False | |
| else: | |
| return True | |
| 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 = "Given spaces's 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 = "Given spaces's input types are different" | |
| return False | |
| return True | |
| 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 = "The the username/space_name is already used for the given token's user" | |
| return False | |
| else: | |
| return True | |
| except Exception as ex: | |
| cls.error_message = "Can not send a request to https://huggingface.co" | |
| return False | |
| def build_space(space_names: str, hf_token: str, target_space_name: str, space_description: str) -> str: | |
| """ | |
| Creates a space with given inputs | |
| :param space_names: | |
| :param hf_token: | |
| :param target_space_name: | |
| :param space_description: | |
| :return: | |
| """ | |
| if space_names == "" or hf_token == "" or target_space_name == "" or space_description == "": | |
| return "Please fill all the inputs" | |
| if SpaceBuilder.check_space_name_availability(hf_token=hf_token, space_name=target_space_name): | |
| print("The space name is available") | |
| if SpaceBuilder.load_and_check_spaces(names=space_names): | |
| print("Loaded and checked input spaces") | |
| if SpaceBuilder.create_space(names=space_names, space_name=target_space_name, hf_token=hf_token): | |
| return SpaceBuilder.url | |
| else: | |
| return SpaceBuilder.error_message | |
| else: | |
| return SpaceBuilder.error_message | |
| else: | |
| return SpaceBuilder.error_message | |
| iface = gr.Interface( | |
| fn=SpaceBuilder.build_space, | |
| inputs=[ | |
| gr.inputs.Textbox( | |
| lines=4, | |
| placeholder=( | |
| f"Drop space links at each line, ie:" | |
| f"\nspaces/Norod78/ComicsHeroHD" | |
| f"\nspaces/Amrrs/gradio-sentiment-analyzer" | |
| ), | |
| ), | |
| gr.inputs.Textbox(lines=1, placeholder="HuggingFace Write Token"), | |
| gr.inputs.Textbox(lines=1, placeholder="Name for the space"), | |
| gr.inputs.Textbox(lines=1, placeholder="Description for the space"), | |
| ], | |
| outputs="text", | |
| ) | |
| iface.launch() | |