File size: 3,716 Bytes
bf0d7be
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# /deployment.py

"""
Handles deployment of generated code to Hugging Face Spaces.

This module provides functions to wrap generated code into a runnable
Gradio or Static HTML app and to programmatically create and upload
it to a user's Hugging Face Space.
"""
import tempfile
import webbrowser
import logging
from urllib.parse import urlencode

from huggingface_hub import HfApi, HfFolder
import gradio as gr

def _create_space_readme(space_name: str, sdk: str) -> str:
    """Generates a standard README.md file for the new Space."""
    return f"""---
title: {space_name}
emoji: πŸš€
colorFrom: blue
colorTo: green
sdk: {sdk}
---

# {space_name}

This Space was generated by [AnyCoder](<YOUR_APP_SPACE_URL>).
"""

def deploy_to_hf_space(
    code: str,
    space_name: str,
    sdk: str,
    hf_token: str
) -> str:
    """
    Creates or updates a Hugging Face Space and uploads the generated code.

    Args:
        code: The code to deploy (HTML or Python).
        space_name: The desired name for the Space.
        sdk: The SDK for the Space ('static', 'gradio', 'streamlit').
        hf_token: The user's Hugging Face write token.

    Returns:
        A success or error message with a link to the Space.
    """
    if not code or not code.strip():
        return "Cannot deploy: No code has been generated."
    if not space_name or not space_name.strip():
        return "Cannot deploy: Please provide a name for your app."
    if not hf_token:
        # Fallback to URL-based deployment if no token is provided
        return deploy_via_url(code, space_name, sdk)

    try:
        api = HfApi(token=hf_token)
        user_info = api.whoami(token=hf_token)
        username = user_info['name']
        repo_id = f"{username}/{space_name.strip()}"

        api.create_repo(repo_id, repo_type="space", space_sdk=sdk, exist_ok=True)

        if sdk == 'static':
            file_content = code
            file_path_in_repo = "index.html"
        else: # gradio or streamlit
            file_content = code # Assume code is already wrapped for Python
            file_path_in_repo = "app.py"

        # Upload the main app file
        api.upload_file(
            path_or_fileobj=file_content.encode('utf-8'),
            path_in_repo=file_path_in_repo,
            repo_id=repo_id,
            repo_type="space"
        )
        # Upload a README
        readme_content = _create_space_readme(space_name, sdk)
        api.upload_file(
            path_or_fileobj=readme_content.encode('utf-8'),
            path_in_repo="README.md",
            repo_id=repo_id,
            repo_type="space"
        )

        space_url = f"https://huggingface.co/spaces/{repo_id}"
        return f"βœ… Deployed successfully! [Open your Space]({space_url})"

    except Exception as e:
        logging.error(f"Failed to deploy to Hugging Face Space: {e}")
        return f"❌ Deployment failed: {str(e)}"

def deploy_via_url(code: str, space_name: str, sdk: str) -> str:
    """
    Opens a new browser tab with pre-filled parameters to create a Space.
    This is a fallback for users who are not logged in via OAuth.
    """
    if sdk == 'static':
        app_file = "index.html"
        content = code
    else:
        app_file = "app.py"
        # Basic wrapping for Python-based SDKs if needed
        content = code # Assuming code is python string
    
    params = urlencode({
        "name": space_name,
        "sdk": sdk,
        "files[0][path]": app_file,
        "files[0][content]": content
    })
    base_url = "https://huggingface.co/new-space"
    full_url = f"{base_url}?{params}"

    webbrowser.open_new_tab(full_url)
    return "πŸš€ Your app is ready to launch! Check the new browser tab."