Spaces:
Running
Running
update space deploy
Browse files
app.py
CHANGED
@@ -18,7 +18,7 @@ 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
|
@@ -172,9 +172,6 @@ client = InferenceClient(
|
|
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,556 +182,6 @@ if TAVILY_API_KEY:
|
|
185 |
print(f"Failed to initialize Tavily client: {e}")
|
186 |
tavily_client = None
|
187 |
|
188 |
-
def validate_oauth_scopes(oauth_token) -> Tuple[bool, List[str]]:
|
189 |
-
"""
|
190 |
-
Validate that the OAuth token has the required scopes for creating spaces
|
191 |
-
Returns (is_valid, missing_scopes)
|
192 |
-
"""
|
193 |
-
required_scopes = ['read-repos', 'write-repos', 'manage-repos']
|
194 |
-
|
195 |
-
if not oauth_token:
|
196 |
-
return False, required_scopes
|
197 |
-
|
198 |
-
# Try to get scopes from the token object
|
199 |
-
token_scopes = []
|
200 |
-
|
201 |
-
# Check different ways scopes might be stored
|
202 |
-
if hasattr(oauth_token, 'scopes'):
|
203 |
-
token_scopes = oauth_token.scopes
|
204 |
-
elif hasattr(oauth_token, 'scope'):
|
205 |
-
token_scopes = oauth_token.scope.split(' ') if oauth_token.scope else []
|
206 |
-
elif hasattr(oauth_token, 'permissions'):
|
207 |
-
token_scopes = oauth_token.permissions
|
208 |
-
else:
|
209 |
-
# If we can't determine scopes, assume they're missing
|
210 |
-
return False, required_scopes
|
211 |
-
|
212 |
-
# Convert to list if it's a string
|
213 |
-
if isinstance(token_scopes, str):
|
214 |
-
token_scopes = token_scopes.split(' ')
|
215 |
-
|
216 |
-
# Check for required scopes
|
217 |
-
missing_scopes = [scope for scope in required_scopes if scope not in token_scopes]
|
218 |
-
|
219 |
-
return len(missing_scopes) == 0, missing_scopes
|
220 |
-
|
221 |
-
# Deployment functions
|
222 |
-
def create_space_from_html(title: str, html_content: str, prompts: List[str] = None, user_token: str = None, username: str = None) -> Dict:
|
223 |
-
"""
|
224 |
-
Create a Hugging Face Space from generated HTML content
|
225 |
-
"""
|
226 |
-
try:
|
227 |
-
# Use user token if provided, otherwise fall back to server token
|
228 |
-
api_token = user_token if user_token else HF_TOKEN
|
229 |
-
|
230 |
-
if not api_token:
|
231 |
-
return {
|
232 |
-
"success": False,
|
233 |
-
"error": "No Hugging Face token available",
|
234 |
-
"message": "Please log in with your Hugging Face account to deploy"
|
235 |
-
}
|
236 |
-
|
237 |
-
# Create API client with user token
|
238 |
-
user_hf_api = HfApi(token=api_token)
|
239 |
-
|
240 |
-
# Debug: Test the token by getting user info
|
241 |
-
try:
|
242 |
-
user_info = user_hf_api.whoami()
|
243 |
-
print(f"Debug: User info from API: {user_info}")
|
244 |
-
if not username:
|
245 |
-
username = user_info.get('name', 'user')
|
246 |
-
print(f"Debug: Final username: {username}")
|
247 |
-
|
248 |
-
# Additional validation
|
249 |
-
if not username or username == 'user':
|
250 |
-
return {
|
251 |
-
"success": False,
|
252 |
-
"error": "Could not retrieve username from token",
|
253 |
-
"message": "The authentication token is valid but username could not be retrieved. Please try logging in again."
|
254 |
-
}
|
255 |
-
|
256 |
-
except Exception as e:
|
257 |
-
print(f"Debug: Could not get user info: {e}")
|
258 |
-
return {
|
259 |
-
"success": False,
|
260 |
-
"error": f"Invalid or expired token: {str(e)}",
|
261 |
-
"message": "Please check your Hugging Face token and try logging in again"
|
262 |
-
}
|
263 |
-
|
264 |
-
# Clean the title for use as repo name
|
265 |
-
clean_title = re.sub(r'[^a-zA-Z0-9_-]', '-', title.lower())
|
266 |
-
clean_title = re.sub(r'-+', '-', clean_title).strip('-')
|
267 |
-
|
268 |
-
# Add timestamp to ensure uniqueness
|
269 |
-
timestamp = int(time.time())
|
270 |
-
repo_name = f"{username}/{clean_title}-{timestamp}"
|
271 |
-
|
272 |
-
print(f"Debug: Attempting to create space: {repo_name}")
|
273 |
-
print(f"Debug: Using token for user: {username}")
|
274 |
-
|
275 |
-
# Create the space
|
276 |
-
try:
|
277 |
-
print(f"Debug: Creating space with parameters:")
|
278 |
-
print(f" repo_id: {repo_name}")
|
279 |
-
print(f" repo_type: space")
|
280 |
-
print(f" space_sdk: static")
|
281 |
-
print(f" private: False")
|
282 |
-
print(f" exist_ok: False")
|
283 |
-
print(f" token length: {len(api_token) if api_token else 0}")
|
284 |
-
|
285 |
-
repo_url = user_hf_api.create_repo(
|
286 |
-
repo_id=repo_name,
|
287 |
-
repo_type="space",
|
288 |
-
space_sdk="static",
|
289 |
-
private=False,
|
290 |
-
exist_ok=False,
|
291 |
-
token=api_token
|
292 |
-
)
|
293 |
-
print(f"Debug: Successfully created space: {repo_url}")
|
294 |
-
except Exception as e:
|
295 |
-
print(f"Debug: Failed to create space: {e}")
|
296 |
-
print(f"Debug: Exception type: {type(e)}")
|
297 |
-
print(f"Debug: Exception args: {e.args}")
|
298 |
-
raise e
|
299 |
-
|
300 |
-
# Prepare the HTML content with proper structure
|
301 |
-
html_template = """<!DOCTYPE html>
|
302 |
-
<html lang="en">
|
303 |
-
<head>
|
304 |
-
<meta charset="UTF-8">
|
305 |
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
306 |
-
<title>{title}</title>
|
307 |
-
<style>
|
308 |
-
body {{
|
309 |
-
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
310 |
-
margin: 0;
|
311 |
-
padding: 20px;
|
312 |
-
background-color: #f5f5f5;
|
313 |
-
}}
|
314 |
-
.container {{
|
315 |
-
max-width: 1200px;
|
316 |
-
margin: 0 auto;
|
317 |
-
background: white;
|
318 |
-
padding: 20px;
|
319 |
-
border-radius: 8px;
|
320 |
-
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
321 |
-
}}
|
322 |
-
.header {{
|
323 |
-
text-align: center;
|
324 |
-
margin-bottom: 30px;
|
325 |
-
padding-bottom: 20px;
|
326 |
-
border-bottom: 2px solid #f0f0f0;
|
327 |
-
}}
|
328 |
-
.header h1 {{
|
329 |
-
color: #333;
|
330 |
-
margin: 0;
|
331 |
-
}}
|
332 |
-
.header p {{
|
333 |
-
color: #666;
|
334 |
-
margin: 10px 0 0 0;
|
335 |
-
}}
|
336 |
-
.content {{
|
337 |
-
line-height: 1.6;
|
338 |
-
}}
|
339 |
-
.footer {{
|
340 |
-
margin-top: 40px;
|
341 |
-
padding-top: 20px;
|
342 |
-
border-top: 1px solid #f0f0f0;
|
343 |
-
text-align: center;
|
344 |
-
color: #666;
|
345 |
-
font-size: 14px;
|
346 |
-
}}
|
347 |
-
</style>
|
348 |
-
</head>
|
349 |
-
<body>
|
350 |
-
<div class="container">
|
351 |
-
<div class="header">
|
352 |
-
<h1>{title}</h1>
|
353 |
-
<p>Generated with AnyCoder - AI Code Generator</p>
|
354 |
-
</div>
|
355 |
-
<div class="content">
|
356 |
-
{html_content}
|
357 |
-
</div>
|
358 |
-
<div class="footer">
|
359 |
-
<p>Created with β€οΈ using AnyCoder</p>
|
360 |
-
</div>
|
361 |
-
</div>
|
362 |
-
</body>
|
363 |
-
</html>"""
|
364 |
-
|
365 |
-
full_html = html_template.format(title=title, html_content=html_content)
|
366 |
-
|
367 |
-
# Check HTML content size
|
368 |
-
html_size = len(full_html.encode('utf-8'))
|
369 |
-
print(f"Debug: HTML content size: {html_size} bytes")
|
370 |
-
|
371 |
-
if html_size > 1000000: # 1MB limit
|
372 |
-
print(f"Debug: Warning - HTML content is large ({html_size} bytes)")
|
373 |
-
# Truncate if too large
|
374 |
-
if len(html_content) > 500000: # 500KB limit for content
|
375 |
-
html_content = html_content[:500000] + "\n<!-- Content truncated due to size -->"
|
376 |
-
full_html = html_template.format(title=title, html_content=html_content)
|
377 |
-
print(f"Debug: HTML content truncated to {len(full_html.encode('utf-8'))} bytes")
|
378 |
-
|
379 |
-
# Upload the HTML file
|
380 |
-
print(f"Debug: Uploading index.html to {repo_name}")
|
381 |
-
user_hf_api.upload_file(
|
382 |
-
path_or_fileobj=full_html.encode('utf-8'),
|
383 |
-
path_in_repo="index.html",
|
384 |
-
repo_id=repo_name,
|
385 |
-
repo_type="space",
|
386 |
-
token=api_token
|
387 |
-
)
|
388 |
-
print(f"Debug: Successfully uploaded index.html")
|
389 |
-
|
390 |
-
# Create README.md with project info
|
391 |
-
prompts_text = "".join([f"- {prompt}\n" for prompt in (prompts or [])])
|
392 |
-
readme_template = """# {title}
|
393 |
-
|
394 |
-
This project was generated using [AnyCoder](https://huggingface.co/spaces/ahsenkhaliq/anycoder), an AI-powered code generator.
|
395 |
-
|
396 |
-
## About
|
397 |
-
|
398 |
-
This is a static HTML application created by describing the requirements in plain English to an AI model.
|
399 |
-
|
400 |
-
## Generated Prompts
|
401 |
-
|
402 |
-
{prompts_text}
|
403 |
-
|
404 |
-
## View Live
|
405 |
-
|
406 |
-
Visit: https://huggingface.co/spaces/{repo_name}
|
407 |
-
|
408 |
-
---
|
409 |
-
*Generated with β€οΈ using AnyCoder*
|
410 |
-
"""
|
411 |
-
|
412 |
-
readme_content = readme_template.format(title=title, prompts_text=prompts_text, repo_name=repo_name)
|
413 |
-
|
414 |
-
print(f"Debug: Uploading README.md to {repo_name}")
|
415 |
-
user_hf_api.upload_file(
|
416 |
-
path_or_fileobj=readme_content.encode('utf-8'),
|
417 |
-
path_in_repo="README.md",
|
418 |
-
repo_id=repo_name,
|
419 |
-
repo_type="space",
|
420 |
-
token=api_token
|
421 |
-
)
|
422 |
-
print(f"Debug: Successfully uploaded README.md")
|
423 |
-
|
424 |
-
return {
|
425 |
-
"success": True,
|
426 |
-
"space_url": f"https://huggingface.co/spaces/{repo_name}",
|
427 |
-
"repo_name": repo_name,
|
428 |
-
"message": f"Successfully created space: {title}"
|
429 |
-
}
|
430 |
-
|
431 |
-
except Exception as e:
|
432 |
-
error_msg = str(e)
|
433 |
-
|
434 |
-
# Handle specific API errors
|
435 |
-
if "401" in error_msg or "Unauthorized" in error_msg:
|
436 |
-
return {
|
437 |
-
"success": False,
|
438 |
-
"error": "Authentication failed - please log in again",
|
439 |
-
"message": "Your token may have expired. Please log out and log back in."
|
440 |
-
}
|
441 |
-
elif "403" in error_msg or "Forbidden" in error_msg:
|
442 |
-
return {
|
443 |
-
"success": False,
|
444 |
-
"error": "Permission denied - insufficient privileges",
|
445 |
-
"message": "You may not have permission to create spaces. Please check your Hugging Face account settings."
|
446 |
-
}
|
447 |
-
elif "409" in error_msg or "Conflict" in error_msg:
|
448 |
-
return {
|
449 |
-
"success": False,
|
450 |
-
"error": "Repository already exists",
|
451 |
-
"message": "A space with this name already exists. Please try a different title."
|
452 |
-
}
|
453 |
-
elif "422" in error_msg or "Validation" in error_msg:
|
454 |
-
return {
|
455 |
-
"success": False,
|
456 |
-
"error": "Invalid repository name",
|
457 |
-
"message": "The space title contains invalid characters. Please use only letters, numbers, hyphens, and underscores."
|
458 |
-
}
|
459 |
-
else:
|
460 |
-
return {
|
461 |
-
"success": False,
|
462 |
-
"error": error_msg,
|
463 |
-
"message": f"Failed to create space: {error_msg}"
|
464 |
-
}
|
465 |
-
|
466 |
-
def deploy_to_space(title: str, html_content: str, history: History, oauth_profile: gr.OAuthProfile = None, oauth_token: gr.OAuthToken = None) -> Tuple[str, str]:
|
467 |
-
"""
|
468 |
-
Deploy the generated HTML to a Hugging Face Space
|
469 |
-
"""
|
470 |
-
if not title or not title.strip():
|
471 |
-
return "β Please enter a title for your space.", update_oauth_status(oauth_profile, oauth_token)
|
472 |
-
|
473 |
-
if not html_content or not html_content.strip():
|
474 |
-
return "β No HTML content to deploy. Please generate some code first.", update_oauth_status(oauth_profile, oauth_token)
|
475 |
-
|
476 |
-
# Check if user is authenticated
|
477 |
-
if not oauth_profile or not oauth_token:
|
478 |
-
return """β **Authentication Required**
|
479 |
-
|
480 |
-
To deploy your application, you need to be logged in with your Hugging Face account.
|
481 |
-
|
482 |
-
**How to log in:**
|
483 |
-
1. Click the "Sign in with Hugging Face" button in the sidebar
|
484 |
-
2. Authorize AnyCoder to access your Hugging Face account with the required permissions:
|
485 |
-
- read-repos
|
486 |
-
- write-repos
|
487 |
-
- manage-repos
|
488 |
-
3. Try deploying again
|
489 |
-
|
490 |
-
**Why login is required:**
|
491 |
-
- Deployments are created under your own Hugging Face account
|
492 |
-
- You need write permissions to create spaces
|
493 |
-
- This ensures you own and can manage your deployed applications
|
494 |
-
|
495 |
-
**Note:** Make sure to grant all the requested permissions when authorizing the application.
|
496 |
-
|
497 |
-
---
|
498 |
-
*Please log in and try again.*""", update_oauth_status(oauth_profile, oauth_token)
|
499 |
-
|
500 |
-
# Get user information from OAuth profile
|
501 |
-
username = oauth_profile.name
|
502 |
-
user_token = oauth_token.token
|
503 |
-
|
504 |
-
# Debug: Print token info (without exposing the actual token)
|
505 |
-
print(f"Debug: Username from OAuth: {username}")
|
506 |
-
print(f"Debug: Token type: {type(user_token)}")
|
507 |
-
print(f"Debug: Token length: {len(user_token) if user_token else 0}")
|
508 |
-
print(f"Debug: Token starts with: {user_token[:10] if user_token else 'None'}...")
|
509 |
-
|
510 |
-
# Additional debugging for OAuth components
|
511 |
-
print(f"Debug: OAuth profile type: {type(oauth_profile)}")
|
512 |
-
print(f"Debug: OAuth token type: {type(oauth_token)}")
|
513 |
-
print(f"Debug: OAuth profile attributes: {dir(oauth_profile) if oauth_profile else 'None'}")
|
514 |
-
print(f"Debug: OAuth token attributes: {dir(oauth_token) if oauth_token else 'None'}")
|
515 |
-
|
516 |
-
# Check OAuth token scopes if available
|
517 |
-
if hasattr(oauth_token, 'scopes'):
|
518 |
-
print(f"Debug: OAuth token scopes: {oauth_token.scopes}")
|
519 |
-
else:
|
520 |
-
print("Debug: OAuth token scopes not available")
|
521 |
-
|
522 |
-
# Check OAuth profile permissions if available
|
523 |
-
if hasattr(oauth_profile, 'permissions'):
|
524 |
-
print(f"Debug: OAuth profile permissions: {oauth_profile.permissions}")
|
525 |
-
else:
|
526 |
-
print("Debug: OAuth profile permissions not available")
|
527 |
-
|
528 |
-
# Validate OAuth scopes
|
529 |
-
scopes_valid, missing_scopes = validate_oauth_scopes(oauth_token)
|
530 |
-
print(f"Debug: OAuth scopes valid: {scopes_valid}")
|
531 |
-
print(f"Debug: Missing scopes: {missing_scopes}")
|
532 |
-
|
533 |
-
if not scopes_valid:
|
534 |
-
return f"""β **Missing OAuth Scopes**
|
535 |
-
|
536 |
-
Your OAuth token is missing the required permissions to create spaces.
|
537 |
-
|
538 |
-
**Missing Scopes:**
|
539 |
-
{chr(10).join([f"- `{scope}`" for scope in missing_scopes])}
|
540 |
-
|
541 |
-
**Required Scopes:**
|
542 |
-
- `read-repos` - Read access to repositories
|
543 |
-
- `write-repos` - Write access to create repositories
|
544 |
-
- `manage-repos` - Manage repository settings
|
545 |
-
|
546 |
-
**Steps to fix:**
|
547 |
-
1. **Logout**: Click the logout button in the sidebar
|
548 |
-
2. **Login Again**: Click "Sign in with Hugging Face" again
|
549 |
-
3. **Grant All Permissions**: When the authorization page appears, make sure to check ALL the requested permissions:
|
550 |
-
- β
read-repos
|
551 |
-
- β
write-repos
|
552 |
-
- β
manage-repos
|
553 |
-
4. **Complete Authorization**: Click "Authorize" to complete the login
|
554 |
-
5. **Try Deploying**: Try deploying again
|
555 |
-
|
556 |
-
**Important:** Make sure you see all three permissions checked on the authorization page before clicking "Authorize".
|
557 |
-
|
558 |
-
---
|
559 |
-
*Please log in again with full permissions.*""", update_oauth_status(oauth_profile, oauth_token)
|
560 |
-
|
561 |
-
# Validate token format
|
562 |
-
if not user_token or not user_token.startswith('hf_'):
|
563 |
-
return """β **Invalid Token Format**
|
564 |
-
|
565 |
-
The OAuth token appears to be invalid or in the wrong format. Please try logging out and logging back in.
|
566 |
-
|
567 |
-
**Steps to fix:**
|
568 |
-
1. Click the logout button in the sidebar
|
569 |
-
2. Click "Sign in with Hugging Face" again
|
570 |
-
3. Authorize the application with the required permissions (read-repos, write-repos, manage-repos)
|
571 |
-
4. Try deploying again
|
572 |
-
|
573 |
-
**Note:** Make sure you authorize all the required permissions when logging in.
|
574 |
-
|
575 |
-
---
|
576 |
-
*Please try logging in again.*""", update_oauth_status(oauth_profile, oauth_token)
|
577 |
-
|
578 |
-
# Test the token by making a simple API call
|
579 |
-
try:
|
580 |
-
test_api = HfApi(token=user_token)
|
581 |
-
user_info = test_api.whoami()
|
582 |
-
print(f"Debug: Token test successful - user: {user_info.get('name', 'unknown')}")
|
583 |
-
|
584 |
-
# Test if user can create repositories by checking their account type
|
585 |
-
try:
|
586 |
-
# Try to get user info to check account capabilities
|
587 |
-
user_info = test_api.whoami()
|
588 |
-
print(f"Debug: User info: {user_info}")
|
589 |
-
|
590 |
-
# Check if user has pro account or sufficient permissions
|
591 |
-
if user_info.get('type') == 'user':
|
592 |
-
print("Debug: User account type confirmed")
|
593 |
-
else:
|
594 |
-
print(f"Debug: User account type: {user_info.get('type', 'unknown')}")
|
595 |
-
|
596 |
-
except Exception as user_info_error:
|
597 |
-
print(f"Debug: Could not get detailed user info: {user_info_error}")
|
598 |
-
# This is not a critical error, so we continue
|
599 |
-
|
600 |
-
except Exception as token_error:
|
601 |
-
print(f"Debug: Token test failed: {token_error}")
|
602 |
-
return """β **Token Validation Failed**
|
603 |
-
|
604 |
-
The OAuth token could not be validated. This could be because:
|
605 |
-
|
606 |
-
1. The token has expired
|
607 |
-
2. The token doesn't have the right permissions
|
608 |
-
3. There's an issue with the authentication
|
609 |
-
|
610 |
-
**Steps to fix:**
|
611 |
-
1. Click the logout button in the sidebar
|
612 |
-
2. Click "Sign in with Hugging Face" again
|
613 |
-
3. Authorize with all required permissions
|
614 |
-
4. Try deploying again
|
615 |
-
|
616 |
-
---
|
617 |
-
*Please log in again.*""", update_oauth_status(oauth_profile, oauth_token)
|
618 |
-
|
619 |
-
# Extract prompts from history
|
620 |
-
prompts = []
|
621 |
-
for user_msg, _ in history:
|
622 |
-
if isinstance(user_msg, str) and user_msg.strip():
|
623 |
-
prompts.append(user_msg.strip())
|
624 |
-
|
625 |
-
# Test if user can create repositories by attempting a test creation
|
626 |
-
try:
|
627 |
-
test_api = HfApi(token=user_token)
|
628 |
-
|
629 |
-
# Try to create a test repository to verify permissions
|
630 |
-
test_repo_name = f"{username}/test-permissions-{int(time.time())}"
|
631 |
-
print(f"Debug: Testing repository creation with: {test_repo_name}")
|
632 |
-
|
633 |
-
try:
|
634 |
-
# Attempt to create a test repository
|
635 |
-
test_repo_url = test_api.create_repo(
|
636 |
-
repo_id=test_repo_name,
|
637 |
-
repo_type="model",
|
638 |
-
private=True,
|
639 |
-
exist_ok=False,
|
640 |
-
token=user_token
|
641 |
-
)
|
642 |
-
print(f"Debug: Successfully created test repository: {test_repo_url}")
|
643 |
-
|
644 |
-
# Clean up the test repository
|
645 |
-
try:
|
646 |
-
test_api.delete_repo(repo_id=test_repo_name, token=user_token)
|
647 |
-
print(f"Debug: Successfully cleaned up test repository")
|
648 |
-
except Exception as cleanup_error:
|
649 |
-
print(f"Debug: Could not clean up test repository: {cleanup_error}")
|
650 |
-
|
651 |
-
except Exception as test_create_error:
|
652 |
-
print(f"Debug: Could not create test repository: {test_create_error}")
|
653 |
-
error_msg = str(test_create_error).lower()
|
654 |
-
|
655 |
-
if "403" in error_msg or "forbidden" in error_msg:
|
656 |
-
return """β **Repository Creation Permission Denied**
|
657 |
-
|
658 |
-
Your Hugging Face account doesn't have permission to create repositories. This could be because:
|
659 |
-
|
660 |
-
1. **Account Type**: Your account type may not allow repository creation
|
661 |
-
2. **Organization Restrictions**: If you're part of an organization, there may be restrictions
|
662 |
-
3. **Account Status**: Your account may be limited or suspended
|
663 |
-
|
664 |
-
**Steps to fix:**
|
665 |
-
1. **Check Account Status**: Visit https://huggingface.co/settings/account to check your account status
|
666 |
-
2. **Verify Account Type**: Make sure your account allows repository creation
|
667 |
-
3. **Contact Support**: If you believe this is an error, contact Hugging Face support
|
668 |
-
4. **Try Different Account**: Consider using a different Hugging Face account
|
669 |
-
|
670 |
-
**Note:** Free accounts should be able to create repositories. If you're having issues, it might be a temporary restriction.
|
671 |
-
|
672 |
-
---
|
673 |
-
*Please check your account settings or try with a different account.*""", update_oauth_status(oauth_profile, oauth_token)
|
674 |
-
else:
|
675 |
-
return f"""β **Repository Creation Test Failed**
|
676 |
-
|
677 |
-
Error: {str(test_create_error)}
|
678 |
-
|
679 |
-
This could be due to:
|
680 |
-
- Network connectivity issues
|
681 |
-
- Hugging Face API temporary problems
|
682 |
-
- Account-specific restrictions
|
683 |
-
|
684 |
-
**Steps to fix:**
|
685 |
-
1. Check your internet connection
|
686 |
-
2. Wait a few minutes and try again
|
687 |
-
3. If the problem persists, check your Hugging Face account settings
|
688 |
-
|
689 |
-
---
|
690 |
-
*Please try again or contact support if the issue persists.*""", update_oauth_status(oauth_profile, oauth_token)
|
691 |
-
|
692 |
-
except Exception as test_error:
|
693 |
-
print(f"Debug: Repository creation test failed: {test_error}")
|
694 |
-
return f"""β **Permission Test Failed**
|
695 |
-
|
696 |
-
Could not test repository creation permissions: {str(test_error)}
|
697 |
-
|
698 |
-
**Steps to fix:**
|
699 |
-
1. Check your internet connection
|
700 |
-
2. Try logging out and logging back in
|
701 |
-
3. Wait a few minutes and try again
|
702 |
-
|
703 |
-
---
|
704 |
-
*Please try again or contact support if the issue persists.*""", update_oauth_status(oauth_profile, oauth_token)
|
705 |
-
|
706 |
-
# Use user's OAuth token to create space under their account
|
707 |
-
result = create_space_from_html(title.strip(), html_content, prompts, user_token, username)
|
708 |
-
|
709 |
-
if result["success"]:
|
710 |
-
return f"""β
**Successfully deployed!**
|
711 |
-
|
712 |
-
**Space URL:** {result['space_url']}
|
713 |
-
|
714 |
-
Your application is now live on Hugging Face Spaces under your account. You can share this URL with others to showcase your generated application.
|
715 |
-
|
716 |
-
**What's next:**
|
717 |
-
- Visit the space to see your application in action
|
718 |
-
- Share the URL with friends and colleagues
|
719 |
-
- Make modifications and redeploy as needed
|
720 |
-
- Manage your space from your Hugging Face dashboard
|
721 |
-
|
722 |
-
---
|
723 |
-
*Generated with β€οΈ using AnyCoder*""", update_oauth_status(oauth_profile, oauth_token)
|
724 |
-
else:
|
725 |
-
return f"""β **Deployment failed**
|
726 |
-
|
727 |
-
**Error:** {result['error']}
|
728 |
-
|
729 |
-
**Possible solutions:**
|
730 |
-
- Ensure you have write access to create spaces on your account
|
731 |
-
- Try a different title (avoid special characters)
|
732 |
-
- Check your internet connection
|
733 |
-
- Make sure your Hugging Face account has the necessary permissions
|
734 |
-
|
735 |
-
---
|
736 |
-
*Please try again or contact support if the issue persists.*""", update_oauth_status(oauth_profile, oauth_token)
|
737 |
-
|
738 |
def history_to_messages(history: History, system: str) -> Messages:
|
739 |
messages = [{'role': 'system', 'content': system}]
|
740 |
for h in history:
|
@@ -807,20 +254,6 @@ def history_render(history: History):
|
|
807 |
def clear_history():
|
808 |
return [], [], None, "" # Empty lists for both tuple format and chatbot messages, None for file, empty string for website URL
|
809 |
|
810 |
-
def update_oauth_status(oauth_profile: gr.OAuthProfile = None, oauth_token: gr.OAuthToken = None):
|
811 |
-
"""Update the OAuth status indicator based on login state"""
|
812 |
-
if not oauth_profile or not oauth_token:
|
813 |
-
return "π **Login Required**\nSign in to deploy applications"
|
814 |
-
|
815 |
-
# Check if we have the required scopes
|
816 |
-
scopes_valid, missing_scopes = validate_oauth_scopes(oauth_token)
|
817 |
-
|
818 |
-
if scopes_valid:
|
819 |
-
return f"β
**Logged in as {oauth_profile.name}**\nReady to deploy applications"
|
820 |
-
else:
|
821 |
-
missing_list = ", ".join(missing_scopes)
|
822 |
-
return f"β οΈ **Incomplete Permissions**\nMissing: {missing_list}\nPlease logout and login again"
|
823 |
-
|
824 |
def update_image_input_visibility(model):
|
825 |
"""Update image input visibility based on selected model"""
|
826 |
is_ernie_vl = model.get("id") == "baidu/ERNIE-4.5-VL-424B-A47B-Base-PT"
|
@@ -981,6 +414,188 @@ def demo_card_click(e: gr.EventData):
|
|
981 |
# Return the first demo description as fallback
|
982 |
return DEMO_LIST[0]['description']
|
983 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
984 |
def extract_text_from_image(image_path):
|
985 |
"""Extract text from image using OCR"""
|
986 |
try:
|
@@ -1477,18 +1092,16 @@ with gr.Blocks(
|
|
1477 |
gr.Markdown("# AnyCoder")
|
1478 |
gr.Markdown("*AI-Powered Code Generator*")
|
1479 |
|
1480 |
-
# Login
|
1481 |
-
login_btn = gr.LoginButton(
|
1482 |
-
value="Sign in with Hugging Face",
|
1483 |
-
logout_value="Logout ({})",
|
1484 |
-
variant="huggingface",
|
1485 |
-
size="sm"
|
1486 |
-
)
|
1487 |
|
1488 |
-
#
|
1489 |
-
|
1490 |
|
1491 |
-
#
|
|
|
|
|
|
|
1492 |
|
1493 |
# Main input section
|
1494 |
input = gr.Textbox(
|
@@ -1536,30 +1149,6 @@ with gr.Blocks(
|
|
1536 |
label="Model"
|
1537 |
)
|
1538 |
|
1539 |
-
# Deployment section
|
1540 |
-
gr.Markdown("---")
|
1541 |
-
gr.Markdown("**π Deploy to Space**")
|
1542 |
-
|
1543 |
-
# Space title input
|
1544 |
-
space_title_input = gr.Textbox(
|
1545 |
-
label="Space title",
|
1546 |
-
placeholder="My Awesome App",
|
1547 |
-
lines=1
|
1548 |
-
)
|
1549 |
-
|
1550 |
-
# Deploy button
|
1551 |
-
deploy_btn = gr.Button(
|
1552 |
-
"π Deploy to Space",
|
1553 |
-
variant="primary",
|
1554 |
-
size="lg"
|
1555 |
-
)
|
1556 |
-
|
1557 |
-
# Deployment status
|
1558 |
-
deploy_status = gr.Markdown(
|
1559 |
-
value="",
|
1560 |
-
visible=False
|
1561 |
-
)
|
1562 |
-
|
1563 |
# Quick examples (minimal)
|
1564 |
gr.Markdown("**Quick start**")
|
1565 |
with gr.Column():
|
@@ -1580,11 +1169,16 @@ with gr.Blocks(
|
|
1580 |
else:
|
1581 |
gr.Markdown("β
Web search available")
|
1582 |
|
1583 |
-
#
|
1584 |
-
|
1585 |
-
|
1586 |
-
|
|
|
|
|
|
|
1587 |
)
|
|
|
|
|
1588 |
|
1589 |
# Hidden elements for functionality
|
1590 |
model_display = gr.Markdown(f"**Model:** {AVAILABLE_MODELS[0]['name']}", visible=False)
|
@@ -1625,46 +1219,9 @@ with gr.Blocks(
|
|
1625 |
)
|
1626 |
with gr.Tab("Preview"):
|
1627 |
sandbox = gr.HTML(label="Live preview")
|
1628 |
-
with gr.Tab("Deploy"):
|
1629 |
-
deploy_output = gr.Markdown(
|
1630 |
-
value="""## π Deploy Your Application
|
1631 |
-
|
1632 |
-
### Prerequisites
|
1633 |
-
1. **Login Required**: You must be logged in with your Hugging Face account
|
1634 |
-
2. **Permissions**: Grant the following permissions when logging in:
|
1635 |
-
- β
**read-repos** - Read access to repositories
|
1636 |
-
- β
**write-repos** - Write access to create repositories
|
1637 |
-
- β
**manage-repos** - Manage repository settings
|
1638 |
-
|
1639 |
-
### Steps to Deploy
|
1640 |
-
1. **Login**: Click "Sign in with Hugging Face" in the sidebar
|
1641 |
-
2. **Authorize Permissions**: When the authorization page appears, make sure to grant ALL the requested permissions
|
1642 |
-
3. **Generate Code**: Generate some HTML code using the AI
|
1643 |
-
4. **Enter Title**: In the sidebar, enter a title for your space (e.g., "My Todo App")
|
1644 |
-
5. **Deploy**: Click the "π Deploy to Space" button
|
1645 |
-
|
1646 |
-
### What Happens
|
1647 |
-
- Your application will be deployed to Hugging Face Spaces under your account
|
1648 |
-
- You'll get a shareable URL (e.g., `https://huggingface.co/spaces/yourusername/my-app-1234567890`)
|
1649 |
-
- The deployment includes professional styling and documentation
|
1650 |
-
|
1651 |
-
### Troubleshooting
|
1652 |
-
If deployment fails:
|
1653 |
-
- Make sure you're logged in with the correct account
|
1654 |
-
- Ensure you granted all required permissions during login
|
1655 |
-
- Try logging out and logging back in
|
1656 |
-
- Check that your Hugging Face account can create repositories
|
1657 |
-
|
1658 |
-
**Important**: You must grant ALL three permissions during the OAuth authorization process.
|
1659 |
-
|
1660 |
-
---
|
1661 |
-
*Your application will be deployed to Hugging Face Spaces and you'll get a shareable URL!*""",
|
1662 |
-
label="Deployment Status"
|
1663 |
-
)
|
1664 |
with gr.Tab("History"):
|
1665 |
history_output = gr.Chatbot(show_label=False, height=400, type="messages")
|
1666 |
|
1667 |
-
|
1668 |
# Event handlers
|
1669 |
btn.click(
|
1670 |
generation_code,
|
@@ -1673,12 +1230,17 @@ If deployment fails:
|
|
1673 |
)
|
1674 |
clear_btn.click(clear_history, outputs=[history, history_output, file_input, website_url_input])
|
1675 |
|
1676 |
-
#
|
|
|
|
|
|
|
1677 |
deploy_btn.click(
|
1678 |
-
|
1679 |
-
inputs=[
|
1680 |
-
outputs=
|
1681 |
-
|
|
|
|
|
1682 |
)
|
1683 |
|
1684 |
if __name__ == "__main__":
|
|
|
18 |
import time
|
19 |
|
20 |
import gradio as gr
|
21 |
+
from huggingface_hub import InferenceClient, HfApi, create_repo, whoami
|
22 |
from tavily import TavilyClient
|
23 |
|
24 |
# Configuration
|
|
|
172 |
History = List[Tuple[str, str]]
|
173 |
Messages = List[Dict[str, str]]
|
174 |
|
|
|
|
|
|
|
175 |
# Tavily Search Client
|
176 |
TAVILY_API_KEY = os.getenv('TAVILY_API_KEY')
|
177 |
tavily_client = None
|
|
|
182 |
print(f"Failed to initialize Tavily client: {e}")
|
183 |
tavily_client = None
|
184 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
185 |
def history_to_messages(history: History, system: str) -> Messages:
|
186 |
messages = [{'role': 'system', 'content': system}]
|
187 |
for h in history:
|
|
|
254 |
def clear_history():
|
255 |
return [], [], None, "" # Empty lists for both tuple format and chatbot messages, None for file, empty string for website URL
|
256 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
257 |
def update_image_input_visibility(model):
|
258 |
"""Update image input visibility based on selected model"""
|
259 |
is_ernie_vl = model.get("id") == "baidu/ERNIE-4.5-VL-424B-A47B-Base-PT"
|
|
|
414 |
# Return the first demo description as fallback
|
415 |
return DEMO_LIST[0]['description']
|
416 |
|
417 |
+
def get_user_info(profile: gr.OAuthProfile | None) -> str:
|
418 |
+
"""Get user information from OAuth profile"""
|
419 |
+
if profile is None:
|
420 |
+
return "π€ **Guest User**\n*Sign in to personalize your experience*"
|
421 |
+
return f"π€ **{profile.name}**\n*Welcome back!*"
|
422 |
+
|
423 |
+
def create_space_from_code(html_code: str, title: str, oauth_token: gr.OAuthToken | None) -> str:
|
424 |
+
"""Create a new Hugging Face Space with the generated HTML code"""
|
425 |
+
if not oauth_token:
|
426 |
+
return "β **Error:** Please sign in with your Hugging Face account to deploy spaces."
|
427 |
+
|
428 |
+
if not html_code or not html_code.strip():
|
429 |
+
return "β **Error:** No code to deploy. Please generate some code first."
|
430 |
+
|
431 |
+
if not title or not title.strip():
|
432 |
+
return "β **Error:** Please provide a title for your space."
|
433 |
+
|
434 |
+
try:
|
435 |
+
# Clean up the title for use as repo name
|
436 |
+
import re
|
437 |
+
clean_title = re.sub(r'[^a-zA-Z0-9\s-]', '', title)
|
438 |
+
clean_title = re.sub(r'\s+', '-', clean_title).lower()
|
439 |
+
clean_title = clean_title[:50] # Limit length
|
440 |
+
|
441 |
+
# Get user info to create repo under their account
|
442 |
+
user_info = whoami(oauth_token.token)
|
443 |
+
username = user_info.get('name', 'unknown')
|
444 |
+
|
445 |
+
# Create unique repo ID
|
446 |
+
import time
|
447 |
+
timestamp = int(time.time())
|
448 |
+
repo_id = f"{username}/{clean_title}-{timestamp}"
|
449 |
+
|
450 |
+
# Create the space
|
451 |
+
api = HfApi(token=oauth_token.token)
|
452 |
+
api.create_repo(
|
453 |
+
repo_id=repo_id,
|
454 |
+
repo_type="space",
|
455 |
+
space_sdk="static",
|
456 |
+
space_hardware="cpu-basic"
|
457 |
+
)
|
458 |
+
|
459 |
+
# Create the HTML file content
|
460 |
+
html_content = f"""<!DOCTYPE html>
|
461 |
+
<html lang="en">
|
462 |
+
<head>
|
463 |
+
<meta charset="UTF-8">
|
464 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
465 |
+
<title>{title}</title>
|
466 |
+
<style>
|
467 |
+
body {{
|
468 |
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
469 |
+
margin: 0;
|
470 |
+
padding: 20px;
|
471 |
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
472 |
+
min-height: 100vh;
|
473 |
+
}}
|
474 |
+
.container {{
|
475 |
+
max-width: 1200px;
|
476 |
+
margin: 0 auto;
|
477 |
+
background: white;
|
478 |
+
border-radius: 12px;
|
479 |
+
box-shadow: 0 20px 40px rgba(0,0,0,0.1);
|
480 |
+
overflow: hidden;
|
481 |
+
}}
|
482 |
+
.header {{
|
483 |
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
484 |
+
color: white;
|
485 |
+
padding: 30px;
|
486 |
+
text-align: center;
|
487 |
+
}}
|
488 |
+
.header h1 {{
|
489 |
+
margin: 0;
|
490 |
+
font-size: 2.5em;
|
491 |
+
font-weight: 300;
|
492 |
+
}}
|
493 |
+
.header p {{
|
494 |
+
margin: 10px 0 0 0;
|
495 |
+
opacity: 0.9;
|
496 |
+
font-size: 1.1em;
|
497 |
+
}}
|
498 |
+
.content {{
|
499 |
+
padding: 40px;
|
500 |
+
}}
|
501 |
+
.footer {{
|
502 |
+
background: #f8f9fa;
|
503 |
+
padding: 20px;
|
504 |
+
text-align: center;
|
505 |
+
color: #666;
|
506 |
+
border-top: 1px solid #eee;
|
507 |
+
}}
|
508 |
+
.footer a {{
|
509 |
+
color: #667eea;
|
510 |
+
text-decoration: none;
|
511 |
+
}}
|
512 |
+
.footer a:hover {{
|
513 |
+
text-decoration: underline;
|
514 |
+
}}
|
515 |
+
</style>
|
516 |
+
</head>
|
517 |
+
<body>
|
518 |
+
<div class="container">
|
519 |
+
<div class="header">
|
520 |
+
<h1>{title}</h1>
|
521 |
+
<p>Generated with AnyCoder - AI-Powered Code Generator</p>
|
522 |
+
</div>
|
523 |
+
<div class="content">
|
524 |
+
{html_code}
|
525 |
+
</div>
|
526 |
+
<div class="footer">
|
527 |
+
<p>π Created with <a href="https://huggingface.co/spaces/anycoder" target="_blank">AnyCoder</a> |
|
528 |
+
<a href="https://huggingface.co/spaces" target="_blank">Hugging Face Spaces</a></p>
|
529 |
+
</div>
|
530 |
+
</div>
|
531 |
+
</body>
|
532 |
+
</html>"""
|
533 |
+
|
534 |
+
# Upload the HTML file
|
535 |
+
api.upload_file(
|
536 |
+
repo_id=repo_id,
|
537 |
+
repo_type="space",
|
538 |
+
path_in_repo="index.html",
|
539 |
+
path_or_fileobj=html_content.encode('utf-8')
|
540 |
+
)
|
541 |
+
|
542 |
+
# Create a README for the space
|
543 |
+
readme_content = f"""---
|
544 |
+
title: {title}
|
545 |
+
emoji: π
|
546 |
+
colorFrom: blue
|
547 |
+
colorTo: purple
|
548 |
+
sdk: static
|
549 |
+
sdk_version: 1.0.0
|
550 |
+
app_file: index.html
|
551 |
+
pinned: false
|
552 |
+
---
|
553 |
+
|
554 |
+
# {title}
|
555 |
+
|
556 |
+
This application was generated using AnyCoder, an AI-powered code generator.
|
557 |
+
|
558 |
+
## About
|
559 |
+
|
560 |
+
This space contains a web application created by describing requirements in natural language and having AI generate the corresponding HTML/CSS/JavaScript code.
|
561 |
+
|
562 |
+
## Features
|
563 |
+
|
564 |
+
- Responsive design
|
565 |
+
- Modern UI/UX
|
566 |
+
- Cross-browser compatibility
|
567 |
+
- Mobile-friendly layout
|
568 |
+
|
569 |
+
## Generated Code
|
570 |
+
|
571 |
+
The application code was automatically generated and includes:
|
572 |
+
- HTML structure
|
573 |
+
- CSS styling
|
574 |
+
- JavaScript functionality (if applicable)
|
575 |
+
|
576 |
+
## Created With
|
577 |
+
|
578 |
+
- [AnyCoder](https://huggingface.co/spaces/anycoder) - AI-Powered Code Generator
|
579 |
+
- [Hugging Face Spaces](https://huggingface.co/spaces) - Deployment Platform
|
580 |
+
|
581 |
+
---
|
582 |
+
*Generated on {time.strftime('%Y-%m-%d %H:%M:%S UTC', time.gmtime())}*
|
583 |
+
"""
|
584 |
+
|
585 |
+
api.upload_file(
|
586 |
+
repo_id=repo_id,
|
587 |
+
repo_type="space",
|
588 |
+
path_in_repo="README.md",
|
589 |
+
path_or_fileobj=readme_content.encode('utf-8')
|
590 |
+
)
|
591 |
+
|
592 |
+
space_url = f"https://huggingface.co/spaces/{repo_id}"
|
593 |
+
return f"β
**Success!** Your space has been created and deployed.\n\n**Space URL:** {space_url}\n\n**Repository:** {repo_id}\n\nYour application is now live and accessible to anyone with the link!"
|
594 |
+
|
595 |
+
except Exception as e:
|
596 |
+
return f"β **Error creating space:** {str(e)}\n\nPlease make sure you have the necessary permissions and try again."
|
597 |
+
|
598 |
+
|
599 |
def extract_text_from_image(image_path):
|
600 |
"""Extract text from image using OCR"""
|
601 |
try:
|
|
|
1092 |
gr.Markdown("# AnyCoder")
|
1093 |
gr.Markdown("*AI-Powered Code Generator*")
|
1094 |
|
1095 |
+
# OAuth Login Button
|
1096 |
+
login_btn = gr.LoginButton()
|
|
|
|
|
|
|
|
|
|
|
1097 |
|
1098 |
+
# User profile display
|
1099 |
+
user_info = gr.Markdown("π€ **Guest User**\n*Sign in to personalize your experience*")
|
1100 |
|
1101 |
+
gr.Markdown("---") # Separator
|
1102 |
+
|
1103 |
+
# Load user info on app load
|
1104 |
+
demo.load(get_user_info, inputs=None, outputs=user_info)
|
1105 |
|
1106 |
# Main input section
|
1107 |
input = gr.Textbox(
|
|
|
1149 |
label="Model"
|
1150 |
)
|
1151 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1152 |
# Quick examples (minimal)
|
1153 |
gr.Markdown("**Quick start**")
|
1154 |
with gr.Column():
|
|
|
1169 |
else:
|
1170 |
gr.Markdown("β
Web search available")
|
1171 |
|
1172 |
+
# Space deployment section
|
1173 |
+
gr.Markdown("---")
|
1174 |
+
gr.Markdown("**π Deploy to Space**")
|
1175 |
+
space_title = gr.Textbox(
|
1176 |
+
label="Space title",
|
1177 |
+
placeholder="My Awesome App",
|
1178 |
+
lines=1
|
1179 |
)
|
1180 |
+
deploy_btn = gr.Button("Create Space", variant="primary", size="sm")
|
1181 |
+
deploy_status = gr.Markdown("", visible=False)
|
1182 |
|
1183 |
# Hidden elements for functionality
|
1184 |
model_display = gr.Markdown(f"**Model:** {AVAILABLE_MODELS[0]['name']}", visible=False)
|
|
|
1219 |
)
|
1220 |
with gr.Tab("Preview"):
|
1221 |
sandbox = gr.HTML(label="Live preview")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1222 |
with gr.Tab("History"):
|
1223 |
history_output = gr.Chatbot(show_label=False, height=400, type="messages")
|
1224 |
|
|
|
1225 |
# Event handlers
|
1226 |
btn.click(
|
1227 |
generation_code,
|
|
|
1230 |
)
|
1231 |
clear_btn.click(clear_history, outputs=[history, history_output, file_input, website_url_input])
|
1232 |
|
1233 |
+
# Deploy space event handler
|
1234 |
+
def deploy_space_wrapper(title, current_code, oauth_token: gr.OAuthToken | None):
|
1235 |
+
return create_space_from_code(current_code, title, oauth_token)
|
1236 |
+
|
1237 |
deploy_btn.click(
|
1238 |
+
deploy_space_wrapper,
|
1239 |
+
inputs=[space_title, code_output],
|
1240 |
+
outputs=deploy_status
|
1241 |
+
).then(
|
1242 |
+
lambda: gr.update(visible=True),
|
1243 |
+
outputs=deploy_status
|
1244 |
)
|
1245 |
|
1246 |
if __name__ == "__main__":
|