File size: 5,956 Bytes
9b373ae
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
import os
import uuid
import requests
import hashlib
from agno.tools import tool
from pathlib import Path
from datetime import datetime


@tool(
    name="deploy_html_file_with_digest",  # Custom name for the tool (otherwise the function name is used)
    description="Deploys the generated HTML File to Netlify",  # Custom description (otherwise the function docstring is used)
    show_result=True,  # Show result after function call
    stop_after_tool_call=True,  # Return the result immediately after the tool call and stop the agent
    cache_results=True,  # Enable caching of results
    cache_dir="/tmp/agno_cache",  # Custom cache directory
    cache_ttl=3600,  # Cache TTL in seconds (1 hour)
)
def deploy_html_file_with_digest(title, html_file_path, access_token=None):
    """
    Deploy a single HTML file to Netlify using the file digest method.

    Args:
        title (str): The title/name for the site
        html_file_path (str): Path to the HTML file to deploy
        access_token (str): Netlify personal access token (optional, will use env var if not provided)

    Returns:
        dict: Response containing site information and deploy details
    """
    # Use provided token or get from environment
    token = access_token or os.getenv("NETLIFY_PERSONAL_ACCESS_TOKEN")
    if not token:
        raise ValueError("No Netlify access token provided")

    # Generate a random site name
    site_name = f"{title.lower().replace(' ', '-')}-{str(uuid.uuid4())[:8]}"

    # Netlify API base URL
    api_base = "https://api.netlify.com/api/v1"

    # Headers for authentication
    headers = {
        "Authorization": f"Bearer {token}",
        "User-Agent": "MicrositePilot-Deployer",
        "Content-Type": "application/json",
    }

    try:
        # Step 1: Create a new site
        site_data = {
            "name": site_name,
            "processing_settings": {"html": {"pretty_urls": True}},
        }

        site_response = requests.post(
            f"{api_base}/sites", headers=headers, json=site_data
        )
        site_response.raise_for_status()
        site_info = site_response.json()

        site_id = site_info["id"]
        site_url = site_info["url"]
        admin_url = site_info["admin_url"]

        # Step 2: Read the HTML file and calculate SHA1
        with open(html_file_path, "rb") as f:
            html_content = f.read()

        # Calculate SHA1 hash
        sha1_hash = hashlib.sha1(html_content).hexdigest()

        # Step 3: Create deployment with file digest

        deploy_data = {"files": {"/index.html": sha1_hash}}

        deploy_response = requests.post(
            f"{api_base}/sites/{site_id}/deploys",
            headers=headers,
            json=deploy_data,
        )
        deploy_response.raise_for_status()
        deploy_info = deploy_response.json()

        deploy_id = deploy_info["id"]
        required_files = deploy_info.get("required", [])
        deploy_url = deploy_info.get("deploy_url", "")
        deploy_state = deploy_info.get("state", "unknown")

        # Step 4: Upload required files
        if sha1_hash in required_files:
            file_headers = {
                "Authorization": f"Bearer {token}",
                "Content-Type": "text/html",
                "User-Agent": "MicrositePilot-Deployer",
            }

            upload_response = requests.put(
                f"{api_base}/deploys/{deploy_id}/files/index.html",
                headers=file_headers,
                data=html_content,
            )
            upload_response.raise_for_status()
            print(f"✅ File uploaded successfully!")
        else:
            print(f"ℹ️  File already exists on Netlify, no upload needed")

        # Step 5: Check final deployment status
        status_response = requests.get(
            f"{api_base}/deploys/{deploy_id}", headers=headers
        )
        status_response.raise_for_status()
        status_info = status_response.json()

        final_state = status_info.get("state", "unknown")
        final_url = status_info.get("deploy_url", deploy_url)

        # Return comprehensive information
        return {
            "success": True,
            "site": {
                "id": site_id,
                "name": site_name,
                "url": site_url,
                "admin_url": admin_url,
            },
        }

    except requests.exceptions.RequestException as e:
        return {
            "success": False,
            "error": str(e),
            "message": f"Failed to deploy {title}",
        }
    except FileNotFoundError:
        return {
            "success": False,
            "error": "File not found",
            "message": f"HTML file {html_file_path} not found",
        }
    except Exception as e:
        return {
            "success": False,
            "error": str(e),
            "message": f"Unexpected error during deployment of {title}",
        }


@tool(
    name="save_html_file",
    description="Saves the html content into a html file",
    show_result=False,  # Don't show result to avoid contaminating agent output
)
def save_html_to_file(html_content: str) -> str:
    """
    Manually save HTML content to the microsites directory.

    Args:
        html_content: The HTML content to save

    Returns:
        str: The full path to the saved HTML file
    """
    # Create microsites directory if it doesn't exist
    microsites_dir = Path(__file__).parent.parent / "microsites"
    microsites_dir.mkdir(exist_ok=True)

    # Generate filename with timestamp
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    filename = f"demo_{timestamp}.html"
    file_path = microsites_dir / filename

    try:
        # Write HTML content to file
        with open(file_path, "w", encoding="utf-8") as f:
            f.write(html_content)

        return str(file_path)

    except Exception as e:
        raise Exception(f"Could not save HTML file: {e}")