akhaliq HF Staff commited on
Commit
2872dcd
Β·
1 Parent(s): 170b952

update to add deploy

Browse files
Files changed (2) hide show
  1. README.md +54 -0
  2. app.py +291 -5
README.md CHANGED
@@ -9,6 +9,9 @@ app_file: app.py
9
  pinned: false
10
  disable_embedding: true
11
  hf_oauth: true
 
 
 
12
  ---
13
 
14
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
@@ -27,6 +30,7 @@ AnyCoder is an AI-powered code generator that helps you create applications by d
27
  - **Web Search Integration**: Enable real-time web search to get the latest information and best practices
28
  - **Chat History**: Keep track of your conversations and generated code
29
  - **Quick Examples**: Pre-built examples to get you started quickly
 
30
 
31
  ## Installation
32
 
@@ -67,6 +71,56 @@ python app.py
67
 
68
  6. View the generated code in the Code Editor tab or see it in action in the Live Preview tab
69
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
  ## Web Search Feature
71
 
72
  The web search feature uses Tavily to provide real-time information when generating code. To enable this feature:
 
9
  pinned: false
10
  disable_embedding: true
11
  hf_oauth: true
12
+ hf_oauth_scopes:
13
+ - read
14
+ - write
15
  ---
16
 
17
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
30
  - **Web Search Integration**: Enable real-time web search to get the latest information and best practices
31
  - **Chat History**: Keep track of your conversations and generated code
32
  - **Quick Examples**: Pre-built examples to get you started quickly
33
+ - **πŸš€ One-Click Deployment**: Deploy your generated applications directly to Hugging Face Spaces
34
 
35
  ## Installation
36
 
 
71
 
72
  6. View the generated code in the Code Editor tab or see it in action in the Live Preview tab
73
 
74
+ 7. **Deploy to Space**: Enter a title and click "πŸš€ Deploy to Space" to publish your application
75
+
76
+ ## πŸš€ Deployment Feature
77
+
78
+ AnyCoder now includes one-click deployment to Hugging Face Spaces! This feature allows you to:
79
+
80
+ ### How to Deploy
81
+
82
+ 1. **Login**: Click the "Sign in with Hugging Face" button in the sidebar and authorize with your Hugging Face account
83
+ 2. **Generate Code**: Generate some HTML code using the AI
84
+ 3. **Enter Title**: In the sidebar, enter a title for your space (e.g., "My Todo App")
85
+ 4. **Deploy**: Click the "πŸš€ Deploy to Space" button
86
+ 5. **Share**: Get a shareable URL for your deployed application
87
+
88
+ **Note**: You need to be logged in with your Hugging Face account to deploy. This ensures that:
89
+ - Deployments are created under your own account namespace
90
+ - You can manage and update your spaces from your Hugging Face dashboard
91
+ - Each deployment gets a unique URL under your username
92
+
93
+ **Technical Note**: The deployment uses your personal OAuth token to create spaces under your account, ensuring full security and ownership of your deployed applications.
94
+
95
+ ### What Gets Deployed
96
+
97
+ - **Complete HTML Application**: Your generated code wrapped in a professional template
98
+ - **Responsive Design**: Mobile-friendly layout with modern styling
99
+ - **Project Documentation**: README with project details and prompts used
100
+ - **Live URL**: Publicly accessible URL that anyone can visit
101
+
102
+ ### Deployment Benefits
103
+
104
+ - **Instant Publishing**: No need to set up hosting or domains
105
+ - **Shareable**: Get a public URL to share with others
106
+ - **Professional**: Clean, branded presentation of your work
107
+ - **Version Control**: Each deployment creates a new space with timestamp
108
+ - **Free Hosting**: Hosted on Hugging Face's infrastructure
109
+
110
+ ### Example Deployment
111
+
112
+ ```
113
+ Title: "My Weather Dashboard"
114
+ Generated Code: <div>Weather app HTML...</div>
115
+ Result: https://huggingface.co/spaces/my-weather-dashboard-1234567890
116
+ ```
117
+
118
+ The deployed space will include:
119
+ - Your application with professional styling
120
+ - A header with your title and AnyCoder branding
121
+ - A footer with attribution
122
+ - A README documenting the project
123
+
124
  ## Web Search Feature
125
 
126
  The web search feature uses Tavily to provide real-time information when generating code. To enable this feature:
app.py CHANGED
@@ -14,9 +14,11 @@ import requests
14
  from urllib.parse import urlparse, urljoin
15
  from bs4 import BeautifulSoup
16
  import html2text
 
 
17
 
18
  import gradio as gr
19
- from huggingface_hub import InferenceClient
20
  from tavily import TavilyClient
21
 
22
  # Configuration
@@ -159,13 +161,20 @@ DEMO_LIST = [
159
  ]
160
 
161
  # HF Inference Client
162
- YOUR_API_TOKEN = os.getenv('HF_TOKEN')
163
  client = InferenceClient(
164
  provider="auto",
165
- api_key=YOUR_API_TOKEN,
166
  bill_to="huggingface"
167
  )
168
 
 
 
 
 
 
 
 
169
  # Tavily Search Client
170
  TAVILY_API_KEY = os.getenv('TAVILY_API_KEY')
171
  tavily_client = None
@@ -176,8 +185,240 @@ if TAVILY_API_KEY:
176
  print(f"Failed to initialize Tavily client: {e}")
177
  tavily_client = None
178
 
179
- History = List[Tuple[str, str]]
180
- Messages = List[Dict[str, str]]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
181
 
182
  def history_to_messages(history: History, system: str) -> Messages:
183
  messages = [{'role': 'system', 'content': system}]
@@ -907,6 +1148,14 @@ with gr.Blocks(
907
  gr.Markdown("# AnyCoder")
908
  gr.Markdown("*AI-Powered Code Generator*")
909
 
 
 
 
 
 
 
 
 
910
  # Main input section
911
  input = gr.Textbox(
912
  label="What would you like to build?",
@@ -953,6 +1202,30 @@ with gr.Blocks(
953
  label="Model"
954
  )
955
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
956
  # Quick examples (minimal)
957
  gr.Markdown("**Quick start**")
958
  with gr.Column():
@@ -1012,6 +1285,11 @@ with gr.Blocks(
1012
  )
1013
  with gr.Tab("Preview"):
1014
  sandbox = gr.HTML(label="Live preview")
 
 
 
 
 
1015
  with gr.Tab("History"):
1016
  history_output = gr.Chatbot(show_label=False, height=400, type="messages")
1017
 
@@ -1023,6 +1301,14 @@ with gr.Blocks(
1023
  outputs=[code_output, history, sandbox, history_output]
1024
  )
1025
  clear_btn.click(clear_history, outputs=[history, history_output, file_input, website_url_input])
 
 
 
 
 
 
 
 
1026
 
1027
  if __name__ == "__main__":
1028
  demo.queue(default_concurrency_limit=20).launch(ssr_mode=True, mcp_server=True)
 
14
  from urllib.parse import urlparse, urljoin
15
  from bs4 import BeautifulSoup
16
  import html2text
17
+ import json
18
+ import time
19
 
20
  import gradio as gr
21
+ from huggingface_hub import InferenceClient, HfApi, create_repo
22
  from tavily import TavilyClient
23
 
24
  # Configuration
 
161
  ]
162
 
163
  # HF Inference Client
164
+ HF_TOKEN = os.getenv('HF_TOKEN')
165
  client = InferenceClient(
166
  provider="auto",
167
+ api_key=HF_TOKEN,
168
  bill_to="huggingface"
169
  )
170
 
171
+ # Type definitions
172
+ History = List[Tuple[str, str]]
173
+ Messages = List[Dict[str, str]]
174
+
175
+ # HF API Client for deployment
176
+ hf_api = HfApi(token=HF_TOKEN)
177
+
178
  # Tavily Search Client
179
  TAVILY_API_KEY = os.getenv('TAVILY_API_KEY')
180
  tavily_client = None
 
185
  print(f"Failed to initialize Tavily client: {e}")
186
  tavily_client = None
187
 
188
+ # Deployment functions
189
+ def create_space_from_html(title: str, html_content: str, prompts: List[str] = None, user_token: str = None, username: str = None) -> Dict:
190
+ """
191
+ Create a Hugging Face Space from generated HTML content
192
+ """
193
+ try:
194
+ # Use user token if provided, otherwise fall back to server token
195
+ api_token = user_token if user_token else HF_TOKEN
196
+
197
+ if not api_token:
198
+ return {
199
+ "success": False,
200
+ "error": "No Hugging Face token available",
201
+ "message": "Please log in with your Hugging Face account to deploy"
202
+ }
203
+
204
+ # Create API client with user token
205
+ user_hf_api = HfApi(token=api_token)
206
+
207
+ # Get the current user's username if not provided
208
+ if not username:
209
+ try:
210
+ user_info = user_hf_api.whoami()
211
+ username = user_info.get('name', 'user')
212
+ except Exception as e:
213
+ print(f"Could not get user info: {e}")
214
+ return {
215
+ "success": False,
216
+ "error": "Invalid or expired token",
217
+ "message": "Please check your Hugging Face token"
218
+ }
219
+
220
+ # Clean the title for use as repo name
221
+ clean_title = re.sub(r'[^a-zA-Z0-9_-]', '-', title.lower())
222
+ clean_title = re.sub(r'-+', '-', clean_title).strip('-')
223
+
224
+ # Add timestamp to ensure uniqueness
225
+ timestamp = int(time.time())
226
+ repo_name = f"{username}/{clean_title}-{timestamp}"
227
+
228
+ # Create the space
229
+ repo_url = user_hf_api.create_repo(
230
+ repo_id=repo_name,
231
+ repo_type="space",
232
+ space_sdk="static",
233
+ private=False,
234
+ exist_ok=False
235
+ )
236
+
237
+ # Prepare the HTML content with proper structure
238
+ full_html = f"""<!DOCTYPE html>
239
+ <html lang="en">
240
+ <head>
241
+ <meta charset="UTF-8">
242
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
243
+ <title>{title}</title>
244
+ <style>
245
+ body {{
246
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
247
+ margin: 0;
248
+ padding: 20px;
249
+ background-color: #f5f5f5;
250
+ }}
251
+ .container {{
252
+ max-width: 1200px;
253
+ margin: 0 auto;
254
+ background: white;
255
+ padding: 20px;
256
+ border-radius: 8px;
257
+ box-shadow: 0 2px 10px rgba(0,0,0,0.1);
258
+ }}
259
+ .header {{
260
+ text-align: center;
261
+ margin-bottom: 30px;
262
+ padding-bottom: 20px;
263
+ border-bottom: 2px solid #f0f0f0;
264
+ }}
265
+ .header h1 {{
266
+ color: #333;
267
+ margin: 0;
268
+ }}
269
+ .header p {{
270
+ color: #666;
271
+ margin: 10px 0 0 0;
272
+ }}
273
+ .content {{
274
+ line-height: 1.6;
275
+ }}
276
+ .footer {{
277
+ margin-top: 40px;
278
+ padding-top: 20px;
279
+ border-top: 1px solid #f0f0f0;
280
+ text-align: center;
281
+ color: #666;
282
+ font-size: 14px;
283
+ }}
284
+ </style>
285
+ </head>
286
+ <body>
287
+ <div class="container">
288
+ <div class="header">
289
+ <h1>{title}</h1>
290
+ <p>Generated with AnyCoder - AI Code Generator</p>
291
+ </div>
292
+ <div class="content">
293
+ {html_content}
294
+ </div>
295
+ <div class="footer">
296
+ <p>Created with ❀️ using AnyCoder</p>
297
+ </div>
298
+ </div>
299
+ </body>
300
+ </html>"""
301
+
302
+ # Upload the HTML file
303
+ user_hf_api.upload_file(
304
+ path_or_fileobj=full_html.encode('utf-8'),
305
+ path_in_repo="index.html",
306
+ repo_id=repo_name,
307
+ repo_type="space"
308
+ )
309
+
310
+ # Create README.md with project info
311
+ readme_content = f"""# {title}
312
+
313
+ This project was generated using [AnyCoder](https://huggingface.co/spaces/ahsenkhaliq/anycoder), an AI-powered code generator.
314
+
315
+ ## About
316
+
317
+ This is a static HTML application created by describing the requirements in plain English to an AI model.
318
+
319
+ ## Generated Prompts
320
+
321
+ {f"".join([f"- {prompt}\n" for prompt in (prompts or [])])}
322
+
323
+ ## View Live
324
+
325
+ Visit: https://huggingface.co/spaces/{repo_name}
326
+
327
+ ---
328
+ *Generated with ❀️ using AnyCoder*
329
+ """
330
+
331
+ user_hf_api.upload_file(
332
+ path_or_fileobj=readme_content.encode('utf-8'),
333
+ path_in_repo="README.md",
334
+ repo_id=repo_name,
335
+ repo_type="space"
336
+ )
337
+
338
+ return {
339
+ "success": True,
340
+ "space_url": f"https://huggingface.co/spaces/{repo_name}",
341
+ "repo_name": repo_name,
342
+ "message": f"Successfully created space: {title}"
343
+ }
344
+
345
+ except Exception as e:
346
+ return {
347
+ "success": False,
348
+ "error": str(e),
349
+ "message": f"Failed to create space: {str(e)}"
350
+ }
351
+
352
+ def deploy_to_space(title: str, html_content: str, history: History, oauth_profile: gr.OAuthProfile = None, oauth_token: gr.OAuthToken = None) -> str:
353
+ """
354
+ Deploy the generated HTML to a Hugging Face Space
355
+ """
356
+ if not title or not title.strip():
357
+ return "❌ Please enter a title for your space."
358
+
359
+ if not html_content or not html_content.strip():
360
+ return "❌ No HTML content to deploy. Please generate some code first."
361
+
362
+ # Check if user is authenticated
363
+ if not oauth_profile or not oauth_token:
364
+ return """❌ **Authentication Required**
365
+
366
+ To deploy your application, you need to be logged in with your Hugging Face account.
367
+
368
+ **How to log in:**
369
+ 1. Click the "Sign in with Hugging Face" button in the sidebar
370
+ 2. Authorize AnyCoder to access your Hugging Face account
371
+ 3. Try deploying again
372
+
373
+ **Why login is required:**
374
+ - Deployments are created under your own Hugging Face account
375
+ - You need write permissions to create spaces
376
+ - This ensures you own and can manage your deployed applications
377
+
378
+ ---
379
+ *Please log in and try again.*"""
380
+
381
+ # Get user information from OAuth profile
382
+ username = oauth_profile.name
383
+ user_token = oauth_token.token
384
+
385
+ # Extract prompts from history
386
+ prompts = []
387
+ for user_msg, _ in history:
388
+ if isinstance(user_msg, str) and user_msg.strip():
389
+ prompts.append(user_msg.strip())
390
+
391
+ # Use user's OAuth token to create space under their account
392
+ result = create_space_from_html(title.strip(), html_content, prompts, user_token, username)
393
+
394
+ if result["success"]:
395
+ return f"""βœ… **Successfully deployed!**
396
+
397
+ **Space URL:** {result['space_url']}
398
+
399
+ Your application is now live on Hugging Face Spaces under your account. You can share this URL with others to showcase your generated application.
400
+
401
+ **What's next:**
402
+ - Visit the space to see your application in action
403
+ - Share the URL with friends and colleagues
404
+ - Make modifications and redeploy as needed
405
+ - Manage your space from your Hugging Face dashboard
406
+
407
+ ---
408
+ *Generated with ❀️ using AnyCoder*"""
409
+ else:
410
+ return f"""❌ **Deployment failed**
411
+
412
+ **Error:** {result['error']}
413
+
414
+ **Possible solutions:**
415
+ - Ensure you have write access to create spaces on your account
416
+ - Try a different title (avoid special characters)
417
+ - Check your internet connection
418
+ - Make sure your Hugging Face account has the necessary permissions
419
+
420
+ ---
421
+ *Please try again or contact support if the issue persists.*"""
422
 
423
  def history_to_messages(history: History, system: str) -> Messages:
424
  messages = [{'role': 'system', 'content': system}]
 
1148
  gr.Markdown("# AnyCoder")
1149
  gr.Markdown("*AI-Powered Code Generator*")
1150
 
1151
+ # Login button at the top
1152
+ login_btn = gr.LoginButton(
1153
+ value="Sign in with Hugging Face",
1154
+ logout_value="Logout ({})",
1155
+ variant="huggingface",
1156
+ size="sm"
1157
+ )
1158
+
1159
  # Main input section
1160
  input = gr.Textbox(
1161
  label="What would you like to build?",
 
1202
  label="Model"
1203
  )
1204
 
1205
+ # Deployment section
1206
+ gr.Markdown("---")
1207
+ gr.Markdown("**πŸš€ Deploy to Space**")
1208
+
1209
+ # Space title input
1210
+ space_title_input = gr.Textbox(
1211
+ label="Space title",
1212
+ placeholder="My Awesome App",
1213
+ lines=1
1214
+ )
1215
+
1216
+ # Deploy button
1217
+ deploy_btn = gr.Button(
1218
+ "πŸš€ Deploy to Space",
1219
+ variant="primary",
1220
+ size="lg"
1221
+ )
1222
+
1223
+ # Deployment status
1224
+ deploy_status = gr.Markdown(
1225
+ value="",
1226
+ visible=False
1227
+ )
1228
+
1229
  # Quick examples (minimal)
1230
  gr.Markdown("**Quick start**")
1231
  with gr.Column():
 
1285
  )
1286
  with gr.Tab("Preview"):
1287
  sandbox = gr.HTML(label="Live preview")
1288
+ with gr.Tab("Deploy"):
1289
+ deploy_output = gr.Markdown(
1290
+ value="## πŸš€ Deploy Your Application\n\n1. Generate some code first\n2. Enter a title for your space\n3. Click 'Deploy to Space' in the sidebar\n\nYour application will be deployed to Hugging Face Spaces and you'll get a shareable URL!",
1291
+ label="Deployment Status"
1292
+ )
1293
  with gr.Tab("History"):
1294
  history_output = gr.Chatbot(show_label=False, height=400, type="messages")
1295
 
 
1301
  outputs=[code_output, history, sandbox, history_output]
1302
  )
1303
  clear_btn.click(clear_history, outputs=[history, history_output, file_input, website_url_input])
1304
+
1305
+ # Deployment event handler
1306
+ deploy_btn.click(
1307
+ deploy_to_space,
1308
+ inputs=[space_title_input, code_output, history],
1309
+ outputs=[deploy_output],
1310
+ api_name="deploy"
1311
+ )
1312
 
1313
  if __name__ == "__main__":
1314
  demo.queue(default_concurrency_limit=20).launch(ssr_mode=True, mcp_server=True)