import gradio as gr import tempfile import os from git import Repo from huggingface_hub import HfApi, create_repo, upload_folder from huggingface_hub.utils import HfHubHTTPError api = HfApi() def process(git_repo_url, space_destination, user_token, space_sdk): your_username = api.whoami(token=user_token)["name"] # Check if space ID is correct including username if f"{your_username}/" in str(space_destination): print("username is present: good to continue") else: space_destination = f"{your_username}/{space_destination}" print(f"user forgot to mention a username in space_destination: {space_destination}") # Create a temporary directory to clone the repository tmp_dir = tempfile.mkdtemp() # Clone the Hugging Face Spaces repository repo = Repo.clone_from(git_repo_url, tmp_dir) # Check if README.md already exists in tmp_dir readme_path = os.path.join(tmp_dir, "README.md") original_readme_path = os.path.join(tmp_dir, "ORIGINAL_README.md") # Rename the existing README.md if it exists if os.path.exists(readme_path): print("Existing README.md found, renaming to ORIGINAL_README.md") os.rename(readme_path, original_readme_path) # Log the contents of the tmp_dir with its subfolders print("Contents of the cloned repository:") for root, dirs, files in os.walk(tmp_dir): level = root.replace(tmp_dir, '').count(os.sep) indent = ' ' * 4 * level print(f"{indent}{os.path.basename(root)}/") sub_indent = ' ' * 4 * (level + 1) for f in files: print(f"{sub_indent}{f}") try: api.upload_folder( folder_path=tmp_dir, repo_id=space_destination, repo_type="space", token=user_token ) return f"Repository cloned ! Find it at hf.co/spaces/{space_destination}" except HfHubHTTPError as e: # Check if the error is a "Repository Not Found" error if "404 Client Error" in str(e) and "Repository Not Found" in str(e): print("Repository not found. Maybe we should Create the repository...") api.create_repo( repo_id=space_destination, token=user_token, private=True, repo_type="space", space_sdk=space_sdk ) print(f"New space repo created: {space_destination}") api.upload_folder( folder_path=tmp_dir, repo_id=space_destination, repo_type="space", token=user_token, commit_message="Migrated from GitHub", ignore_patterns=[ "*.git*", "*.DS_Store", "*.env", ] ) return f"Repository cloned ! Find it at hf.co/spaces/{space_destination}" else: # Re-raise the exception if it's not a "Repository Not Found" error raise e css = """ div#col-container{ margin: 0 auto; max-width: 720px; } """ with gr.Blocks(css=css) as demo: with gr.Column(elem_id="col-container"): gr.Markdown("# Clone GitHub repo to Space") with gr.Group(): git_repo_url = gr.Textbox( label="Git repo URL to clone", placeholder="https://github.com/username/my-repo.git" ) with gr.Row(): space_destination = gr.Textbox( label="Space ID", placeholder="your_hf_username/space_name" ) user_token = gr.Textbox( label="WRITE permissions HF token", type="password" ) space_sdk = gr.Radio( label="Space SDK", info="If specified space ID doesn't exist, a new private space will be created. In that case, please choose a SDK", choices=["gradio", "docker", "static"], value="gradio" ) submit_btn = gr.Button("Clone git repo to my space") status = gr.Textbox( label="Status" ) submit_btn.click( fn=process, inputs=[git_repo_url, space_destination, user_token, space_sdk], outputs=[status] ) demo.launch(show_error=True)