gihub_to_spaces / app.py
broadfield-dev's picture
Update app.py
8229763 verified
import gradio as gr
import os
import subprocess
import shutil
from huggingface_hub import HfApi, HfFolder, whoami, create_repo, upload_folder
from huggingface_hub.utils import HfHubHTTPError
# --- Core Logic ---
def create_space_from_github(github_url, new_space_name, hf_token, space_sdk):
if not github_url or not new_space_name or not hf_token:
raise gr.Error("All fields are required. Please provide a GitHub URL, a new Space name, and your HF Token.")
# Sanitize the space name
new_space_name = new_space_name.strip().replace(" ", "-")
if not new_space_name:
raise gr.Error("New Space name cannot be empty.")
# Temporary directory for cloning
temp_clone_dir = f"/tmp/{new_space_name}"
try:
# 1. Authenticate with Hugging Face Hub
yield "Step 1/5: Authenticating with Hugging Face..."
api = HfApi(token=hf_token)
user = whoami(token=hf_token)
username = user['name']
repo_id = f"{username}/{new_space_name}"
# 2. Create the new, empty Hugging Face Space
yield f"Step 2/5: Creating new Space repository: {repo_id}..."
try:
space_url = create_repo(
repo_id=repo_id,
repo_type="space",
space_sdk=space_sdk.lower(),
token=hf_token,
exist_ok=False # Fail if it already exists
).url
except HfHubHTTPError as e:
if "exists" in str(e):
raise gr.Error(f"Space '{repo_id}' already exists on the Hub. Please choose a different name.")
else:
raise gr.Error(f"Error creating repository: {e}")
# 3. Clone the GitHub repository
yield f"Step 3/5: Cloning GitHub repo from {github_url}..."
if os.path.exists(temp_clone_dir):
shutil.rmtree(temp_clone_dir)
# Use subprocess to run git clone
subprocess.run(
["git", "clone", github_url, temp_clone_dir],
check=True,
capture_output=True # Capture stdout/stderr
)
# Remove the .git directory from the clone to avoid nested repos
git_dir = os.path.join(temp_clone_dir, ".git")
if os.path.exists(git_dir):
shutil.rmtree(git_dir)
# 4. Upload the contents to the new Space
yield f"Step 4/5: Uploading files to {repo_id}..."
upload_folder(
folder_path=temp_clone_dir,
repo_id=repo_id,
repo_type="space",
token=hf_token,
commit_message="Initial import from GitHub"
)
# 5. Cleanup
yield "Step 5/5: Cleaning up temporary files..."
shutil.rmtree(temp_clone_dir)
success_message = f"""
## βœ… Success!
Your new Space has been created.
**[Click here to visit your new Space]({space_url})**
Please note that it might take a few minutes for the Space to build and become fully operational.
"""
yield success_message
except subprocess.CalledProcessError as e:
error_msg = f"Error cloning GitHub repo. Is the URL correct and the repository public?\nDetails: {e.stderr.decode()}"
raise gr.Error(error_msg)
except Exception as e:
# Cleanup on failure
if os.path.exists(temp_clone_dir):
shutil.rmtree(temp_clone_dir)
raise gr.Error(f"An unexpected error occurred: {str(e)}")
# --- Gradio UI ---
with gr.Blocks(theme=gr.themes.Soft(), css="footer {display: none !important;}") as demo:
gr.Markdown(
"""
# GitHub Repo to Hugging Face Space Creator πŸš€
Turn any public GitHub repository into a Hugging Face Space with just a few clicks.
"""
)
with gr.Row():
with gr.Column(scale=2):
gr.Markdown(
"""
### **Step 1: Get a Hugging Face Token**
You need a token with **`write`** permission to create a Space on your behalf.
1. Go to **[Settings β†’ Access Tokens](https://huggingface.co/settings/tokens)**.
2. Create a `New token` with the `write` role.
3. Copy the token and paste it below. **Treat this token like a password!**
"""
)
#with gr.Column(scale=1):
# gr.Image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/hub/security-tokens-write.png", show_label=False, interactive=False)
with gr.Group():
github_url = gr.Textbox(
label="GitHub Repository URL",
placeholder="e.g., https://github.com/gradio-app/gradio"
)
new_space_name = gr.Textbox(
label="New Hugging Face Space Name",
placeholder="e.g., my-cool-gradio-app"
)
hf_token = gr.Textbox(
label="Hugging Face Write Token",
placeholder="hf_...",
type="password"
)
space_sdk = gr.Radio(
["Gradio", "Streamlit", "Static", "Docker"],
label="Select the Space SDK",
value="Gradio",
info="Choose the SDK that matches the repo. If you're unsure, check the repo for app.py (Gradio/Streamlit), index.html (Static), or a Dockerfile."
)
create_button = gr.Button("Create Space ✨", variant="primary")
output_status = gr.Markdown(value="Awaiting input...")
create_button.click(
fn=create_space_from_github,
inputs=[github_url, new_space_name, hf_token, space_sdk],
outputs=[output_status]
)
gr.Markdown("Created by [Your Name/Handle](https://huggingface.co/Your-Handle) | This Space is stateless and does not store your token.")
# Launch the app
demo.launch()