multimodalart HF Staff commited on
Commit
02d2af6
·
verified ·
1 Parent(s): eaaa625

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +175 -0
app.py ADDED
@@ -0,0 +1,175 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import re
3
+ import gradio as gr
4
+ from huggingface_hub import InferenceClient, HfApi, CommitOperationAdd
5
+
6
+ # 1. Load Environment Token
7
+ HF_TOKEN = os.environ.get("HF_TOKEN")
8
+
9
+ if not HF_TOKEN:
10
+ raise ValueError("HF_TOKEN environment variable is not set. Please add it to your Space settings.")
11
+
12
+ def load_migration_guide():
13
+ """Loads the migration context from the external txt file."""
14
+ try:
15
+ with open("migration_guide.txt", "r", encoding="utf-8") as f:
16
+ return f.read()
17
+ except FileNotFoundError:
18
+ return "Error: migration_guide.txt not found. Please ensure it is in the same directory."
19
+
20
+ def extract_code_block(text: str) -> str:
21
+ """Extracts python code from LLM markdown response."""
22
+ pattern = r"```python\s*(.*?)\s*```"
23
+ match = re.search(pattern, text, re.DOTALL)
24
+ if match:
25
+ return match.group(1)
26
+
27
+ # Fallback: if the model just returned code without blocks
28
+ if "import gradio" in text:
29
+ return text
30
+
31
+ return ""
32
+
33
+ def migrate_app(space_url):
34
+ """
35
+ 1. Fetches Space metadata and code using Env Token.
36
+ 2. Sends code + migration guide to LLM.
37
+ 3. Creates a PR on the Space.
38
+ """
39
+ if not space_url:
40
+ raise gr.Error("Please enter a Space URL.")
41
+
42
+ # Setup Clients using the Environment Token
43
+ api = HfApi(token=HF_TOKEN)
44
+ client = InferenceClient(api_key=HF_TOKEN)
45
+
46
+ # Verify Auth
47
+ try:
48
+ user = api.whoami()
49
+ print(f"Authenticated as {user['name']}")
50
+ except Exception as e:
51
+ raise gr.Error(f"Authentication failed using HF_TOKEN: {str(e)}")
52
+
53
+ # Parse Space ID
54
+ space_id = space_url.replace("https://huggingface.co/spaces/", "").strip("/")
55
+
56
+ try:
57
+ # Get README to update SDK version and find app file
58
+ readme_path = api.hf_hub_download(repo_id=space_id, filename="README.md", repo_type="space")
59
+ with open(readme_path, "r", encoding="utf-8") as f:
60
+ readme_content = f.read()
61
+
62
+ # Determine python file name (default to app.py)
63
+ app_file_match = re.search(r"app_file:\s*(.*)", readme_content)
64
+ app_file_name = app_file_match.group(1).strip() if app_file_match else "app.py"
65
+
66
+ # Get Python Code
67
+ code_path = api.hf_hub_download(repo_id=space_id, filename=app_file_name, repo_type="space")
68
+ with open(code_path, "r", encoding="utf-8") as f:
69
+ original_code = f.read()
70
+
71
+ except Exception as e:
72
+ raise gr.Error(f"Error fetching files from {space_id}: {str(e)}")
73
+
74
+ # Prepare Prompt
75
+ migration_guide = load_migration_guide()
76
+
77
+ system_prompt = (
78
+ "You are an expert Python developer specializing in Gradio. "
79
+ "Your task is to strictly migrate a Gradio 5.x application to Gradio 6.x based on the provided guide.\n\n"
80
+ "### MIGRATION GUIDE ###\n"
81
+ f"{migration_guide}\n\n"
82
+ "### INSTRUCTIONS ###\n"
83
+ "1. Analyze the user's code.\n"
84
+ "2. Apply ALL necessary changes according to the guide (e.g., Blocks parameters, Chatbot tuples to messages, Video return types, API visibility).\n"
85
+ "3. Output ONLY the complete, runnable Python code inside a ```python markdown block.\n"
86
+ "4. Do not include conversational text, only the code."
87
+ )
88
+
89
+ messages = [
90
+ {"role": "system", "content": system_prompt},
91
+ {"role": "user", "content": f"Migrate this code to Gradio 6:\n\n```python\n{original_code}\n```"}
92
+ ]
93
+
94
+ # Call Moonshot Model
95
+ gr.Info(f"Analysing {app_file_name} with moonshotai/Kimi-K2-Thinking...")
96
+
97
+ try:
98
+ completion = client.chat.completions.create(
99
+ model="moonshotai/Kimi-K2-Thinking:novita",
100
+ messages=messages,
101
+ temperature=0.1,
102
+ max_tokens=8000,
103
+ )
104
+ llm_response = completion.choices[0].message.content
105
+ migrated_code = extract_code_block(llm_response)
106
+
107
+ if not migrated_code:
108
+ raise ValueError("LLM failed to generate valid Python code block.")
109
+
110
+ except Exception as e:
111
+ raise gr.Error(f"LLM Processing failed: {str(e)}")
112
+
113
+ # Prepare Commit
114
+ # Update SDK version in README to 6.0.0
115
+ new_readme_content = re.sub(
116
+ r"sdk_version:.*",
117
+ "sdk_version: 6.0.0",
118
+ readme_content
119
+ )
120
+
121
+ operations = [
122
+ CommitOperationAdd(path_in_repo="README.md", path_or_fileobj=new_readme_content.encode('utf-8')),
123
+ CommitOperationAdd(path_in_repo=app_file_name, path_or_fileobj=migrated_code.encode('utf-8')),
124
+ ]
125
+
126
+ pr_title = "[AUTOMATED] Migration to Gradio 6.0"
127
+ pr_description = (
128
+ "This PR migrates the Space to Gradio 6.0.\n\n"
129
+ "### Changes\n"
130
+ "- `README.md`: Updated `sdk_version` to `6.0.0`\n"
131
+ f"- `{app_file_name}`: Automated refactoring using `moonshotai/Kimi-K2-Thinking` based on the migration guide."
132
+ )
133
+
134
+ # Create PR
135
+ try:
136
+ commit_info = api.create_commit(
137
+ repo_id=space_id,
138
+ operations=operations,
139
+ commit_message=pr_title,
140
+ commit_description=pr_description,
141
+ repo_type="space",
142
+ create_pr=True
143
+ )
144
+ return f"## ✅ Success!\n\nPull Request created: [**{commit_info.pr_url}**]({commit_info.pr_url})"
145
+ except Exception as e:
146
+ raise gr.Error(f"Failed to create Pull Request: {str(e)}")
147
+
148
+ # --- UI ---
149
+ with gr.Blocks(title="Gradio 6 Auto-Migrator") as demo:
150
+ gr.Markdown("# 🚀 Gradio 6 Auto-Migrator")
151
+ gr.Markdown(
152
+ "Enter a Hugging Face Space URL below. This tool will:\n"
153
+ "1. Fetch your code.\n"
154
+ "2. Use **Kimi-K2-Thinking** to refactor it based on the Official Gradio 6 Migration Guide.\n"
155
+ "3. Open a Pull Request on your Space automatically."
156
+ )
157
+
158
+ with gr.Row():
159
+ space_input = gr.Textbox(
160
+ label="Space URL or ID",
161
+ placeholder="username/space-name",
162
+ scale=4
163
+ )
164
+ btn = gr.Button("Migrate Space", variant="primary", scale=1)
165
+
166
+ output_md = gr.Markdown(label="Status")
167
+
168
+ btn.click(
169
+ fn=migrate_app,
170
+ inputs=[space_input],
171
+ outputs=output_md
172
+ )
173
+
174
+ if __name__ == "__main__":
175
+ demo.launch()