dure-waseem's picture
initial code
9c60c5f
# #main.py
# import sys
# import os
# import warnings
# from crew import DocProcessing
# import re
# # Fix Unicode encoding issues on Windows
# if sys.platform.startswith('win'):
# import codecs
# sys.stdout = codecs.getwriter('utf-8')(sys.stdout.detach())
# sys.stderr = codecs.getwriter('utf-8')(sys.stderr.detach())
# warnings.filterwarnings("ignore", category=SyntaxWarning, module="pysbd")
# def determine_file_type(file_path):
# """
# Determine the file type based on the file extension.
# Args:
# file_path (str): Path to the file
# Returns:
# str: 'pdf' if the file is a PDF, 'image' otherwise
# """
# _, ext = os.path.splitext(file_path)
# if ext.lower() == '.pdf':
# return 'pdf'
# return 'image'
# def run():
# """
# Run the crew with file paths received from command line arguments.
# """
# # Get file paths from command line arguments
# file_paths = sys.argv[1:] if len(sys.argv) > 1 else []
# if not file_paths:
# print("No file paths provided. Usage: python main.py <file_path1> <file_path2> ...")
# return
# # Process the first file (you can modify this to handle multiple files if needed)
# file_path = file_paths[0]
# file_type = determine_file_type(file_path)
# # Prepare inputs for the CrewAI
# inputs = {
# "file_path": file_path,
# "file_type": file_type,
# }
# try:
# # Pass the inputs to the crew kickoff method
# result = DocProcessing().crew().kickoff(inputs=inputs)
# # Try to get the actual output content from CrewOutput
# return result
# except Exception as e:
# error_msg = f"An error occurred while running the crew: {e}"
# print(error_msg)
# raise Exception(error_msg)
# if __name__ == "__main__":
# run()
#&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
# import gradio as gr
# import os
# import tempfile
# import shutil
# from pathlib import Path
# import warnings
# from typing import Tuple, Optional
# import sys
# # Suppress warnings
# warnings.filterwarnings("ignore", category=SyntaxWarning, module="pysbd")
# # Import your existing modules
# from crew import DocProcessing
# from tools.custom_tool import landing_ai_document_analysis
# def get_landing_ai_key():
# """Get Landing AI API key from environment (HF secrets or local .env)"""
# # Try multiple environment variable names for flexibility
# return (
# os.getenv("LANDING_AI_API_KEY") or # HuggingFace secrets or production
# os.getenv("LANDING_AI_API_KEY_LOCAL") or # Local development alternative
# os.getenv("LANDINGAI_API_KEY") or # Alternative naming
# os.getenv("LANDING_API_KEY") # Another alternative
# )
# def validate_api_key(api_key: str) -> bool:
# """Validate Anthropic API key format"""
# if not api_key:
# return False
# return api_key.startswith("sk-ant-") and len(api_key) > 20
# def determine_file_type(file_path: str) -> str:
# """Determine file type based on extension"""
# _, ext = os.path.splitext(file_path)
# return 'pdf' if ext.lower() == '.pdf' else 'image'
# def process_document(file, anthropic_api_key: str) -> Tuple[str, str]:
# """
# Process the uploaded document and return analysis + generated code
# Args:
# file: Uploaded file object from Gradio
# anthropic_api_key: User's Anthropic API key
# Returns:
# Tuple of (analysis_result, generated_code)
# """
# try:
# # Validate inputs
# if not file:
# return "❌ No file uploaded", ""
# if not validate_api_key(anthropic_api_key):
# return "❌ Invalid Anthropic API key. Please ensure it starts with 'sk-ant-' and is complete.", ""
# # Check if Landing AI key is available
# landing_ai_key = get_landing_ai_key()
# if not landing_ai_key:
# return "❌ Landing AI API key not configured. Please ensure LANDING_AI_API_KEY is set in environment variables or HuggingFace secrets.", ""
# # Set environment variables securely
# os.environ["ANTHROPIC_API_KEY"] = anthropic_api_key
# os.environ["LANDING_AI_API_KEY"] = landing_ai_key
# # Create temporary directory for processing
# with tempfile.TemporaryDirectory() as temp_dir:
# # Save uploaded file
# file_extension = Path(file.name).suffix
# temp_file_path = os.path.join(temp_dir, f"uploaded_file{file_extension}")
# # Copy uploaded file to temp location
# shutil.copy2(file.name, temp_file_path)
# # Determine file type
# file_type = determine_file_type(temp_file_path)
# # Prepare inputs for CrewAI
# inputs = {
# "file_path": temp_file_path,
# "file_type": file_type,
# }
# # Initialize and run the crew with the API key
# doc_processing = DocProcessing(anthropic_api_key=anthropic_api_key)
# result = doc_processing.crew().kickoff(inputs=inputs)
# # Extract results from CrewOutput
# if hasattr(result, 'tasks_output') and result.tasks_output:
# analysis_result = ""
# generated_code = ""
# for i, task_output in enumerate(result.tasks_output):
# if i == 0: # First task is document analysis
# analysis_result = str(task_output.raw) if hasattr(task_output, 'raw') else str(task_output)
# elif i == 1: # Second task is code implementation
# generated_code = str(task_output.raw) if hasattr(task_output, 'raw') else str(task_output)
# return analysis_result, generated_code
# else:
# # Fallback if structure is different
# result_str = str(result)
# return result_str, "Code generation completed. Check the analysis section for details."
# except Exception as e:
# error_msg = f"❌ Error processing document: {str(e)}"
# return error_msg, ""
# finally:
# # Clean up environment variables for security
# if "ANTHROPIC_API_KEY" in os.environ:
# del os.environ["ANTHROPIC_API_KEY"]
# def create_demo_interface():
# """Create the Gradio interface"""
# # Custom CSS for better styling
# custom_css = """
# .gradio-container {
# max-width: 1200px !important;
# margin: auto !important;
# }
# .header {
# text-align: center;
# margin-bottom: 2rem;
# }
# .api-key-input {
# margin-bottom: 1rem;
# }
# .output-section {
# margin-top: 2rem;
# }
# """
# with gr.Blocks(css=custom_css, title="Document to Code Converter") as demo:
# gr.HTML("""
# <div class="header">
# <h1>πŸš€ Document to Code Converter</h1>
# <p>Upload your design documents (images/PDFs) and convert them to working HTML/CSS/JS code!</p>
# </div>
# """)
# with gr.Row():
# with gr.Column(scale=1):
# gr.HTML("<h3>πŸ“€ Upload & Configuration</h3>")
# # API Key input
# api_key_input = gr.Textbox(
# label="πŸ”‘ Anthropic API Key",
# placeholder="sk-ant-...",
# type="password",
# info="Enter your Anthropic API key. It will be used securely and not stored.",
# elem_classes=["api-key-input"]
# )
# # File upload
# file_input = gr.File(
# label="πŸ“ Upload Document",
# file_types=[".pdf", ".png", ".jpg", ".jpeg", ".gif", ".bmp", ".tiff"],
# )
# # Process button
# process_btn = gr.Button(
# "πŸ”„ Process Document",
# variant="primary",
# size="lg"
# )
# # Status indicator
# gr.HTML("""
# <div style="margin-top: 1rem; padding: 1rem; background: #f0f9ff; border-radius: 8px; border-left: 4px solid #0ea5e9;">
# <h4 style="margin: 0; color: #0c4a6e;">ℹ️ How it works:</h4>
# <ol style="margin: 0.5rem 0; color: #164e63;">
# <li>Upload your design document (image or PDF)</li>
# <li>Enter your Anthropic API key</li>
# <li>Click "Process Document" to analyze and generate code</li>
# <li>Get detailed analysis and working HTML/CSS/JS code</li>
# </ol>
# </div>
# """)
# with gr.Row():
# with gr.Column(scale=1):
# gr.HTML("<h3 class='output-section'>πŸ“Š Document Analysis</h3>")
# analysis_output = gr.Textbox(
# label="Analysis Results",
# lines=15,
# placeholder="Document analysis will appear here...",
# show_copy_button=True
# )
# with gr.Column(scale=1):
# gr.HTML("<h3 class='output-section'>πŸ’» Generated Code</h3>")
# code_output = gr.Textbox(
# label="HTML/CSS/JS Code",
# lines=15,
# placeholder="Generated code will appear here...",
# show_copy_button=True
# )
# # Add examples section
# gr.HTML("""
# <div style="margin-top: 2rem; padding: 1rem; background: #f8fafc; border-radius: 8px;">
# <h4>🎯 Best Results Tips:</h4>
# <ul>
# <li><strong>High Quality Images:</strong> Use clear, high-resolution images for better analysis</li>
# <li><strong>Design Mockups:</strong> Website mockups, app designs, and UI sketches work great</li>
# <li><strong>PDF Documents:</strong> Multi-page design documents are supported</li>
# <li><strong>Clear Layouts:</strong> Well-organized designs produce better code structure</li>
# </ul>
# </div>
# """)
# # Set up the processing event
# process_btn.click(
# fn=process_document,
# inputs=[file_input, api_key_input],
# outputs=[analysis_output, code_output],
# show_progress=True
# )
# # Add footer
# gr.HTML("""
# <div style="text-align: center; margin-top: 2rem; padding: 1rem; border-top: 1px solid #e2e8f0; color: #64748b;">
# <p>πŸ”’ Your API keys are handled securely and never stored.
# <br>Built with CrewAI, LandingAI, and Anthropic Claude.</p>
# </div>
# """)
# return demo
# if __name__ == "__main__":
# # Test Landing AI connection on startup
# from tools.custom_tool import test_landing_ai_connection
# print("πŸ” Testing API connections...")
# landing_ai_available = test_landing_ai_connection()
# if not landing_ai_available:
# print("\n⚠️ Warning: Landing AI API key not properly configured!")
# print("For local development: Set LANDING_AI_API_KEY in your .env file")
# print("For HuggingFace deployment: Add LANDING_AI_API_KEY to your Space secrets")
# print("The app will still start, but document analysis will fail without the API key.\n")
# else:
# print("βœ… Landing AI API key configured correctly!\n")
# # Create and launch the demo
# demo = create_demo_interface()
# # Launch configuration
# demo.launch(
# server_name="0.0.0.0", # Required for HuggingFace deployment
# server_port=7860, # Standard port for HuggingFace
# share=False, # Set to True for temporary public link during development
# debug=False, # Set to True for development
# show_error=True, # Show errors in the interface
# quiet=False # Set to True to reduce console output
# )
import gradio as gr
import os
import tempfile
import shutil
from pathlib import Path
import warnings
from typing import Tuple, Optional
import sys
# Suppress warnings
warnings.filterwarnings("ignore", category=SyntaxWarning, module="pysbd")
# Import your existing modules
from crew import DocProcessing
from tools.custom_tool import landing_ai_document_analysis
def get_landing_ai_key():
"""Get Landing AI API key from environment (HF secrets or local .env)"""
# Try multiple environment variable names for flexibility
return (
os.getenv("LANDING_AI_API_KEY") or # HuggingFace secrets or production
os.getenv("LANDING_AI_API_KEY_LOCAL") or # Local development alternative
os.getenv("LANDINGAI_API_KEY") or # Alternative naming
os.getenv("LANDING_API_KEY") # Another alternative
)
def validate_api_key(api_key: str) -> bool:
"""Validate Anthropic API key format"""
if not api_key:
return False
return api_key.startswith("sk-ant-") and len(api_key) > 20
def create_html_file(code_content: str, filename: str = "generated_page.html") -> str:
"""
Create an HTML file from the generated code
Args:
code_content: The HTML/CSS/JS code
filename: Name for the HTML file
Returns:
str: Path to the created file
"""
try:
# Create temporary file
temp_dir = tempfile.gettempdir()
file_path = os.path.join(temp_dir, filename)
# Clean the code content - remove any markdown formatting if present
cleaned_code = code_content.strip()
if cleaned_code.startswith("```html"):
cleaned_code = cleaned_code[7:]
if cleaned_code.endswith("```"):
cleaned_code = cleaned_code[:-3]
cleaned_code = cleaned_code.strip()
# Ensure it's a complete HTML document
if not cleaned_code.lower().startswith('<!doctype') and not cleaned_code.lower().startswith('<html'):
cleaned_code = f"""<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Generated Page</title>
</head>
<body>
{cleaned_code}
</body>
</html>"""
# Write to file
with open(file_path, 'w', encoding='utf-8') as f:
f.write(cleaned_code)
return file_path
except Exception as e:
print(f"Error creating HTML file: {e}")
return None
def determine_file_type(file_path: str) -> str:
"""Determine file type based on extension"""
_, ext = os.path.splitext(file_path)
return 'pdf' if ext.lower() == '.pdf' else 'image'
def prepare_preview_content(code_content: str) -> str:
"""
Prepare code content for safe preview in iframe
Args:
code_content: The HTML/CSS/JS code
Returns:
str: Cleaned and safe HTML content for preview
"""
try:
if not code_content or code_content.strip() == "":
return "<div style='padding: 20px; text-align: center; color: #666;'>No code generated yet...</div>"
# Clean the code content
cleaned_code = code_content.strip()
# Remove markdown formatting if present
if cleaned_code.startswith("```html"):
cleaned_code = cleaned_code[7:]
if cleaned_code.startswith("```"):
cleaned_code = cleaned_code[3:]
if cleaned_code.endswith("```"):
cleaned_code = cleaned_code[:-3]
cleaned_code = cleaned_code.strip()
# If it's not a complete HTML document, wrap it
if not cleaned_code.lower().startswith('<!doctype') and not cleaned_code.lower().startswith('<html'):
cleaned_code = f"""<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Preview</title>
<style>
body {{ margin: 0; padding: 10px; font-family: Arial, sans-serif; }}
* {{ box-sizing: border-box; }}
</style>
</head>
<body>
{cleaned_code}
</body>
</html>"""
# Wrap in iframe for safe rendering
iframe_content = f"""
<iframe
srcdoc="{cleaned_code.replace('"', '&quot;')}"
style="width: 100%; height: 400px; border: 1px solid #ddd; border-radius: 8px;"
sandbox="allow-scripts allow-same-origin">
</iframe>
"""
return iframe_content
except Exception as e:
return f"<div style='padding: 20px; color: red;'>Error preparing preview: {str(e)}</div>"
def toggle_to_code():
"""Show code view and hide preview"""
return (
gr.update(visible=True), # code_output
gr.update(visible=False), # preview_output
gr.update(variant="primary"), # code_view_btn
gr.update(variant="secondary") # preview_btn
)
def toggle_to_preview(code_content):
"""Show preview and hide code view"""
preview_html = prepare_preview_content(code_content)
return (
gr.update(visible=False), # code_output
gr.update(visible=True, value=preview_html), # preview_output
gr.update(variant="secondary"), # code_view_btn
gr.update(variant="primary") # preview_btn
)
# def download_html_file(code_content):
# """Create downloadable HTML file"""
# if not code_content or code_content.strip() == "":
# return gr.update(visible=False)
# file_path = create_html_file(code_content)
# if file_path:
# return gr.update(visible=True, value=file_path)
# else:
# return gr.update(visible=False)
def process_document(file, anthropic_api_key: str) -> Tuple[str, str]:
"""
Process the uploaded document and return analysis + generated code
Args:
file: Uploaded file object from Gradio
anthropic_api_key: User's Anthropic API key
Returns:
Tuple of (analysis_result, generated_code)
"""
try:
# Validate inputs
if not file:
return "❌ No file uploaded", ""
if not validate_api_key(anthropic_api_key):
return "❌ Invalid Anthropic API key. Please ensure it starts with 'sk-ant-' and is complete.", ""
# Check if Landing AI key is available
landing_ai_key = get_landing_ai_key()
if not landing_ai_key:
return "❌ Landing AI API key not configured. Please ensure LANDING_AI_API_KEY is set in environment variables or HuggingFace secrets.", ""
# Set environment variables securely
os.environ["ANTHROPIC_API_KEY"] = anthropic_api_key
os.environ["LANDING_AI_API_KEY"] = landing_ai_key
# Create temporary directory for processing
with tempfile.TemporaryDirectory() as temp_dir:
# Save uploaded file
file_extension = Path(file.name).suffix
temp_file_path = os.path.join(temp_dir, f"uploaded_file{file_extension}")
# Copy uploaded file to temp location
shutil.copy2(file.name, temp_file_path)
# Determine file type
file_type = determine_file_type(temp_file_path)
# Prepare inputs for CrewAI
inputs = {
"file_path": temp_file_path,
"file_type": file_type,
}
# Initialize and run the crew with the API key
doc_processing = DocProcessing(anthropic_api_key=anthropic_api_key)
result = doc_processing.crew().kickoff(inputs=inputs)
# Extract results from CrewOutput
if hasattr(result, 'tasks_output') and result.tasks_output:
analysis_result = ""
generated_code = ""
for i, task_output in enumerate(result.tasks_output):
if i == 0: # First task is document analysis
analysis_result = str(task_output.raw) if hasattr(task_output, 'raw') else str(task_output)
elif i == 1: # Second task is code implementation
generated_code = str(task_output.raw) if hasattr(task_output, 'raw') else str(task_output)
return generated_code
# analysis_result,
else:
# Fallback if structure is different
result_str = str(result)
return result_str, "Code generation completed. Check the analysis section for details."
except Exception as e:
error_msg = f"❌ Error processing document: {str(e)}"
return error_msg, ""
finally:
# Clean up environment variables for security
if "ANTHROPIC_API_KEY" in os.environ:
del os.environ["ANTHROPIC_API_KEY"]
def create_demo_interface():
"""Create the Gradio interface"""
# Custom CSS for better styling
custom_css = """
.gradio-container {
max-width: 1200px !important;
margin: auto !important;
}
.header {
text-align: center;
margin-bottom: 2rem;
}
.api-key-input {
margin-bottom: 1rem;
}
.output-section {
margin-top: 2rem;
}
.toggle-buttons {
margin-bottom: 1rem;
}
.preview-container {
border: 1px solid #e2e8f0;
border-radius: 8px;
background: #f8fafc;
min-height: 400px;
}
"""
with gr.Blocks(css=custom_css, title="Document to Code Converter") as demo:
gr.HTML("""
<div class="header">
<h1>πŸš€ Document to Code Converter</h1>
<p>Upload your design documents (images/PDFs) and convert them to working HTML/CSS/JS code!</p>
</div>
""")
with gr.Row():
with gr.Column(scale=1):
gr.HTML("<h3>πŸ“€ Upload & Configuration</h3>")
# API Key input
api_key_input = gr.Textbox(
label="πŸ”‘ Anthropic API Key",
placeholder="sk-ant-...",
type="password",
info="Enter your Anthropic API key. It will be used securely and not stored.",
elem_classes=["api-key-input"]
)
# File upload
file_input = gr.File(
label="πŸ“ Upload Document",
file_types=[".pdf", ".png", ".jpg", ".jpeg", ".gif", ".bmp", ".tiff"],
)
# Process button
process_btn = gr.Button(
"πŸ”„ Process Document",
variant="primary",
size="lg"
)
# Status indicator
gr.HTML("""
<div style="margin-top: 1rem; padding: 1rem; background: #f0f9ff; border-radius: 8px; border-left: 4px solid #0ea5e9;">
<h4 style="margin: 0; color: #0c4a6e;">ℹ️ How it works:</h4>
<ol style="margin: 0.5rem 0; color: #164e63;">
<li>Upload your design document (image or PDF)</li>
<li>Enter your Anthropic API key</li>
<li>Click "Process Document" to analyze and generate code</li>
<li>Use toggle buttons to switch between code view and live preview</li>
</ol>
</div>
""")
gr.HTML("<h3 class='output-section'>πŸ’» Generated Code & Preview</h3>")
# Toggle buttons for code/preview
with gr.Row():
code_view_btn = gr.Button("πŸ“ View Code", variant="primary", size="sm")
preview_btn = gr.Button("πŸ‘οΈ Preview Result", variant="secondary", size="sm")
# Code output (visible by default)
code_output = gr.Textbox(
label="HTML/CSS/JS Code",
lines=15,
placeholder="Generated code will appear here...",
show_copy_button=True,
visible=True
)
# Preview output (hidden by default)
preview_output = gr.HTML(
label="Live Preview",
value="<div style='padding: 20px; text-align: center; color: #666;'>Preview will appear here after code generation...</div>",
visible=False
)
# with gr.Row():
# with gr.Column(scale=1):
# gr.HTML("<h3 class='output-section'>πŸ“Š Document Analysis</h3>")
# analysis_output = gr.Textbox(
# label="Analysis Results",
# lines=15,
# placeholder="Document analysis will appear here...",
# show_copy_button=True
# )
# with gr.Column(scale=1):
# Download file component (hidden)
# download_file = gr.File(
# label="Download",
# visible=False
# )
# Add examples section
gr.HTML("""
<div style="margin-top: 2rem; padding: 1rem; background: #f8fafc; border-radius: 8px;">
<h4>🎯 New Features:</h4>
<ul>
<li><strong>πŸ“ Code View:</strong> See the raw HTML/CSS/JS code generated from your design</li>
<li><strong>πŸ‘οΈ Live Preview:</strong> Toggle to see how your code will actually look when rendered</li>
<li><strong>πŸ”„ Real-time Toggle:</strong> Switch between code and preview instantly</li>
</ul>
<h4>🎯 Best Results Tips:</h4>
<ul>
<li><strong>High Quality Images:</strong> Use clear, high-resolution images for better analysis</li>
<li><strong>Design Mockups:</strong> Website mockups, app designs, and UI sketches work great</li>
<li><strong>PDF Documents:</strong> Multi-page design documents are supported</li>
<li><strong>Clear Layouts:</strong> Well-organized designs produce better code structure</li>
</ul>
</div>
""")
# Set up the processing event
process_btn.click(
fn=process_document,
inputs=[file_input, api_key_input],
outputs=[code_output],
# analysis_output,
show_progress=True
)
# Set up toggle events
code_view_btn.click(
fn=toggle_to_code,
inputs=[],
outputs=[code_output, preview_output, code_view_btn, preview_btn]
)
preview_btn.click(
fn=toggle_to_preview,
inputs=[code_output],
outputs=[code_output, preview_output, code_view_btn, preview_btn]
)
# Set up download event
# download_btn.click(
# fn=download_html_file,
# inputs=[code_output],
# outputs=[download_file]
# )
# Add footer
gr.HTML("""
<div style="text-align: center; margin-top: 2rem; padding: 1rem; border-top: 1px solid #e2e8f0; color: #64748b;">
<p>πŸ”’ Your API keys are handled securely and never stored.
<br>Built with CrewAI, LandingAI, and Anthropic Claude.</p>
</div>
""")
return demo
if __name__ == "__main__":
# Test Landing AI connection on startup
from tools.custom_tool import test_landing_ai_connection
print("πŸ” Testing API connections...")
landing_ai_available = test_landing_ai_connection()
if not landing_ai_available:
print("\n⚠️ Warning: Landing AI API key not properly configured!")
print("For local development: Set LANDING_AI_API_KEY in your .env file")
print("For HuggingFace deployment: Add LANDING_AI_API_KEY to your Space secrets")
print("The app will still start, but document analysis will fail without the API key.\n")
else:
print("βœ… Landing AI API key configured correctly!\n")
# Create and launch the demo
demo = create_demo_interface()
# Launch configuration
demo.launch(
server_name="0.0.0.0", # Required for HuggingFace deployment
server_port=7860, # Standard port for HuggingFace
share=False, # Set to True for temporary public link during development
debug=False, # Set to True for development
show_error=True, # Show errors in the interface
quiet=False # Set to True to reduce console output
)