broadfield-dev commited on
Commit
d13391d
Β·
verified Β·
1 Parent(s): 49d7f09

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +155 -0
app.py ADDED
@@ -0,0 +1,155 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import os
3
+ import subprocess
4
+ import shutil
5
+ from huggingface_hub import HfApi, HfFolder, whoami, create_repo, upload_folder
6
+ from huggingface_hub.utils import HfHubHTTPError
7
+
8
+ # --- Core Logic ---
9
+
10
+ def create_space_from_github(github_url, new_space_name, hf_token, space_sdk):
11
+ if not github_url or not new_space_name or not hf_token:
12
+ raise gr.Error("All fields are required. Please provide a GitHub URL, a new Space name, and your HF Token.")
13
+
14
+ # Sanitize the space name
15
+ new_space_name = new_space_name.strip().replace(" ", "-")
16
+ if not new_space_name:
17
+ raise gr.Error("New Space name cannot be empty.")
18
+
19
+ # Temporary directory for cloning
20
+ temp_clone_dir = f"/tmp/{new_space_name}"
21
+
22
+ try:
23
+ # 1. Authenticate with Hugging Face Hub
24
+ yield "Step 1/5: Authenticating with Hugging Face..."
25
+ api = HfApi(token=hf_token)
26
+ user = whoami(token=hf_token)
27
+ username = user['name']
28
+ repo_id = f"{username}/{new_space_name}"
29
+
30
+ # 2. Create the new, empty Hugging Face Space
31
+ yield f"Step 2/5: Creating new Space repository: {repo_id}..."
32
+ try:
33
+ space_url = create_repo(
34
+ repo_id=repo_id,
35
+ repo_type="space",
36
+ space_sdk=space_sdk.lower(),
37
+ token=hf_token,
38
+ exist_ok=False # Fail if it already exists
39
+ ).url
40
+ except HfHubHTTPError as e:
41
+ if "exists" in str(e):
42
+ raise gr.Error(f"Space '{repo_id}' already exists on the Hub. Please choose a different name.")
43
+ else:
44
+ raise gr.Error(f"Error creating repository: {e}")
45
+
46
+ # 3. Clone the GitHub repository
47
+ yield f"Step 3/5: Cloning GitHub repo from {github_url}..."
48
+ if os.path.exists(temp_clone_dir):
49
+ shutil.rmtree(temp_clone_dir)
50
+
51
+ # Use subprocess to run git clone
52
+ subprocess.run(
53
+ ["git", "clone", github_url, temp_clone_dir],
54
+ check=True,
55
+ capture_output=True # Capture stdout/stderr
56
+ )
57
+
58
+ # Remove the .git directory from the clone to avoid nested repos
59
+ git_dir = os.path.join(temp_clone_dir, ".git")
60
+ if os.path.exists(git_dir):
61
+ shutil.rmtree(git_dir)
62
+
63
+ # 4. Upload the contents to the new Space
64
+ yield f"Step 4/5: Uploading files to {repo_id}..."
65
+ upload_folder(
66
+ folder_path=temp_clone_dir,
67
+ repo_id=repo_id,
68
+ repo_type="space",
69
+ token=hf_token,
70
+ commit_message="Initial import from GitHub"
71
+ )
72
+
73
+ # 5. Cleanup
74
+ yield "Step 5/5: Cleaning up temporary files..."
75
+ shutil.rmtree(temp_clone_dir)
76
+
77
+ success_message = f"""
78
+ ## βœ… Success!
79
+
80
+ Your new Space has been created.
81
+
82
+ **[Click here to visit your new Space]({space_url})**
83
+
84
+ Please note that it might take a few minutes for the Space to build and become fully operational.
85
+ """
86
+ yield success_message
87
+
88
+ except subprocess.CalledProcessError as e:
89
+ error_msg = f"Error cloning GitHub repo. Is the URL correct and the repository public?\nDetails: {e.stderr.decode()}"
90
+ raise gr.Error(error_msg)
91
+ except Exception as e:
92
+ # Cleanup on failure
93
+ if os.path.exists(temp_clone_dir):
94
+ shutil.rmtree(temp_clone_dir)
95
+ raise gr.Error(f"An unexpected error occurred: {str(e)}")
96
+
97
+
98
+ # --- Gradio UI ---
99
+
100
+ with gr.Blocks(theme=gr.themes.Soft(), css="footer {display: none !important;}") as demo:
101
+ gr.Markdown(
102
+ """
103
+ # GitHub Repo to Hugging Face Space Creator πŸš€
104
+ Turn any public GitHub repository into a Hugging Face Space with just a few clicks.
105
+ """
106
+ )
107
+ with gr.Row():
108
+ with gr.Column(scale=2):
109
+ gr.Markdown(
110
+ """
111
+ ### **Step 1: Get a Hugging Face Token**
112
+ You need a token with **`write`** permission to create a Space on your behalf.
113
+ 1. Go to **[Settings β†’ Access Tokens](https://huggingface.co/settings/tokens)**.
114
+ 2. Create a `New token` with the `write` role.
115
+ 3. Copy the token and paste it below. **Treat this token like a password!**
116
+ """
117
+ )
118
+ with gr.Column(scale=1):
119
+ gr.Image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/hub/security-tokens-write.png", show_label=False, interactive=False)
120
+
121
+ with gr.Group():
122
+ github_url = gr.Textbox(
123
+ label="GitHub Repository URL",
124
+ placeholder="e.g., https://github.com/gradio-app/gradio"
125
+ )
126
+ new_space_name = gr.Textbox(
127
+ label="New Hugging Face Space Name",
128
+ placeholder="e.g., my-cool-gradio-app"
129
+ )
130
+ hf_token = gr.Textbox(
131
+ label="Hugging Face Write Token",
132
+ placeholder="hf_...",
133
+ type="password"
134
+ )
135
+ space_sdk = gr.Radio(
136
+ ["Gradio", "Streamlit", "Static", "Docker"],
137
+ label="Select the Space SDK",
138
+ value="Gradio",
139
+ 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."
140
+ )
141
+
142
+ create_button = gr.Button("Create Space ✨", variant="primary")
143
+
144
+ output_status = gr.Markdown(value="Awaiting input...")
145
+
146
+ create_button.click(
147
+ fn=create_space_from_github,
148
+ inputs=[github_url, new_space_name, hf_token, space_sdk],
149
+ outputs=[output_status]
150
+ )
151
+
152
+ gr.Markdown("Created by [Your Name/Handle](https://huggingface.co/Your-Handle) | This Space is stateless and does not store your token.")
153
+
154
+ # Launch the app
155
+ demo.launch()