import gradio as gr import anthropic import json import os import re from typing import Tuple, Optional import tempfile import zipfile from pathlib import Path # Initialize Anthropic client ANTHROPIC_API_KEY = os.getenv("ANTHROPIC_API_KEY") client = anthropic.Anthropic(api_key=ANTHROPIC_API_KEY) if ANTHROPIC_API_KEY else None def generate_website(description: str, style: str, features: list) -> Tuple[str, str, str]: """Generate website HTML, CSS, and JavaScript using Claude Sonnet 4.5""" if not client: return create_error_page("API Error: Please set ANTHROPIC_API_KEY environment variable") # Create prompt for Claude features_text = ", ".join(features) if features else "basic" prompt = f""" Create a complete, modern website based on this description: {description} Style: {style} Features to include: {features_text} Please generate: 1. A complete HTML file with semantic HTML5 structure 2. Modern CSS with responsive design (using CSS Grid/Flexbox) 3. JavaScript for interactivity (if needed) Requirements: - Use modern design principles - Make it fully responsive for mobile, tablet, and desktop - Include smooth animations and transitions - Use semantic HTML5 tags - Add hover effects and micro-interactions - Include proper meta tags for SEO - Use a modern color scheme - Add placeholder content that matches the description - Make it production-ready Return your response as a JSON object with this exact structure: {{ "html": "", "css": "", "js": "", "title": "Website Title" }} Do not include any explanations outside the JSON. Just return the JSON object. """ try: message = client.messages.create( model="claude-3-5-sonnet-20241022", max_tokens=4000, temperature=0.7, messages=[{ "role": "user", "content": prompt }] ) response_text = message.content[0].text # Extract JSON from response json_match = re.search(r'\{.*\}', response_text, re.DOTALL) if json_match: website_data = json.loads(json_match.group()) # Validate required keys if all(key in website_data for key in ['html', 'css', 'js', 'title']): return website_data['html'], website_data['css'], website_data['js'] else: return create_error_page("Invalid response format from AI") else: return create_error_page("Could not parse AI response") except Exception as e: return create_error_page(f"Error generating website: {str(e)}") def create_error_page(error_message: str) -> Tuple[str, str, str]: """Create an error page HTML""" error_html = f""" Error

⚠️ Error

{error_message}

""" return error_html, "", "" def create_preview(html: str, css: str, js: str) -> str: """Create a complete preview by combining HTML, CSS, and JS""" # Create a complete HTML document with embedded CSS and JS preview_html = f""" AI Generated Website Preview {html} """ return preview_html def download_website(html: str, css: str, js: str) -> str: """Create a zip file with the website files""" with tempfile.TemporaryDirectory() as temp_dir: temp_path = Path(temp_dir) # Create index.html index_content = f""" AI Generated Website {html} """ with open(temp_path / "index.html", "w", encoding="utf-8") as f: f.write(index_content) # Create styles.css with open(temp_path / "styles.css", "w", encoding="utf-8") as f: f.write(css) # Create script.js with open(temp_path / "script.js", "w", encoding="utf-8") as f: f.write(js) # Create README.md readme_content = """# AI Generated Website This website was generated using AI Website Builder with Claude Sonnet 4.5. ## Files - `index.html` - Main HTML file - `styles.css` - Stylesheet - `script.js` - JavaScript functionality ## Customization Feel free to modify any of the files to customize your website. """ with open(temp_path / "README.md", "w", encoding="utf-8") as f: f.write(readme_content) # Create zip file zip_path = temp_path / "website.zip" with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf: zipf.write(temp_path / "index.html", "index.html") zipf.write(temp_path / "styles.css", "styles.css") zipf.write(temp_path / "script.js", "script.js") zipf.write(temp_path / "README.md", "README.md") # Read zip file as bytes with open(zip_path, "rb") as f: zip_bytes = f.read() return zip_bytes # Custom CSS for the Gradio interface custom_css = """ .main-container { max-width: 1400px !important; margin: 0 auto !important; } .header { text-align: center; padding: 2rem; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; border-radius: 10px; margin-bottom: 2rem; } .header h1 { margin: 0; font-size: 2.5rem; font-weight: 700; } .header p { margin: 0.5rem 0 0 0; opacity: 0.9; font-size: 1.1rem; } .generator-section { background: #f8f9fa; padding: 2rem; border-radius: 10px; margin-bottom: 2rem; } .preview-section { background: white; border: 1px solid #e0e0e0; border-radius: 10px; overflow: hidden; } .preview-frame { width: 100%; height: 600px; border: none; } .code-editor { font-family: 'Courier New', monospace; font-size: 14px; } .tabs { margin-top: 1rem; } .generate-btn { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important; border: none !important; font-weight: 600 !important; padding: 0.75rem 2rem !important; font-size: 1.1rem !important; } .generate-btn:hover { transform: translateY(-2px); box-shadow: 0 5px 15px rgba(102, 126, 234, 0.4); } .feature-group { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1rem; margin-top: 1rem; } .feature-checkbox { background: white; padding: 1rem; border-radius: 8px; border: 2px solid #e0e0e0; transition: all 0.3s ease; } .feature-checkbox:hover { border-color: #667eea; transform: translateY(-2px); } .feature-checkbox label { font-weight: 500; cursor: pointer; } @media (max-width: 768px) { .header h1 { font-size: 2rem; } .feature-group { grid-template-columns: 1fr; } } """ # Create the Gradio interface with gr.Blocks(css=custom_css, title="AI Website Builder") as demo: # Header gr.HTML("""

🚀 AI Website Builder

Create stunning websites instantly with Claude Sonnet 4.5

Built with anycoder

""") with gr.Row(): # Left column - Generator controls with gr.Column(scale=1): with gr.Box(elem_classes=["generator-section"]): gr.Markdown("## 📝 Website Description") description = gr.Textbox( label="Describe your website", placeholder="e.g., A modern portfolio website for a web developer with projects, about section, and contact form", lines=4, max_lines=6 ) gr.Markdown("## 🎨 Style Preference") style = gr.Dropdown( choices=[ "Modern & Minimalist", "Corporate & Professional", "Creative & Colorful", "Dark & Moody", "Elegant & Sophisticated", "Playful & Fun", "Tech & Futuristic", "Nature & Organic" ], value="Modern & Minimalist", label="Choose a style" ) gr.Markdown("## ✨ Features") with gr.Row(elem_classes=["feature-group"]): with gr.Column(): responsive = gr.Checkbox(label="📱 Responsive Design", value=True) animations = gr.Checkbox(label="🎬 Animations", value=True) navbar = gr.Checkbox(label="🧭 Navigation Bar", value=True) with gr.Column(): footer = gr.Checkbox(label="📄 Footer", value=True) social = gr.Checkbox(label="🔗 Social Links", value=False) contact = gr.Checkbox(label="📧 Contact Form", value=False) with gr.Column(): gallery = gr.Checkbox(label="🖼️ Image Gallery", value=False) blog = gr.Checkbox(label="📝 Blog Section", value=False) dark_mode = gr.Checkbox(label="🌙 Dark Mode Toggle", value=False) features = [responsive, animations, navbar, footer, social, contact, gallery, blog, dark_mode] generate_btn = gr.Button( "🚀 Generate Website", variant="primary", size="lg", elem_classes=["generate-btn"] ) # Right column - Preview and Code with gr.Column(scale=2): with gr.Tabs(elem_classes=["tabs"]) as tabs: with gr.TabItem("🖥️ Live Preview"): with gr.Box(elem_classes=["preview-section"]): preview = gr.HTML( value='
Your website preview will appear here after generation
', label="Preview" ) with gr.TabItem("💻 Code Editor"): with gr.Tabs(): with gr.TabItem("HTML"): html_code = gr.Code( language="html", label="HTML Code", elem_classes=["code-editor"], lines=20 ) with gr.TabItem("CSS"): css_code = gr.Code( language="css", label="CSS Code", elem_classes=["code-editor"], lines=20 ) with gr.TabItem("JavaScript"): js_code = gr.Code( language="javascript", label="JavaScript Code", elem_classes=["code-editor"], lines=20 ) with gr.TabItem("⬇️ Download"): gr.Markdown("### 📦 Download Your Website") gr.Markdown("Click the button below to download a complete ZIP file with all website assets.") download_btn = gr.DownloadButton( "📥 Download Website", variant="primary", size="lg" ) gr.Markdown(""" **What's included:** - `index.html` - Main HTML file - `styles.css` - Complete stylesheet - `script.js` - JavaScript functionality - `README.md` - Documentation """) # Store generated website data website_state = gr.State({"html": "", "css": "", "js": ""}) # Event handlers def generate_and_update(desc, style_choice, *feature_flags): """Generate website and update all components""" if not desc.strip(): return ( '
Please enter a website description
', "", "", "", None, {"html": "", "css": "", "js": ""} ) # Filter selected features selected_features = [] feature_names = [ "Responsive Design", "Animations", "Navigation Bar", "Footer", "Social Links", "Contact Form", "Image Gallery", "Blog Section", "Dark Mode Toggle" ] for i, flag in enumerate(feature_flags): if flag: selected_features.append(feature_names[i]) # Generate website html, css, js = generate_website(desc, style_choice, selected_features) # Create preview preview_html = create_preview(html, css, js) # Create download file zip_file = download_website(html, css, js) return ( preview_html, html, css, js, zip_file, {"html": html, "css": css, "js": js} ) # Wire up the generate button generate_btn.click( fn=generate_and_update, inputs=[description, style] + features, outputs=[ preview, html_code, css_code, js_code, download_btn, website_state ] ) # Add example descriptions gr.Examples( examples=[ [ "A professional portfolio website for a UX designer showcasing their best projects with case studies, testimonials, and contact information", "Modern & Minimalist", [True, True, True, True, False, True, False, False, False] ], [ "A vibrant restaurant website with menu, online reservations, gallery of dishes, and location map", "Creative & Colorful", [True, True, True, True, True, True, True, False, False] ], [ "A tech startup landing page with features, pricing plans, team section, and signup form", "Tech & Futuristic", [True, True, True, True, False, True, False, False, True] ], [ "A photography portfolio with gallery, about section, services offered, and booking form", "Elegant & Sophisticated", [True, True, True, True, True, True, True, False, False] ] ], inputs=[description, style] + features, outputs=[preview, html_code, css_code, js_code, download_btn, website_state], fn=generate_and_update, cache_examples=False ) # Launch the app if __name__ == "__main__": demo.launch( share=False, show_error=True, show_api=False )